NFC手机二代身份证阅读开发说明
作者:互联网
随着互联网的发展,我们发现人的身份是混乱的,最终将导致交易混乱,从而会出现大量的欺诈交易。如今网络诚信,网络安全等问题已经严重制约的我国电子商务,甚至威胁到我国互联网的健康发展,实名认证有利于确定身份,让商家和客户之间彼此了解和交流,有利于网络商城的开展,避免了一些不法分子在网络上欺骗消费者。
实名认证是市场经济中不能跳过的流程,那是否意味着每一次的认证都要让人百般怀疑的进行“拍照”、“上传”这一系列步骤吗,万一真遇上“钓鱼网站”,个人信息遭到泄露,后果将不堪设想,并且繁复的上传回馈过程也大大降低了工作效率。再者,如遇到假冒伪造证件,普通民众用肉眼并不能立即识别真假,
随着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.printStackTrace();
}
if (macSerial == null || "".equals(macSerial)) {
try {
return loadFileAsString("/sys/class/net/eth0/address")
.toUpperCase().substring(0, 17);
} catch (Exception e) {
e.printStackTrace();
}
}
return macSerial;
}
public static String loadFileAsString(String fileName) throws Exception {
FileReader reader = new FileReader(fileName);
String text = loadReaderAsString(reader);
reader.close();
return text;
}
public static String loadReaderAsString(Reader reader) throws Exception {
StringBuilder builder = new StringBuilder();
char[] buffer = new char[4096];
int readLength = reader.read(buffer);
while (readLength >= 0) {
builder.append(buffer, 0, readLength);
readLength = reader.read(buffer);
}
return builder.toString();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
m_MainActivity = this;
try {
m_NfcAdpater = NfcAdapter.getDefaultAdapter(this);
if (m_NfcAdpater == null) {
Toast.makeText(this, "Not Found NfcAdapter!", Toast.LENGTH_SHORT)
.show();
// finish();
// return;
} else if (!m_NfcAdpater.isEnabled()) {
Toast.makeText(this, "Please Enabled NfcAdapter",
Toast.LENGTH_SHORT).show();
// finish();
// return;
}
} catch (java.lang.NullPointerException e) {
Toast.makeText(this, e.toString(),
Toast.LENGTH_SHORT).show();
}
m_edtLog = (EditText) findViewById(R.id.edtLog);
m_imgIdPhoto = (ImageView) findViewById(R.id.imgIdPhoto);
m_txtCommandIndex = (TextView) findViewById(R.id.txtCommandIndex);
m_edtPostCode = (EditText) findViewById(R.id.edtPostCode);
m_edtAccoutCode = (EditText) findViewById(R.id.edtAccountCode);
m_edtUserPassword = (EditText) findViewById(R.id.edtUserPassword);
pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
ndef.addCategory("*/*");
mFilters = new IntentFilter[]{ndef};// 过滤器
mTechLists = new String[][]{
new String[]{MifareClassic.class.getName()},
new String[]{NfcB.class.getName()},
new String[]{IsoDep.class.getName()},
new String[]{NfcA.class.getName()}};// 允许扫描的标签类型
// 设置USB读写回调 串口可以不用此操作
m_bCanUseUsbHostApi = SetUsbCallBack();
if (m_bCanUseUsbHostApi) {
AddLog("Find IC Reader!");
AddLog("Device Node:" + m_strDeviceNode);
} else {
AddLog("Not Find IC Reader!");
}
mLotusCardDriver = new LotusCardDriver();
mLotusCardDriver.m_lotusCallBack = this;
m_Handler = new Handler() {
public void handleMessage(Message msg) {
AddLog(msg.obj.toString());
super.handleMessage(msg);
}
};
//区分系统版本
m_nSystemVersion = Integer.parseInt(VERSION.SDK);
// if(m_nSystemVersion<19)
// onNewIntent(getIntent());
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_READ_PHONE_STATE);
} else {
//TODO
}
requestPermission();
TelephonyManager mTelephonyMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String imsi = mTelephonyMgr.getSubscriberId();
String imei = mTelephonyMgr.getDeviceId();
//String tel = mTelephonyMgr.getLine1Number();
String tel = mTelephonyMgr.getLine1Number();
if (tel == null) tel = "";
if (tel.equals("")) {
tel = mTelephonyMgr.getSubscriberId();
}
if (tel == null) tel = "";
String iccid = mTelephonyMgr.getSimSerialNumber(); //取出ICCID }
public static String int2ip(long ipInt) {
StringBuilder sb = new StringBuilder();
sb.append(ipInt & 0xFF).append(".");
sb.append((ipInt >> 8) & 0xFF).append(".");
sb.append((ipInt >> 16) & 0xFF).append(".");
sb.append((ipInt >> 24) & 0xFF);
return sb.toString();
}
public void OnClearLogListener(View arg0) {
m_imgIdPhoto.setBackgroundColor(0);
if (null == m_edtLog)
return;
m_edtLog.setText("");
}
public void OnIdOtgTestListener(View arg0) {
if (m_nDeviceHandle == -1) {
m_nDeviceHandle = mLotusCardDriver.OpenDevice("", 0, 0,
0, 0,// 使用内部默认超时设置
true);
}
if (m_nDeviceHandle == -1) return;
TwoIdInfoParam tTwoIdInfo = new TwoIdInfoParam();
boolean bResult = false;
int nResult = 0;
boolean bWlDecodeResult = false;
byte[] arrBmpAndWl = null;
String temp;
int nErrorCode = 0;
LotusCardParam tLotusCardParam1 = new LotusCardParam();
bResult = mLotusCardDriver.Beep(m_nDeviceHandle, 10);
// bResult = mLotusCardDriver.Beep(nDeviceHandle, 10);
if (!bResult) {
AddLog("Call Beep Error!");
return;
}
AddLog("Call Beep Ok!");
bResult = mLotusCardDriver.SetCardType(m_nDeviceHandle, 'B');
if (!bResult) {
AddLog("Call SetCardType Error!");
return;
}
//mLotusCardDriver.GetTwoGenerationIDCardNo(m_nDeviceHandle);
AddLog("Call SetCardType Ok!");
nResult = mLotusCardDriver.RequestB(m_nDeviceHandle,0, tLotusCardParam1);
if(nResult== 0)
{
AddLog("Call RequestB Error!");
return;
}
nResult = mLotusCardDriver.SelectB(m_nDeviceHandle, tLotusCardParam1);
if(nResult== 0)
{
AddLog("Call SelectB Error!");
return;
}
bResult = mLotusCardDriver.GetTwoIdInfoByMcuServer(this, null,
m_nDeviceHandle, "samv.highwillow.cn", Integer.valueOf(m_edtAccoutCode.getText().toString()),
m_edtUserPassword.getText().toString(), tTwoIdInfo, Long.valueOf(m_edtPostCode.getText().toString()), 0, 2, true);
if (!bResult) {
nErrorCode = mLotusCardDriver.GetTwoIdErrorCode(m_nDeviceHandle);
AddLog("Call GetTwoIdInfoByMcuServer Error! ErrorCode:" + nErrorCode);
AddLog("ErrorInfo:" + mLotusCardDriver.GetIdErrorInfo(nErrorCode));
return;
}
AddLog("Call GetTwoIdInfoByMcuServer Ok!");
if (true == bResult) {
// 姓名
try {
temp = new String(tTwoIdInfo.arrTwoIdName, 0, 30,
"UTF-16LE").trim();
if (temp.equals("")) {
AddLog("数据为空");
return;
}
AddLog("姓名:" + temp);
// 性别
temp = new String(tTwoIdInfo.arrTwoIdSex, 0, 2,
"UTF-16LE").trim();
if (temp.equals("1"))
temp = "男";
else
temp = "女";
AddLog("性别:" + temp);
// 民族
temp = new String(tTwoIdInfo.arrTwoIdNation, 0, 4,
"UTF-16LE").trim();
try {
int code = Integer.parseInt(temp.toString());
temp = decodeNation(code);
} catch (Exception e) {
temp = "";
}
AddLog("民族:" + temp);
// 出生日期
temp = new String(tTwoIdInfo.arrTwoIdBirthday, 0,
16, "UTF-16LE").trim();
AddLog("出生日期:" + temp);
// 住址
temp = new String(tTwoIdInfo.arrTwoIdAddress, 0,
70, "UTF-16LE").trim();
AddLog("住址:" + temp);
// 身份证号码
temp = new String(tTwoIdInfo.arrTwoIdNo, 0, 36,
"UTF-16LE").trim();
AddLog("身份证号码:" + temp);
// 签发机关
temp = new String(
tTwoIdInfo.arrTwoIdSignedDepartment, 0, 30,
"UTF-16LE").trim();
AddLog("签发机关:" + temp);
// 有效期起始日期
temp = new String(
tTwoIdInfo.arrTwoIdValidityPeriodBegin, 0,
16, "UTF-16LE").trim();
AddLog("有效期起始日期:" + temp);
// 有效期截止日期 UNICODE YYYYMMDD 有效期为长期时存储“长期”
temp = new String(
tTwoIdInfo.arrTwoIdValidityPeriodEnd, 0,
16, "UTF-16LE").trim();
AddLog("有效期截止日期:" + temp);
if (tTwoIdInfo.unTwoIdPhotoJpegLength > 0) {
final Bitmap photo = BitmapFactory.decodeByteArray(
tTwoIdInfo.arrTwoIdPhotoJpeg, 0,
tTwoIdInfo.unTwoIdPhotoJpegLength);
runOnUiThread(new Runnable() {
@Override
public void run() {
m_imgIdPhoto.setBackgroundDrawable(new BitmapDrawable(photo));
}
});
}
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} else {
AddLog("GetTwoIdInfoByMcuServer执行失败");
}
}
public void AddLog(String strLog) {
final String strText = strLog;
runOnUiThread(new Runnable() {
@Override
public void run() {
SimpleDateFormat formatter = new SimpleDateFormat("MM-dd HH:mm:ss:SSS");
Date curDate = new Date(System.currentTimeMillis());// 获取当前时间
String strDate = formatter.format(curDate);
if (null == m_edtLog)
return;
String strLogs = m_edtLog.getText().toString().trim();
if (strLogs.equals("")) {
strLogs = strDate + " " + strText;
} else {
strLogs += "\r\n" + strDate + " " + strText;
}
m_edtLog.setText(strLogs);
}
});
}
public void showCommandIndex(int nIndex) {
final int nTmp = nIndex;
runOnUiThread(new Runnable() {
@Override
public void run() {
m_txtCommandIndex.setText("索引" + nTmp);
}
});
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.i(Activity_TAG, "This is Information");
if (m_NfcAdpater != null) {
m_NfcAdpater.enableForegroundDispatch(this, pendingIntent, mFilters,
mTechLists);
enableReaderMode();
}
}
@Override
protected void onPause() {
super.onPause();
if (m_NfcAdpater != null) {
m_NfcAdpater.disableForegroundDispatch(this);
disableReaderMode();
}
}
@TargetApi(19)
private void enableReaderMode() {
if (m_nSystemVersion < 19)
return;
Bundle options = new Bundle();
options.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 5000);
//int READER_FLAGS = NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK;
int READER_FLAGS = NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_NFC_B | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK;
if (m_NfcAdpater != null) {
m_NfcAdpater.enableReaderMode(this, new IdReaderCallback(), READER_FLAGS, options);
}
}
@TargetApi(19)
public class IdReaderCallback implements NfcAdapter.ReaderCallback {
@Override
public void onTagDiscovered(Tag tag) {
boolean bResult = false;
boolean bWlDecodeResult = false;
String temp;
int nErrorCode = 0;
byte[] arrBmpBuffer = new byte[38862];
NfcB nfcbId = NfcB.get(tag);
byte[] arrRequest = new byte[3];
byte[] arrSelect = new byte[9];
byte[] arrResult;
//byte[] arrBmpAndWl = null;
arrRequest[0] = (byte) 0x5;
arrRequest[1] = (byte) 0x0;
arrRequest[2] = (byte) 0x0;
arrSelect[0] = (byte) 0x1D;//1D 00 00 00 00 00 08 01 08
arrSelect[1] = (byte) 0x0;
arrSelect[2] = (byte) 0x0;
arrSelect[3] = (byte) 0x0;
arrSelect[4] = (byte) 0x0;
arrSelect[5] = (byte) 0x0;
arrSelect[6] = (byte) 0x8;
arrSelect[7] = (byte) 0x1;
arrSelect[8] = (byte) 0x8;
if (nfcbId != null) {
try {
nfcbId.connect();
if (nfcbId.isConnected())
AddLog("connect");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (nfcbId.isConnected()) {
TwoIdInfoParam tTwoIdInfo = new TwoIdInfoParam();
try {
arrResult = nfcbId.transceive(arrRequest);
AddLog("length" + arrResult.length);
arrResult = nfcbId.transceive(arrSelect);
AddLog("length" + arrResult.length);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (m_nDeviceHandle == -1) {
m_nDeviceHandle = mLotusCardDriver.OpenDevice("", 0, 0,
0, 0,// 使用内部默认超时设置
true);
}
m_nCommandInex = 0;
bResult = mLotusCardDriver.GetTwoIdInfoByMcuServer(m_MainActivity, nfcbId,
m_nDeviceHandle, "samv.highwillow.cn", Integer.valueOf(m_edtAccoutCode.getText().toString()),
//m_nDeviceHandle, "192.168.1.21", 99999,
m_edtUserPassword.getText().toString(), tTwoIdInfo, Long.valueOf(m_edtPostCode.getText().toString()), 0, 3, false);
if (!bResult) {
nErrorCode = mLotusCardDriver.GetTwoIdErrorCode(m_nDeviceHandle);
AddLog("Call GetTwoIdInfoByMcuServer Error! ErrorCode:" + nErrorCode);
AddLog("ErrorInfo:" + mLotusCardDriver.GetIdErrorInfo(nErrorCode));
return;
}
AddLog("Call GetTwoIdInfoByMcuServer Ok!");
if (true == bResult) {
// 姓名
try {
temp = new String(tTwoIdInfo.arrTwoIdName, 0, 30,
"UTF-16LE").trim();
if (temp.equals("")) {
AddLog("数据为空");
return;
}
AddLog("姓名:" + temp);
// 性别
temp = new String(tTwoIdInfo.arrTwoIdSex, 0, 2,
"UTF-16LE").trim();
if (temp.equals("1"))
temp = "男";
else
temp = "女";
AddLog("性别:" + temp);
// 民族
temp = new String(tTwoIdInfo.arrTwoIdNation, 0, 4,
"UTF-16LE").trim();
try {
int code = Integer.parseInt(temp.toString());
temp = decodeNation(code);
} catch (Exception e) {
temp = "";
}
AddLog("民族:" + temp);
// 出生日期
temp = new String(tTwoIdInfo.arrTwoIdBirthday, 0,
16, "UTF-16LE").trim();
AddLog("出生日期:" + temp);
// 住址
temp = new String(tTwoIdInfo.arrTwoIdAddress, 0,
70, "UTF-16LE").trim();
AddLog("住址:" + temp);
// 身份证号码
temp = new String(tTwoIdInfo.arrTwoIdNo, 0, 36,
"UTF-16LE").trim();
AddLog("身份证号码:" + temp);
// 签发机关
temp = new String(
tTwoIdInfo.arrTwoIdSignedDepartment, 0, 30,
"UTF-16LE").trim();
AddLog("签发机关:" + temp);
// 有效期起始日期
temp = new String(
tTwoIdInfo.arrTwoIdValidityPeriodBegin, 0,
16, "UTF-16LE").trim();
AddLog("有效期起始日期:" + temp);
// 有效期截止日期 UNICODE YYYYMMDD 有效期为长期时存储“长期”
temp = new String(
tTwoIdInfo.arrTwoIdValidityPeriodEnd, 0,
16, "UTF-16LE").trim();
AddLog("有效期截止日期:" + temp);
//显示JPEG
//显示BMP
if(true == mLotusCardDriver.GetIdPhotoBmpBuffer(m_nDeviceHandle,arrBmpBuffer)) {
final Bitmap photo = BitmapFactory.decodeByteArray(
arrBmpBuffer, 0,
38862);
runOnUiThread(new Runnable() {
@Override
public void run() {
m_imgIdPhoto.setBackgroundDrawable(new BitmapDrawable(photo));
}
});
}
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} else {
AddLog("GetTwoIdInfoByMcuServer执行失败");
}
}
}
}
}
@TargetApi(19)
private void disableReaderMode() {
if (m_nSystemVersion < 19)
return;
if (m_NfcAdpater != null) {
m_NfcAdpater.disableReaderMode(this);
}
}
//@Override
protected void onNewIntent(Intent intent) {
// TODO Auto-generated method stub
super.onNewIntent(intent);
boolean bResult = false;
boolean bWlDecodeResult = false;
String temp;
int nErrorCode = 0;
Log.d(Activity_TAG, intent.getAction());
Log.i(Activity_TAG, "onNewIntent");
if (m_nSystemVersion >= 19)
return;
if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) {
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
NfcB nfcbId = NfcB.get(tagFromIntent);
if (nfcbId != null) {
try {
nfcbId.connect();
if (nfcbId.isConnected())
AddLog("connect");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (nfcbId.isConnected()) {
TwoIdInfoParam tTwoIdInfo = new TwoIdInfoParam();
if (m_nDeviceHandle == -1) {
m_nDeviceHandle = mLotusCardDriver.OpenDevice("", 0, 0,
0, 0,// 使用内部默认超时设置
true);
}
bResult = mLotusCardDriver.GetTwoIdInfoByMcuServer(this, nfcbId,
m_nDeviceHandle, "samv.highwillow.cn", 99999,
"123456", tTwoIdInfo, 400000, 0, 2, false);
if (!bResult) {
nErrorCode = mLotusCardDriver.GetTwoIdErrorCode(m_nDeviceHandle);
AddLog("Call GetTwoIdInfoByMcuServer Error! ErrorCode:" + nErrorCode);
AddLog("ErrorInfo:" + mLotusCardDriver.GetIdErrorInfo(nErrorCode));
return;
}
AddLog("Call GetTwoIdInfoByMcuServer Ok!");
//处理照片
if (0x00 == tTwoIdInfo.unTwoIdPhotoJpegLength) {
bWlDecodeResult = mLotusCardDriver.WlDecodeByServer(m_nDeviceHandle, "119.29.18.30", tTwoIdInfo);
if (!bWlDecodeResult) {
AddLog("Call WlDecodeByServer Error! ");
} else {
AddLog("Call WlDecodeByServer Ok!");
}
}
if (true == bResult) {
// 姓名
try {
temp = new String(tTwoIdInfo.arrTwoIdName, 0, 30,
"UTF-16LE").trim();
if (temp.equals("")) {
AddLog("数据为空");
return;
}
AddLog("姓名:" + temp);
// 性别
temp = new String(tTwoIdInfo.arrTwoIdSex, 0, 2,
"UTF-16LE").trim();
if (temp.equals("1"))
temp = "男";
else
temp = "女";
AddLog("性别:" + temp);
// 民族
temp = new String(tTwoIdInfo.arrTwoIdNation, 0, 4,
"UTF-16LE").trim();
try {
int code = Integer.parseInt(temp.toString());
temp = decodeNation(code);
} catch (Exception e) {
temp = "";
}
AddLog("民族:" + temp);
// 出生日期
temp = new String(tTwoIdInfo.arrTwoIdBirthday, 0,
16, "UTF-16LE").trim();
AddLog("出生日期:" + temp);
// 住址
temp = new String(tTwoIdInfo.arrTwoIdAddress, 0,
70, "UTF-16LE").trim();
AddLog("住址:" + temp);
// 身份证号码
temp = new String(tTwoIdInfo.arrTwoIdNo, 0, 36,
"UTF-16LE").trim();
AddLog("身份证号码:" + temp);
// 签发机关
temp = new String(
tTwoIdInfo.arrTwoIdSignedDepartment, 0, 30,
"UTF-16LE").trim();
AddLog("签发机关:" + temp);
// 有效期起始日期
temp = new String(
tTwoIdInfo.arrTwoIdValidityPeriodBegin, 0,
16, "UTF-16LE").trim();
AddLog("有效期起始日期:" + temp);
// 有效期截止日期 UNICODE YYYYMMDD 有效期为长期时存储“长期”
temp = new String(
tTwoIdInfo.arrTwoIdValidityPeriodEnd, 0,
16, "UTF-16LE").trim();
AddLog("有效期截止日期:" + temp);
if (tTwoIdInfo.unTwoIdPhotoJpegLength > 0) {
Bitmap photo = BitmapFactory.decodeByteArray(
tTwoIdInfo.arrTwoIdPhotoJpeg, 0,
tTwoIdInfo.unTwoIdPhotoJpegLength);
m_imgIdPhoto.setBackgroundDrawable(new BitmapDrawable(photo));
}
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} else {
AddLog("GetTwoIdInfoByMcuServer执行失败");
}
}
}
}
}
private String decodeNation(int code) {
String nation;
switch (code) {
case 1:
nation = "汉";
break;
case 2:
nation = "蒙古";
break;
case 3:
nation = "回";
break;
case 4:
nation = "藏";
break;
case 5:
nation = "维吾尔";
break;
case 6:
nation = "苗";
break;
case 7:
nation = "彝";
break;
case 8:
nation = "壮";
break;
case 9:
nation = "布依";
break;
case 10:
nation = "朝鲜";
break;
case 11:
nation = "满";
break;
case 12:
nation = "侗";
break;
case 13:
nation = "瑶";
break;
case 14:
nation = "白";
break;
case 15:
nation = "土家";
break;
case 16:
nation = "哈尼";
break;
case 17:
nation = "哈萨克";
break;
case 18:
nation = "傣";
break;
case 19:
nation = "黎";
break;
case 20:
nation = "傈僳";
break;
case 21:
nation = "佤";
break;
case 22:
nation = "畲";
break;
case 23:
nation = "高山";
break;
case 24:
nation = "拉祜";
break;
case 25:
nation = "水";
break;
case 26:
nation = "东乡";
break;
case 27:
nation = "纳西";
break;
case 28:
nation = "景颇";
break;
case 29:
nation = "柯尔克孜";
break;
case 30:
nation = "土";
break;
case 31:
nation = "达斡尔";
break;
case 32:
nation = "仫佬";
break;
case 33:
nation = "羌";
break;
case 34:
nation = "布朗";
break;
case 35:
nation = "撒拉";
break;
case 36:
nation = "毛南";
break;
case 37:
nation = "仡佬";
break;
case 38:
nation = "锡伯";
break;
case 39:
nation = "阿昌";
break;
case 40:
nation = "普米";
break;
case 41:
nation = "塔吉克";
break;
case 42:
nation = "怒";
break;
case 43:
nation = "乌孜别克";
break;
case 44:
nation = "俄罗斯";
break;
case 45:
nation = "鄂温克";
break;
case 46:
nation = "德昂";
break;
case 47:
nation = "保安";
break;
case 48:
nation = "裕固";
break;
case 49:
nation = "京";
break;
case 50:
nation = "塔塔尔";
break;
case 51:
nation = "独龙";
break;
case 52:
nation = "鄂伦春";
break;
case 53:
nation = "赫哲";
break;
case 54:
nation = "门巴";
break;
case 55:
nation = "珞巴";
break;
case 56:
nation = "基诺";
break;
case 97:
nation = "其他";
break;
case 98:
nation = "外国血统中国籍人士";
break;
default:
nation = "";
}
return nation;
}
public String toHexString(byte[] d, int s, int n) {
final char[] ret = new char[n * 2];
final int e = s + n;
int x = 0;
for (int i = s; i < e; ++i) {
final byte v = d[i];
ret[x++] = HEX[0x0F & (v >> 4)];
ret[x++] = HEX[0x0F & v];
}
return new String(ret);
}
public String toHexStringR(byte[] d, int s, int n) {
final char[] ret = new char[n * 2];
int x = 0;
for (int i = s + n - 1; i >= s; --i) {
final byte v = d[i];
ret[x++] = HEX[0x0F & (v >> 4)];
ret[x++] = HEX[0x0F & v];
}
return new String(ret);
}
public boolean callBackExtendIdDeviceProcess(Object objUser,
byte[] arrBuffer) {
// TODO Auto-generated method stub
boolean bResult = false;
NfcB nfcbId = (NfcB) objUser;
if (null == nfcbId)
return false;
byte[] arrCommnad = new byte[arrBuffer[0]];
System.arraycopy(arrBuffer, 1, arrCommnad, 0, arrBuffer[0]);
//AddLog("执行指令"+arrCommnad.length);
m_nCommandInex++;
showCommandIndex(m_nCommandInex);
try {
//Log.i("LOTUS_CARD_DRIVER","Send "+toHexString(arrCommnad, 0, arrCommnad.length));
byte[] arrResult = nfcbId.transceive(arrCommnad);
//Log.i("LOTUS_CARD_DRIVER","Receive "+toHexString(arrResult, 0, arrResult.length));
if (LotusCardDriver.isZero(arrResult)) {
AddLog("读取卡片数据全部为0");
} else {
if (arrResult.length > 2) {
if (((byte) 0x90 == arrResult[arrResult.length - 3]) &&
((byte) 0x00 == arrResult[arrResult.length - 2]) &&
((byte) 0x00 == arrResult[arrResult.length - 1])) {
arrBuffer[0] = (byte) (arrResult.length - 1);
} else {
arrBuffer[0] = (byte) (arrResult.length);
}
} else {
arrBuffer[0] = (byte) (arrResult.length);
}
System.arraycopy(arrResult, 0, arrBuffer, 1, arrBuffer[0]);
bResult = true;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
AddLog(e.getMessage());
}
return bResult;
}
private Boolean SetUsbCallBack() {
Boolean bResult = false;
PendingIntent pendingIntent;
pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(
ACTION_USB_PERMISSION), 0);
m_UsbManager = (UsbManager) getSystemService(USB_SERVICE);
if (null == m_UsbManager)
return bResult;
HashMap<String, UsbDevice> deviceList = m_UsbManager.getDeviceList();
if (!deviceList.isEmpty()) {
for (UsbDevice device : deviceList.values()) {
if ((m_nVID == device.getVendorId())
&& (m_nPID == device.getProductId())) {
m_LotusCardDevice = device;
m_strDeviceNode = m_LotusCardDevice.getDeviceName();
break;
}
}
}
if (null == m_LotusCardDevice)
return bResult;
m_LotusCardInterface = m_LotusCardDevice.getInterface(0);
if (null == m_LotusCardInterface)
return bResult;
if (false == m_UsbManager.hasPermission(m_LotusCardDevice)) {
m_UsbManager.requestPermission(m_LotusCardDevice, pendingIntent);
}
UsbDeviceConnection conn = null;
if (m_UsbManager.hasPermission(m_LotusCardDevice)) {
conn = m_UsbManager.openDevice(m_LotusCardDevice);
}
if (null == conn)
return bResult;
if (conn.claimInterface(m_LotusCardInterface, true)) {
m_LotusCardDeviceConnection = conn;
} else {
conn.close();
}
if (null == m_LotusCardDeviceConnection)
return bResult;
// 把上面获取的对性设置到接口中用于回调操作
m_UsbDeviceConnection = m_LotusCardDeviceConnection;
if (m_LotusCardInterface.getEndpoint(1) != null) {
m_OutEndpoint = m_LotusCardInterface.getEndpoint(1);
}
if (m_LotusCardInterface.getEndpoint(0) != null) {
m_InEndpoint = m_LotusCardInterface.getEndpoint(0);
}
bResult = true;
return bResult;
}
@Override
public boolean callBackReadWriteProcess(long nDeviceHandle, boolean bRead, byte[] arrBuffer) {
int nResult = 0;
boolean bResult = false;
int nBufferLength = arrBuffer.length;
int nWaitCount = 0;
if (null == m_UsbDeviceConnection)
return false;
if (null == m_OutEndpoint)
return false;
if (null == m_InEndpoint)
return false;
//AddLog("callBackReadWriteProcess nBufferLength:" + nBufferLength);
if (nBufferLength < 65)
return false;
if (true == bRead) {
arrBuffer[0] = 0;
while (true) {
nResult = m_UsbDeviceConnection.bulkTransfer(m_InEndpoint,
arrBuffer, 64, 5000);
if (nResult <= 0)
break;
if (arrBuffer[0] != 0) {
//此处调整一下
System.arraycopy(arrBuffer, 0, arrBuffer, 1, nResult);
arrBuffer[0] = (byte) nResult;
break;
}
nWaitCount++;
if (nWaitCount > 1000)
break;
}
if (nResult < 64) AddLog("m_InEndpoint bulkTransfer Read:" + nResult);
if (nResult == 64) {
bResult = true;
} else {
bResult = false;
}
} else {
nResult = m_UsbDeviceConnection.bulkTransfer(m_OutEndpoint,
arrBuffer, 64, 3000);
//AddLog("m_OutEndpoint bulkTransfer Write:"+nResult);
if (nResult == 64) {
bResult = true;
//AddLog("m_OutEndpoint bulkTransfer Write Ok!");
} else {
bResult = false;
}
}
return bResult;
}
}
注意:以下两个文本框需要输入并获取正确的用户名和密码才能接入解析服务器。
m_nDeviceHandle, "samv.highwillow.cn", Integer.valueOf(m_edtAccoutCode.getText().toString()),
m_edtUserPassword.getText().toString(), tTwoIdInfo, Long.valueOf(m_edtPostCode.getText().toString()), 0, 2, true);
以上内容是关于NFC手机二代身份证阅读开发说明,仅供参考!
标签:NFC,二代,temp,import,break,身份证,AddLog,new,byte 来源: https://blog.csdn.net/itsso/article/details/94398583