android SDK集成文档
更新时间:2026-11-09 16:11:22
一.准备工作
1.概述
本文是创蓝 NFC 读卡 SDK_Android 端接入文档,用于指导 SDK 的集成使用。业务方只需集成单个 AAR 即可完成接入。
2.能力介绍
身份证读卡:通过 NFC 读取中国居民身份证芯片信息,成功后通过回调返回证件全部字段,包括姓名、身份证号码、出生日期、住址、签发机关、有效期、证件照片等。
3.前置条件
- SDK 支持 minSdkVersion 24(Android 7.0)及以上版本
设备需具备 NFC 硬件且已开启- 云解码方式需要设备可访问网络
4.开发环境搭建
a.本地集成
将 SDK 的 AAR 包拷贝到您工程的 libs 目录下,如没有该目录需新建。
在 build 文件的 dependencies 中添加 aar 包依赖:
repositories { flatDir { dirs '../app/libs' } } dependencies { implementation fileTree(include: ['*.aar'], dir: 'libs') }
注意:SDK 内部依赖 androidx.appcompat,若您的工程尚未依赖,请自行添加:
dependencies { implementation "androidx.appcompat:appcompat:1.6.1" }
b.权限配置
SDK 的 AAR 中已通过 AndroidManifest.xml 声明以下必要权限(打包时会自动合并进您的工程,无需重复配置),列出供合规说明使用:
<uses-permission android:name="android.permission.NFC" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
配置权限说明
| 权限名称 | 权限说明 | 使用说明 |
|---|---|---|
| NFC | 允许使用 NFC | 读取身份证芯片数据 |
| INTERNET | 允许应用程序联网 | 用于连接云解码服务器 |
| ACCESS_NETWORK_STATE | 允许访问网络状态 | 检测网络连接情况 |
如需开启 SDK 日志落盘保存到外部存储,可按需添加读写存储权限(详见 二.9 日志)。
c.读卡 Activity 配置
在 AndroidManifest.xml 中为承接 NFC 读卡的 Activity 配置 singleTop 启动模式及 NFC intent-filter,否则收不到卡片贴近事件:
<activity android:name=".NfcReadActivity" android:exported="true" android:launchMode="singleTop"> <intent-filter> <action android:name="android.nfc.action.TECH_DISCOVERED" /> </intent-filter> <intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc_tech_filter" /> </activity>
res/xml/nfc_tech_filter.xml 文件内容:
<?xml version="1.0" encoding="utf-8"?> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <tech-list><tech>android.nfc.tech.NfcA</tech></tech-list> <tech-list><tech>android.nfc.tech.NfcB</tech></tech-list> <tech-list><tech>android.nfc.tech.NfcF</tech></tech-list> <tech-list><tech>android.nfc.tech.NfcV</tech></tech-list> <tech-list><tech>android.nfc.tech.IsoDep</tech></tech-list> <tech-list><tech>android.nfc.tech.MifareClassic</tech></tech-list> <tech-list><tech>android.nfc.tech.MifareUltralight</tech></tech-list> <tech-list><tech>android.nfc.tech.Ndef</tech></tech-list> <tech-list><tech>android.nfc.tech.NdefFormatable</tech></tech-list> </resources>
d.混淆规则
若您的工程开启了代码混淆(minifyEnabled true),请在 proguard-rules.pro 中添加以下规则:
-keep class com.chuanglan.nfc.sdk.**{*;} -keep class com.csht.**{*;} -dontwarn com.csht.** -keep class org.bouncycastle.**{*;} -dontwarn org.bouncycastle.** -keep class com.google.gson.**{*;} -dontwarn com.google.gson.**
5.快速体验 demo
demo 工程源码中包含完整的身份证读卡示例(初始化、token 获取、NFC 前台调度、读卡回调、日志展示),可直接运行到支持 NFC 的 Android 手机上测试。
二.身份证读卡 api
1.初始化
初始化用于完成 SDK 的全局准备,请在 Application 的 onCreate 中调用,一个 APP 启动周期只调用一次即可。
方法原型
public static void init(Application application)
参数描述
| 参数 | 类型 | 说明 |
|---|---|---|
| application | Application | 传 Application 对象 |
示例代码
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); // 设置调试模式,开启后 SDK 输出内部流程日志,生产环境请关闭 CLReadCardManager.setDebug(true); // NFC 读卡 SDK 初始化 CLReadCardManager.init(this); } }
2.获取 authToken
token 鉴权为必须配置:APP 端须在 buildCreate() 之前调用 buildAppID(appId) 与 buildAuthToken(token) 完成鉴权配置,两者缺一不可,缺失时 buildCreate() 会抛出 IllegalStateException。
请查看服务端集成文档,由服务端调用获取授权 Token(authToken)接口,获取 authToken 为后续步骤做准备。
接口简述:POST https://ip:port/identity_auth/nfc/getToken,请求体 {"appId":"...","appKey":"...","requestId":"0~32位随机串"},响应 code 为 "200000" 时 data.token 即认证令牌。APP 端将业务方 appId 通过 buildAppID 传入 SDK,服务端获取并下发的 token 通过 buildAuthToken 传入 SDK。
注意:appKey 属于敏感凭证,须保管在业务服务器上,由服务端调用获取 token 接口;demo 中在 APP 内直连调用仅为演示接入流程,请勿用于生产环境。
3.读卡参数配置
读卡初始化之前,通过链式配置设置必要的读卡参数,buildCreate() 返回读卡操作对象。
注意:服务器地址(主/备)、读卡方式及基础鉴权凭证均已内置于 SDK,无需 APP 层配置;token 鉴权(buildAppID + buildAuthToken)为必须配置项。
示例代码
CLReadSettingBuilder builder = CLReadCardManager .builder(this) // 上下文 .buildOpenSound(true) // 开启读卡提示音 .buildDecodeImageType(CLDecodeImageType.LOCAL_DECODE) // 照片解码方式:本地解码 .buildNeedIdCardPhoto(false) // 是否返回身份证照片 .buildOpenLocalCache(true); // 开启本地缓存 // token 鉴权(必须):appId 为业务方 appId,token 由服务端获取下发,须在 buildCreate() 之前配套设置 builder.buildAppID(appId); builder.buildAuthToken(authToken); CLReadCardOutMethod readCardManager = builder.buildCreate();
配置方法说明
| 方法 | 参数 | 说明 |
|---|---|---|
| buildDecodeImageType | (CLDecodeImageType type) | 证件照片解码方式,见下方解码方式表 |
| buildNeedIdCardPhoto | (boolean need) | 是否回调身份证照片(onReadIDCardPhoto),默认 false |
| buildDelIdCardPhotoWhiteBg | (boolean del) | 是否去除身份证照片白边,默认 false |
| buildOpenSound | (boolean open) | 是否开启读卡提示音,默认 false |
| buildOpenLocalCache | (boolean open) | 是否开启本地缓存 |
| buildResultRepeatIdCard | (boolean repeat) | 同一张卡重复贴近时是否重复返回读卡结果 |
| buildIsAsynApiResult | (boolean isAsyn) | 是否异步返回解码结果(配合 onAsynResult 回调),默认 false |
| buildPingNetHeartbeat | (boolean enable, long interval) | 是否开启网络心跳及心跳间隔 |
| buildAppID | (String appID) | (必须) token 鉴权:业务方 appId,需与 buildAuthToken 配套使用,缺失时 buildCreate() 抛异常 |
| buildAuthToken | (String authToken) | (必须) token 鉴权:服务端下发的 token,需与 buildAppID 配套使用,缺失时 buildCreate() 抛异常 |
照片解码方式(CLDecodeImageType)
| 枚举值 | 说明 |
|---|---|
| NO_IMAGE | 不解码照片 |
| LOCAL_DECODE | 本地解码照片(推荐) |
| SERVER_DECODE | 服务端解码照片 |
| LOCAL_DECODE_FINGER | 本地解码照片+指纹 |
| SERVER_DECODE_FINGER | 服务端解码照片+指纹 |
| LOCAL_DECODE_4 | 本地解码(兼容第 4 代证件) |
4.SDK 初始化
参数配置完成后调用初始化,初始化结果通过回调返回。请在初始化成功(code 为 1001)后再开始读卡。
方法原型
public void init(CLInitCallback callback)
参数描述
| 参数 | 类型 | 说明 |
|---|---|---|
| callback | CLInitCallback | 初始化回调监听 |
示例代码
readCardManager.init((code, msg) -> { if (code == CLStatusCode.ININ_ING.getCode()) { // 初始化中 } else if (code == CLStatusCode.ININ_OK.getCode()) { // 初始化成功,可以开始读卡 } else if (code == CLStatusCode.ININ_FAILE.getCode()) { // 初始化失败,对照状态码表排查 } });
init 回调返回参数 code 和 msg,含义如下:
| 字段 | 类型 | 含义 |
|---|---|---|
| code | int | 100:初始化中;1001:初始化成功;1002:初始化失败;其他:见状态码表 |
| msg | String | 结果描述(SDK 返回空描述时,会按状态码自动补全中文描述) |
5.NFC 前置检查与前台调度
a.NFC 前置检查
读卡前应判断当前设备是否支持 NFC、NFC 是否已开启:
if (!CLNfcHelper.hasNfc(this)) { // 设备不支持 NFC } else if (!CLNfcHelper.isNfcEnabled(this)) { // NFC 未开启,引导用户去系统设置打开 CLNfcHelper.openNfcSettings(this); }
b.前台调度
推荐在读卡页面使用 NFC 前台调度:页面在前台时接收卡片事件,离开页面自动失效。SDK 已封装全部样板代码,按以下方式接入 Activity 生命周期:
private PendingIntent pendingIntent; private boolean isReading = false; // 是否正在读卡 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Activity 需在 manifest 配置 launchMode="singleTop" pendingIntent = CLNfcHelper.createPendingIntent(this); } @Override protected void onResume() { super.onResume(); // 只有正在读卡时才启用前台调度 if (isReading) { CLNfcHelper.enableForegroundDispatch(this, pendingIntent); } } @Override protected void onPause() { CLNfcHelper.disableForegroundDispatch(this); super.onPause(); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); // 已停止读卡时不处理 NFC 事件 if (!isReading) return; setIntent(intent); // 从 Intent 中取出 Tag,传给开始读卡方法(见下一节) Tag tag = CLNfcHelper.getTagFromIntent(intent); if (tag != null) { readCardManager.readCardStart(tag, listener); } }
c.CLNfcHelper 方法说明
| 方法 | 参数 | 说明 |
|---|---|---|
| hasNfc | (Context) | 设备是否支持 NFC 硬件 |
| isNfcEnabled | (Context) | NFC 是否已开启 |
| getNfcAdapter | (Context) | 获取系统 NfcAdapter,不支持时返回 null |
| openNfcSettings | (Activity) | 跳转到系统 NFC 设置页 |
| createPendingIntent | (Activity) | 构建前台调度用的 PendingIntent |
| enableForegroundDispatch | (Activity, PendingIntent) | 启用前台调度(内部已含过滤器配置) |
| disableForegroundDispatch | (Activity) | 禁用前台调度 |
| getTagFromIntent | (Intent) | 从 Intent 中提取 NFC Tag |
| isNfcTag | (Object) | 判断对象是否为 NFC Tag |
6.开始读卡
初始化成功后调用,卡片贴近 NFC 感应区后触发读卡,结果通过 CLReadCardListener 回调返回(见下一节)。
方法原型
public void readCardStart(Tag tag, CLReadCardListener listener) public void readCardStart(Intent intent, CLReadCardListener listener) public void readCardStart(CLReadCardListener listener) public void readCardOnceStart(CLReadCardListener listener)
参数描述
| 参数 | 类型 | 说明 |
|---|---|---|
| tag | Tag | NFC Tag,从 onNewIntent 中通过 getTagFromIntent 获取 |
| intent | Intent | 含 NFC Tag 的 Intent(内部自动提取 Tag) |
| listener | CLReadCardListener | 读卡回调监听 |
各重载说明:
| 方法 | 说明 |
|---|---|
| readCardStart(tag, listener) | 携带 Tag 开始读卡,配合前台调度在 onNewIntent 中调用(推荐) |
| readCardStart(intent, listener) | 携带 Intent 开始读卡,内部自动提取 Tag |
| readCardStart(listener) | 开始持续监听读卡,配合 manifest 的 intent-filter 方式使用 |
| readCardOnceStart(listener) | 单次读卡,读到一次结果后自动停止 |
示例代码
// 方式一:前台调度 + onNewIntent 中携带 Tag 调用(推荐) readCardManager.readCardStart(tag, this); // 方式二:开始读卡时启用持续监听 isReading = true; CLNfcHelper.enableForegroundDispatch(this, pendingIntent); readCardManager.readCardStart(this);
7.读卡回调说明
业务方实现 CLReadCardListener 接口接收读卡结果:
| 方法名 | 参数 | 说明 |
|---|---|---|
| onReadIDCardSuccess(CLIdCardData data) | data(证件信息) | 身份证读取成功,详见 CLIdCardData 数据结构表 |
| onReadCardState(int type, String msg) | type(状态码)msg(状态信息) | 读卡过程状态及失败回调,详见状态码表 |
| onReadIDCardPhoto(Bitmap frontPhoto, Bitmap backPhoto) | 正面照/反面照 | 配置 buildNeedIdCardPhoto(true) 且照片解码成功时回调 |
| onReadICCardSuccess(String icNumber, int type) | icNumber(卡号) | 贴近非身份证的其他卡片时回调,身份证读卡场景可忽略 |
| onAsynResult(boolean isSuccess, String msg, String requestId) | requestId(异步请求ID) | 配置 buildIsAsynApiResult(true) 时异步返回解码结果 |
示例代码
@Override public void onReadIDCardSuccess(CLIdCardData data) { // 读取成功:姓名、身份证号等 Log.d("NfcRead", "name=" + data.getName() + ", id=" + data.getId()); } @Override public void onReadCardState(int type, String msg) { if (type == CLStatusCode.FIND_CARD_SUCCESS.getCode()) { // 寻卡成功,开始解码 } else if (type == CLStatusCode.READCARD_FAILE.getCode()) { // 解码失败,提示用户重新贴卡 } }
温馨提示:回调方法可能在子线程中执行,如需处理 UI 相关逻辑,请切换到主线程处理。
8.停止读卡与释放
// 停止读卡,可再次调用 readCardStart 继续读卡 readCardManager.readCardStop(); // 释放读卡资源,释放后如需再次读卡,需重新走初始化流程 readCardManager.readCardReleaseDestory();
建议在 Activity 销毁时停止并释放:
@Override protected void onDestroy() { if (readCardManager != null) { readCardManager.readCardStop(); readCardManager.readCardReleaseDestory(); } super.onDestroy(); }
9.日志
a.设置 log 开关
CLReadCardManager.setDebug(true);
开启后 SDK 通过 logcat 输出内部流程日志,logcat 过滤关键字 NFC_SDK_ 可观测 SDK 全部流程:
| TAG | 说明 |
|---|---|
| NFC_SDK_INIT | 初始化 / 释放 / 重启等生命周期 |
| NFC_SDK_CONFIG | 参数配置构建 |
| NFC_SDK_READ_CARD | 读卡流程 |
| NFC_SDK_NFC | NFC 通道(检查、前台调度、Tag 提取) |
| NFC_SDK_INOUTCALLBACK | 回调边界(SDK 回调进入并转发 APP) |
| NFC_SDK_ONCALLBACK | SDK 内部回调 |
| NFC_SDK_ERROR | 异常 / 错误 |
b.设置日志监听器
APP 层可通过此接口接收 SDK 内部全部日志,便于统一收集、上报或显示:
CLReadCardManager.setLogListener((level, tag, msg) -> { // level:v/d/i/w/e;tag:上表中的 TAG;msg:日志内容 }); // 取消监听 CLReadCardManager.setLogListener(null);
注意:日志监听器回调不受 setDebug 开关控制,注册后始终会收到日志;传 null 取消监听。
三.数据结构
CLIdCardData(身份证信息)
身份证读取成功后通过 onReadIDCardSuccess 回调返回,字段如下:
| 字段 | 类型 | 注释 |
|---|---|---|
| name | String | 姓名 |
| sex | String | 性别 |
| nation | String | 民族 |
| birthday | String | 出生日期 |
| address | String | 家庭住址 |
| id | String | 身份证号码 |
| issue | String | 签发机关 |
| startDate | String | 证件生效时间 |
| endDate | String | 证件结束时间 |
| dn | String | dn 码 |
| uuid | String | uuid |
| msid | String | msid |
| type | int | 证件类型码(居民身份证固定为 1080) |
| image | byte[] | 证件照原始数据 |
| bitmap | Bitmap | 证件照(解码成功时) |
| fingerPrint | byte[] | 指纹信息 |
| distime | long | 解码耗时 |
| requestId | String | 异步解码请求 ID(配合 onAsynResult 使用) |
| fingerPrintData | List<?> | 指纹信息列表 |
| frontPhoto | byte[] | 身份证正面照数据(配置照片回调时) |
| backPhoto | byte[] | 身份证反面照数据(配置照片回调时) |
四.状态码
onReadCardState 状态码表
| 状态码 | 描述 |
|---|---|
| 1000 | 解码成功 |
| 100 | 初始化中 |
| 1001 | 初始化成功 |
| 1002 | 初始化失败 |
| 1010 | 网络通讯异常 |
| 1018 | 本地通信失败 |
| 1020 | 未知异常 |
| 1021 | 解码开始 |
| 1022 | 解码失败 |
| 1023 | 解码中 |
| 1024 | 开始寻卡 |
| 1025 | 寻卡失败 |
| 1026 | 寻卡成功 |
| 1031 | UID 异常 |
这篇文档对您有帮助吗?




