赞
踩
说明:
此文使用华为SDK、百度SDK、百度在线API三种方式实现。
一、使用华为SDK实现身份证识别:
说明:免费,不需要联网。
1.AndroidManifest.xml添加权限:
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.CAMERA"/>
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
-
- <uses-feature android:name="android.hardware.camera" />
- <uses-feature android:name="android.hardware.camera.autofocus" />
2. 工程根目录build.gradle:
- buildscript {
- repositories {
- //...省略之前配的其他地址
- maven { url "https://developer.huawei.com/repo/" }
- }
- dependencies {
- //...省略之前配的其他地址
- classpath 'com.huawei.agconnect:agcp:1.6.0.300'
- }
- }
-
- allprojects {
- repositories {
- //...省略之前配的其他地址
- maven { url "https://developer.huawei.com/repo/" }
- }
- }
3.工程/app/build.gradle:
- //...省略之前配的其他地址
- apply plugin: 'com.huawei.agconnect'
- android {
- //...省略之前配的其他地址
- packagingOptions {
- exclude 'lib/arm64-v8a/libmsoptimize.so'
- }
- }
- dependencies {
- //...省略之前配的其他地址
- implementation 'com.huawei.hms:ml-computer-card-icr-cn:2.0.3.303'
- implementation 'com.huawei.hms:ml-computer-vision-ocr:2.0.5.301'
- implementation 'com.huawei.hms:ml-computer-vision-ocr-cn-model:2.0.5.301'
- implementation 'com.huawei.hms:ml-computer-vision-ocr-jk-model:2.0.5.301'
- implementation 'com.huawei.hms:ml-computer-vision-ocr-latin-model:2.0.5.301'
- implementation 'com.huawei.hms:ml-computer-card-gcr-plugin:2.0.1.301'
- }
4.调用身份证SDK:
(1)身份证识别业务类:
- public class HWIDCardScanBiz {
- private static HWIDCardScanBiz I;
-
- public static HWIDCardScanBiz I() {
- if (I == null) {
- I = new HWIDCardScanBiz();
- }
- return I;
- }
-
- /**
- * 打开身份证识别页,调用之前要申请蓝牙动态权限
- */
- public void startIDCardScanActivity(Context context, IDCardScanCallback callback) {
- MLCnIcrCaptureConfig config = new MLCnIcrCaptureConfig.Factory()
- .setFront(true)
- .create();
- MLCnIcrCapture icrCapture = MLCnIcrCaptureFactory.getInstance().getIcrCapture(config);
- icrCapture.capture(new HWIDScanCallback(callback), context);
- }
-
-
- private class HWIDScanCallback implements MLCnIcrCapture.CallBack {
-
- private IDCardScanCallback callback;
-
- public HWIDScanCallback(IDCardScanCallback callback) {
- this.callback = callback;
- }
-
- /**
- * 识别成功回调
- */
- @Override
- public void onSuccess(MLCnIcrCaptureResult result) {
- if (result == null) {
- Toast.makeText(XApp.Companion.getContext(), "识别失败", Toast.LENGTH_SHORT);
- return;
- }
- if (callback != null) {
- IDCardInfo info = new IDCardInfo(result.name, result.sex, result.nation, result.birthday, result.address, result.idNum, result.authority, result.validDate, result.sideType);
- callback.onIDCardResult(info);
- }
- }
-
- @Override
- public void onCanceled() {
- }
-
- @Override
- public void onFailure(int retCode, Bitmap bitmap) {
- Toast.makeText(XApp.Companion.getContext(), "识别失败", Toast.LENGTH_SHORT);
- }
-
- @Override
- public void onDenied() {
- }
- }
-
- public interface IDCardScanCallback {
- void onIDCardResult(IDCardInfo result);
- }
- }
(2)调用识别业务类,更新UI:
- HWIDCardScanBiz.I().startIDCardScanActivity(context, new HWIDCardScanBiz.IDCardScanCallback() {
- @Override
- public void onIDCardResult(IDCardInfo result) {
- /*
- result.name: 姓名
- result.sex:性别
- result.nation:国籍
- result.birthday:生日
- result.address:地址
- result.idNum:身份证号
- result.validDate:有效期
- */
- }
- });
二、使用百度云SDK实现身份证识别:
说明:免费额度个人帐户每月1千次/企业帐户每月2千次,要联网。
1.添加配置: (1)AndroidManifest.xml添加权限:
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.CAMERA"/>
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
-
- <uses-feature android:name="android.hardware.camera" />
- <uses-feature android:name="android.hardware.camera.autofocus" />
(2)proguard-rules.pro添加混淆例外:
- -keep class com.baidu.ocr.sdk.**{*;}
- -dontwarn com.baidu.ocr.**
(3)将ocrsdk.aar放入工程\app\libs目录下。 (4)从以下地址(控制台-公有云-应用列表-进入某个应用详情页)下载aip-ocr.license放入工程\app\src\main\assets下:
https://console.bce.baidu.com/ai/#/ai/ocr/app/detail~appId=4571869
(5)将ocr_ui模块工程放入工程根目录下,在settings.gradle中添加导入模块工程的配置:
include ':app', 'ocrsdk', 'ocr_ui'
(6)工程/app/build.gradle,导入ocrsdk.aar与ocr_ui模块工程:
- //...省略之前配的其他地址
- repositories {
- flatDir {
- dirs 'libs'
- }
- }
- dependencies {
- //...省略之前配的其他地址
- implementation(name: 'ocrsdk', ext: 'aar')
- implementation project(path: ':ocr_ui')
- }
2.调用代码实现身份证识别: 第1步:调用SDK方法获取token; 第2步:调用SDK方法打开身份证识别界面; 第3步,在调用的Activity的onActivityResult中调用SDK识别图片中的身份信息。 身份证SDK业务类:
- public class IDCardScanBiz {
- public static final int REQUEST_CODE_CAMERA = 100;
- private boolean mHasGotToken;
- private static IDCardScanBiz I;
-
-
- public static IDCardScanBiz I() {
- if (I == null) {
- I = new IDCardScanBiz();
- }
- return I;
- }
-
- /**
- * 第1步,调用此方法获取token
- */
- public void initToken() {
- OCR.getInstance(ExampleApplication.Companion.getContext()).initAccessTokenWithAkSk(new OnResultListener() {
- @Override
- public void onResult(Object o) {
- Log.i("BDIDCard", "getAccessToken onResult >>> o: " + o.toString());
- mHasGotToken = true;
- init();
- }
-
- @Override
- public void onError(OCRError error) {
- Log.i("BDIDCard", "getAccessToken onError >>> error: " + error.toString());
- // 调用失败,返回OCRError子类SDKError对象
- }
- }, ExampleApplication.Companion.getContext(), "gPxzwMwJVfENiggqd6csyE85", "hcTVlJYj8sKGEgWngy8Qmp83mNxVqp8O");
- }
-
-
- /**
- * 初始化本地质量控制模型
- */
- private void init() {
- Context context = ExampleApplication.Companion.getContext();
- CameraNativeHelper.init(context, OCR.getInstance(context).getLicense(), (errorCode, e) -> Log.i("BDIDCard", "init onError >>> errorCode: " + errorCode));
- }
-
- /**
- * 第2步:调用此方法打开身份证识别界面
- */
- public void startIDCardScanActivity(Activity act) {
- if (!mHasGotToken) return;
- Intent intent = new Intent(act, CameraActivity.class);
- intent.putExtra(CameraActivity.KEY_OUTPUT_FILE_PATH, getSaveFile().getAbsolutePath());
- intent.putExtra(CameraActivity.KEY_NATIVE_ENABLE, true);
- intent.putExtra(CameraActivity.KEY_NATIVE_MANUAL, true);
- intent.putExtra(CameraActivity.KEY_CONTENT_TYPE, CameraActivity.CONTENT_TYPE_ID_CARD_FRONT);
- act.startActivityForResult(intent, REQUEST_CODE_CAMERA);
- }
-
- /**
- * 第3步,在onActivityResult中调此方法,调用百度云API获取照片中的身份证信息
- */
- public void readIDCard() {
- if (!mHasGotToken) return;
- String filePath = getSaveFile().getAbsolutePath();
- IDCardParams param = new IDCardParams();
- param.setImageFile(new File(filePath));
- // 设置身份证正反面
- param.setIdCardSide(IDCardParams.ID_CARD_SIDE_FRONT);
- // 设置方向检测
- param.setDetectDirection(true);
- // 设置图像参数压缩质量0-100, 越大图像质量越好但是请求时间越长。 不设置则默认值为20
- param.setImageQuality(20);
- param.setDetectRisk(true);
- OCR.getInstance(ExampleApplication.Companion.getContext()).recognizeIDCard(param, new OnResultListener<IDCardResult>() {
- @Override
- public void onResult(IDCardResult result) {
- Log.i("BDIDCard", "recIDCard result >>> result: " + result.toString());
- if (result != null) {//获取身份信息
- }
- }
-
- @Override
- public void onError(OCRError error) {
- Log.i("BDIDCard", "recIDCard result >>> error: " + error.toString());
- }
- });
- }
-
- public static File getSaveFile() {
- File file = new File(ExampleApplication.Companion.getContext().getFilesDir(), "pic.jpg");
- return file;
- }
- }
调用业务类的Activity:
- class MainActivity : Activity() {
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- var ps = arrayOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
- ActivityCompat.requestPermissions(this, ps, 100);
- IDCardScanBiz.I().initToken()
- }
-
- fun onScanClick(v: View) {
- IDCardScanBiz.I().startIDCardScanActivity(this)
- }
-
- override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
- super.onActivityResult(requestCode, resultCode, data)
- if (requestCode == IDCardScanBiz.REQUEST_CODE_CAMERA && resultCode == RESULT_OK) {
- IDCardScanBiz.I().readIDCard()
- }
- }
-
- }
三、使用百度云API实现身份证识别:
说明:免费额度个人帐户每月1千次/企业帐户每月2千次,要联网。
1.AndroidManifest.xml添加权限:
同上面两种
2.调用代码实现身份证识别:
第1步,调用百度API获取token:
- public static String getToken() {
- String url = "https://aip.baidubce.com/oauth/2.0/token?client_id=" + Config.CLIENT_ID + "&client_secret=" + Config.CLIENT_SECRET + "&grant_type=client_credentials";
- if (!NetHelp.getCurConnectStatus()) {
- return null;
- }
- Response response = null;
- try {
- Request request = new Request.Builder().url(url).get().build();
- LogUtils.d("getToken request url :" + url);
- response = httpClient.newCall(request).execute();
- } catch (IOException e) {
- LogUtils.d("getToken request exception: " + e.getMessage());
- e.printStackTrace();
- return null;
- }
- LogUtils.d("getToken response isSuccessful: " + response.isSuccessful());
- if (response != null && response.isSuccessful()) {
- try {
- String strRecData = response.body().string();
- LogUtils.d("getToken response body: " + strRecData);
- if (strRecData != null && strRecData.length() > 2) {
- JSONObject jsonObj = new JSONObject(strRecData);
- if (jsonObj != null && !jsonObj.isNull("access_token")) {
- return jsonObj.getString("access_token");
- }
- }
- return response.body().string();
- } catch (Exception e) {
- LogUtils.d("getToken response parse exception: " + e.getMessage());
- e.printStackTrace();
- return null;
- }
- }
- return null;
- }
第2步,调用系统相机拍身份证照片(可以自已实现带身份证头像框的拍照功能,界面更加美观):
- /**
- * 调起系统相机进行拍照,此步可以自已实现拍照功能,界面更美观
- */
- public void startIDCardScanActivity(Activity act) {
- Log.i("IDCard", "IDCard startIDCardScanActivity >>>");
- Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
- if (intent.resolveActivity(act.getPackageManager()) != null) {
- act.startActivityForResult(intent, REQUEST_CODE_CAMERA);
- }
- }
第3步,在onActivityResult中,将图片上传百度API获取身份证信息:
- /**
- * 解析身份证图片,获取身份信息
- */
- public void handlerData(Activity act, Intent data, IDCardScanCallback callback) {
- new Thread() {
- @Override
- public void run() {
- Bundle bundle = data.getExtras();
- Log.i("IDCard", "IDCard handlerData bundle >>> : " + bundle);
- if (bundle == null) return;
- Bitmap bitmap = (Bitmap) bundle.get("data");
- Log.i("IDCard", "IDCard handlerData bitmap >>> : " + bitmap);
- if (bitmap == null) return;
- File file = new File(App.getContext().getCacheDir(), System.currentTimeMillis() + ".jpeg");
- if (!file.getParentFile().exists()) file.mkdirs();
- try {
- FileOutputStream out = new FileOutputStream(file);
- bitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
- out.flush();
- out.close();
- Log.i("IDCard", "IDCard saveBitmap filePath: " + file.getAbsolutePath() + " fileLen: " + file.length());
- } catch (IOException ex) {
- ex.printStackTrace();
- }
- String filePath = file.getAbsolutePath();
- Log.i("IDCard", "IDCard parseImage >>> filePath: " + filePath);
- final IDCardInfo info = HttpHelp.getIDCard(new File(filePath));
- if (info != null && callback != null) {
- act.runOnUiThread(() -> callback.onIDCardResult(info));
- }
- }
- }.start();
- }
-
- public static IDCardInfo getIDCard(File file){
- if (!NetHelp.getCurConnectStatus() || file == null || file.length() <= 0){
- return null;
- }
- String accessToken = getToken();
- if (TextUtils.isEmpty(accessToken)) return null;
- String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=" + accessToken;
- String img = null;
- try {
- img = FileUtils.base64File(file);
- } catch (Exception e) {
- e.printStackTrace();
- }
- if (TextUtils.isEmpty(img)) return null;
- Response response = null;
- try {
- FormBody.Builder builder = new FormBody.Builder()
- .add("id_card_side", "front")
- .add("image", img);
- Request request = new Request.Builder()
- .url(url)
- .post(builder.build())
- .build();
- LogUtils.d("getIDCard request url :" + url + " img: " + img);
- response = httpClient.newCall(request).execute();
- } catch (IOException e) {
- LogUtils.d("getIDCard request exception: " + e.getMessage());
- e.printStackTrace();
- return null;
- }
- LogUtils.d("getIDCard response isSuccessful: " + response.isSuccessful());
- if (response != null && response.isSuccessful()) {
- try {
- String strRecData = response.body().string();
- LogUtils.d("getIDCard response body: " + strRecData);
- if (strRecData != null && strRecData.length() > 2) {
- JSONObject rootObj = new JSONObject(strRecData);
- if (rootObj != null && !rootObj.isNull("words_result")) {
- JSONObject wordObj = rootObj.getJSONObject("words_result");
- IDCardInfo info = new IDCardInfo();
- if (!wordObj.isNull("姓名") && !wordObj.getJSONObject("姓名").isNull("words")) {
- info.name = wordObj.getJSONObject("姓名").getString("words");
- }
- if (wordObj != null && !wordObj.isNull("民族") && !wordObj.getJSONObject("民族").isNull("words")) {
- info.nation = wordObj.getJSONObject("民族").getString("words");
- }
- if (wordObj != null && !wordObj.isNull("住址") && !wordObj.getJSONObject("住址").isNull("words")) {
- info.address = wordObj.getJSONObject("住址").getString("words");
- }
- if (wordObj != null && !wordObj.isNull("公民身份号码") && !wordObj.getJSONObject("公民身份号码").isNull("words")) {
- info.idNum = wordObj.getJSONObject("公民身份号码").getString("words");
- }
- if (wordObj != null && !wordObj.isNull("出生") && !wordObj.getJSONObject("出生").isNull("words")) {
- info.birthday = wordObj.getJSONObject("出生").getString("words");
- }
- if (wordObj != null && !wordObj.isNull("性别") && !wordObj.getJSONObject("性别").isNull("words")) {
- info.sex = wordObj.getJSONObject("性别").getString("words");
- }
- LogUtils.d("getIDCard response parse IDCardInfo: " + info.toString());
- return info;
- }
- }
- } catch (Exception e) {
- LogUtils.d("getIDCard response parse exception: " + e.getMessage());
- e.printStackTrace();
- return null;
- }
- }
- return null;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。