logo
logo
请输入关键词搜索产品或者文档
中国

中国站

创蓝云智

国际站

Innopaas

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)

参数描述

参数类型说明
applicationApplication传 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)

参数描述

参数类型说明
callbackCLInitCallback初始化回调监听

示例代码

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,含义如下:

字段类型含义
codeint100:初始化中;1001:初始化成功;1002:初始化失败;其他:见状态码表
msgString结果描述(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)

参数描述

参数类型说明
tagTagNFC Tag,从 onNewIntent 中通过 getTagFromIntent 获取
intentIntent含 NFC Tag 的 Intent(内部自动提取 Tag)
listenerCLReadCardListener读卡回调监听

各重载说明:

方法说明
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_NFCNFC 通道(检查、前台调度、Tag 提取)
NFC_SDK_INOUTCALLBACK回调边界(SDK 回调进入并转发 APP)
NFC_SDK_ONCALLBACKSDK 内部回调
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 回调返回,字段如下:

字段类型注释
nameString姓名
sexString性别
nationString民族
birthdayString出生日期
addressString家庭住址
idString身份证号码
issueString签发机关
startDateString证件生效时间
endDateString证件结束时间
dnStringdn 码
uuidStringuuid
msidStringmsid
typeint证件类型码(居民身份证固定为 1080)
imagebyte[]证件照原始数据
bitmapBitmap证件照(解码成功时)
fingerPrintbyte[]指纹信息
distimelong解码耗时
requestIdString异步解码请求 ID(配合 onAsynResult 使用)
fingerPrintDataList<?>指纹信息列表
frontPhotobyte[]身份证正面照数据(配置照片回调时)
backPhotobyte[]身份证反面照数据(配置照片回调时)

四.状态码

onReadCardState 状态码表

状态码描述
1000解码成功
100初始化中
1001初始化成功
1002初始化失败
1010网络通讯异常
1018本地通信失败
1020未知异常
1021解码开始
1022解码失败
1023解码中
1024开始寻卡
1025寻卡失败
1026寻卡成功
1031UID 异常