随着互联网的发展,我们发现人的身份是混乱的,最终将导致交易混乱,从而会出现大量的欺诈交易。如今网络诚信,网络安全等问题已经严重制约的我国电子商务,甚至威胁到我国互联网的健康发展,实名认证有利于确定身份,让商家和客户之间彼此了解和交流,有利于网络商城的开展,避免了一些不法分子在网络上欺骗消费者。
实名认证是市场经济中不能跳过的流程,那是否意味着每一次的认证都要让人百般怀疑的进行“拍照”、“上传”这一系列步骤吗,万一真遇上“钓鱼网站”,个人信息遭到泄露,后果将不堪设想,并且繁复的上传回馈过程也大大降低了工作效率。再者,如遇到假冒伪造证件,普通民众用肉眼并不能立即识别真假,
随着NFC手机的不断普及,利用手机NFC进行身份证证件识别和判断真伪,检测身份证信息并读取内容进行实名认证。未来,人们在线交易或签署合同时,只需用手机扫描身份证即可完成身份验证,随后便可使用该身份进行交易、合同签署,方便快捷的同时,安全性更是上升到更高层级。
NFC手机二代身份证阅读开发说明
1、首先需要在AndroidManifest.xml文件中进行权限配置,我们需要手机上网和打开NFC功能的权限。
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
</uses-permission>
<uses-permission android:name="android.permission.INTERNET" >
</uses-permission>
<uses-permission android:name="android.permission.NFC" />
<uses-feature
android:name="android.hardware.nfc"
android:required="true" />
2、在Android NFC手机二代身份证阅读工程中建立一个libs文件夹并导入.so库文件,我们提供了 包括,arm64-v8a、armeabi、armeabi-v7a、mips、mips64、x86、x86_64等一系列的库文件,开发者可以根据自己项目需求,选择性的导入.so库文件。
3、定义二代身份证阅读过程中的关键参数,如:姓名,性别,地址等。参数定义如下:
package cc.lotuscard;
public class TwoIdInfoParam {
public TwoIdInfoParam()
{
arrTwoIdName = new byte[30];
arrTwoIdSex = new byte[2];
arrTwoIdNation = new byte[4];
arrTwoIdBirthday = new byte[16];
arrTwoIdAddress = new byte[70];
arrTwoIdNo = new byte[36];
arrTwoIdSignedDepartment = new byte[30];
arrTwoIdValidityPeriodBegin = new byte[16];
arrTwoIdValidityPeriodEnd = new byte[16];
arrTwoIdNewAddress = new byte[70];
arrTwoIdPhoto = new byte[1024];
arrTwoIdFingerprint = new byte[1024];
arrTwoIdPhotoJpeg = new byte[4096];
}
/**
* 姓名 UNICODE
*/
public byte[] arrTwoIdName;
/**
* 性别 UNICODE
*/
public byte[] arrTwoIdSex;
/**
* 民族 UNICODE
*/
public byte[] arrTwoIdNation;
/**
* 出生日期 UNICODE YYYYMMDD
*/
public byte[] arrTwoIdBirthday;
/**
* 住址 UNICODE
*/
public byte[] arrTwoIdAddress;
/**
* 身份证号码 UNICODE
*/
public byte[] arrTwoIdNo;
/**
* 签发机关 UNICODE
*/
public byte[] arrTwoIdSignedDepartment;
/**
* 有效期起始日期 UNICODE YYYYMMDD
*/
public byte[] arrTwoIdValidityPeriodBegin;
/**
* 有效期截止日期 UNICODE YYYYMMDD 有效期为长期时存储“长期”
*/
public byte[] arrTwoIdValidityPeriodEnd;
/**
* 最新住址 UNICODE
*/
public byte[] arrTwoIdNewAddress;
/**
* 照片信息
*/
public byte[] arrTwoIdPhoto;
/**
* 指纹信息
*/
public byte[] arrTwoIdFingerprint;
/**
* 照片信息 JPEG 格式
*/
public byte[] arrTwoIdPhotoJpeg;
/**
* 照片信息长度 JPEG格式
*/
public int unTwoIdPhotoJpegLength;
}
注意,NFC手机二代身份证阅读开发过程中,建立项目的时候,包名必须要遵循以下格式,否则无法编译通过。
package cc.lotuscard;
4、创建一个Activity来实现NFC手机二代身份证阅读的功能。实现代码如下:
package cn.highwillow.iddemo;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.net.DhcpInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.nfc.tech.MifareClassic;
import android.nfc.tech.Ndef;
import android.nfc.tech.NfcA;
import android.nfc.tech.NfcB;
import android.os.Parcelable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.os.Build.VERSION;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.NetworkInterface;
import java.text.SimpleDateFormat;
import java.sql.Date;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import cc.lotuscard.ILotusCallBack;
import cc.lotuscard.LotusCardDriver;
import cc.lotuscard.LotusCardParam;
import cc.lotuscard.TwoIdInfoParam;
//import static GuoTeng.GtTermb.Wlt2Bmp2;
import static cc.lotuscard.LotusCardDriver.isZero;
public class MainActivity extends AppCompatActivity implements ILotusCallBack {
private static final int REQUEST_READ_PHONE_STATE = 0; // 请求码
private UsbDeviceConnection m_UsbDeviceConnection = null;
private UsbEndpoint m_InEndpoint = null;
private UsbEndpoint m_OutEndpoint = null;
private final static char[] HEX = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
private LotusCardDriver mLotusCardDriver;
private NfcAdapter m_NfcAdpater;
private PendingIntent pendingIntent;
private IntentFilter[] mFilters;
private String[][] mTechLists;
private Handler m_Handler = null;
private EditText m_edtLog;
private TextView m_txtCommandIndex;
private ImageView m_imgIdPhoto;
private Activity m_MainActivity = null;
private UsbManager m_UsbManager = null;
private UsbDevice m_LotusCardDevice = null;
private UsbInterface m_LotusCardInterface = null;
private UsbDeviceConnection m_LotusCardDeviceConnection = null;
private final int m_nVID = 1306;
private final int m_nPID = 20763;
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
private Boolean m_bUseUsbHostApi = true;
private Boolean m_bCanUseUsbHostApi = true;
private String m_strDeviceNode;
private long m_nDeviceHandle = -1;
private int m_nSystemVersion = -1;
private int m_nCommandInex = 0;
private static final String Activity_TAG = "IdDemo";
private EditText m_edtPostCode = null;
private EditText m_edtAccoutCode = null;
private EditText m_edtUserPassword = null;
private void requestPermission() {
List<String> permissionsNeeded = new ArrayList<>();
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
permissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
permissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) ==
PackageManager.PERMISSION_DENIED) {
permissionsNeeded.add(Manifest.permission.CAMERA);
}
if (permissionsNeeded.size() > 0) {
ActivityCompat.requestPermissions(this, permissionsNeeded.toArray(new
String[permissionsNeeded.size()]), 1);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int
[] grantResults) {
switch (requestCode) {
case 1: {
boolean allowed = true;
if (grantResults.length > 0) {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
//Timber.e("case 1权限没有打开");
AddLog(permissions[i] + "打开");
} else {
//Timber.e("case 1权限没有");
AddLog(permissions[i] + "关闭");
allowed = false;
break;
}
}
}
if (!allowed) {
//O TODO 自定义处理
//dialog();
//Timber.e("case 1自定义处理");
}
break;
}
}
}
/**
* 获取手机的MAC地址
*
* @return
*/
public static String getMac() {
String str = "";
String macSerial = "";
try {
Process pp = Runtime.getRuntime().exec(
"cat /sys/class/net/wlan0/address ");
InputStreamReader ir = new InputStreamReader(pp.getInputStream());
LineNumberReader input = new LineNumberReader(ir);
for (; null != str; ) {
str = input.readLine();
if (str != null) {
macSerial = str.trim();// 去空格
break;
}
}
} catch (Exception ex) {
ex.print