# 身份证读卡器 Flutter 插件
一个用于读取中国二代身份证的 Flutter 插件,集成了01SDK身份证识别功能,支持USB和蓝牙连接方式。
## 功能特性
- ✅ 支持二代身份证读取
- ✅ 获取完整的身份证信息(姓名、性别、民族、出生日期、地址、身份证号、签发机关、有效期)
- ✅ 支持读取身份证照片
- ✅ 支持USB连接读卡器
- ✅ 支持蓝牙连接读卡器
- ✅ 完整的错误处理和状态管理
- ✅ 简单易用的API接口
## 支持平台
- ✅ Android
- ❌ iOS(暂不支持)
## 安装
在 `pubspec.yaml` 文件中添加依赖:
```yaml
dependencies:
idcard: ^0.0.1
```
然后运行:
```bash
flutter pub get
```
## Android 配置
### 权限配置
在 `android/app/src/main/AndroidManifest.xml` 中添加必要权限:
```xml
```
### SDK版本配置
确保 `minSdkVersion` 至少为 21,`targetSdkVersion` 为 34:
```gradle
android {
compileSdk 34
defaultConfig {
minSdkVersion 21
targetSdkVersion 34
}
}
```
### Android 12+ 兼容性
本插件已针对 Android 12+ 进行了优化,包括:
- **PendingIntent 兼容性**:自动处理 Android 12+ 的 `FLAG_IMMUTABLE` 要求
- **USB 权限优化**:改进了权限请求流程,增加了超时处理
- **错误处理增强**:提供更详细的错误信息和用户指导
## 使用方法
### 基本用法
```dart
import 'package:idcard/idcard.dart';
class IdCardReader {
final _idcardPlugin = Idcard();
/// 连接设备并读取身份证
Future readIdCard() async {
try {
// 1. 获取USB权限
int permissionResult = await _idcardPlugin.getUsbPermission();
if (permissionResult != 0) {
print('获取USB权限失败,错误码:$permissionResult');
return;
}
// 2. 打开设备
int openResult = await _idcardPlugin.openDevice();
if (openResult <= 0) {
print('打开设备失败,错误码:$openResult');
return;
}
print('设备打开成功,句柄:$openResult');
// 3. 读取身份证信息(完整流程)
IdCardInfo cardInfo = await _idcardPlugin.readCardComplete();
print('姓名:${cardInfo.name}');
print('身份证号:${cardInfo.idNumber}');
print('性别:${cardInfo.gender}');
// ... 其他信息
// 4. 关闭设备
await _idcardPlugin.closeDevice();
} catch (e) {
print('读卡失败:$e');
}
}
}
```
### 高级用法
#### 分步骤读取
```dart
// 手动控制每个步骤
try {
// 寻卡
int findResult = await _idcardPlugin.findCard();
if (findResult <= 0) {
throw Exception('寻卡失败,错误码:$findResult');
}
// 选卡
int selectResult = await _idcardPlugin.selectCard();
if (selectResult <= 0) {
throw Exception('选卡失败,错误码:$selectResult');
}
// 读取详细信息
IdCardInfo cardInfo = await _idcardPlugin.readCardInfo();
print('读取成功:${cardInfo.toString()}');
} catch (e) {
print('读卡过程出错:$e');
}
```
#### 蓝牙连接
```dart
// 使用蓝牙连接
int result = await _idcardPlugin.openDevice(
portType: 'BLUETOOTH',
portPara: 'BLUETOOTH_DEVICE_NAME', // 蓝牙设备名称
);
```
#### 读取原始数据
```dart
// 读取原始二进制数据
Map result = await _idcardPlugin.readCard(
cardType: 1,
infoEncoding: 0,
timeOut: 30000,
);
if (result['result'] > 0) {
List rawData = result['data'];
// 处理原始数据
}
```
## 返回值说明
根据神思标准化接口规范,所有设备操作方法的返回值遵循以下规则:
- **大于0**:表示操作成功
- 对于 `openDevice()`:返回值是设备句柄,用于后续操作
- 对于其他方法:返回值表示操作成功的状态码
- **小于等于0**:表示操作失败,返回值为错误码
- 具体错误码含义请参考设备厂商提供的接口文档
### 重要提醒
在判断操作是否成功时,请使用 `> 0` 而不是 `== 0` 来判断成功状态:
```dart
// ✅ 正确的判断方式
int result = await _idcardPlugin.openDevice();
if (result > 0) {
print('设备打开成功,句柄:$result');
} else {
print('设备打开失败,错误码:$result');
}
// ❌ 错误的判断方式
if (result == 0) {
// 这样判断是错误的
}
```
## API 参考
### Idcard 类
#### 方法
| 方法 | 描述 | 参数 | 返回值 |
|------|------|------|--------|
| `getPlatformVersion()` | 获取平台版本 | 无 | `Future` |
| `getUsbPermission({int vid, int pid})` | 获取USB权限 | vid: 厂商ID, pid: 产品ID | `Future` |
| `openDevice({String portType, String portPara, String extendPara})` | 打开设备 | portType: 端口类型, portPara: 端口参数, extendPara: 扩展参数 | `Future` - 大于0表示成功(设备句柄),小于等于0表示失败 |
| `closeDevice()` | 关闭设备 | 无 | `Future` - 大于0表示成功,小于等于0表示失败 |
| `findCard()` | 寻卡 | 无 | `Future` - 大于0表示成功,小于等于0表示失败 |
| `selectCard()` | 选卡 | 无 | `Future` - 大于0表示成功,小于等于0表示失败 |
| `readCard({int cardType, int infoEncoding, int timeOut})` | 读取原始数据 | cardType: 卡片类型, infoEncoding: 编码, timeOut: 超时时间 | `Future