一、概要
本例子為讀取nfca類型的數據,應用場景是讀取燃氣卡的id。
二、示例代碼
1.在AndroidManifest.xml中加入nfc權限
<!-- 支持nfc功能--> <uses-permission android:name="android.permission.NFC" /> <!-- 只有提供了nfc功能的手機可安裝--> <uses-feature android:name="android.hardware.nfc" android:required="true" />
2.新建一個BaseNfcActivity
public class BaseNfcActivity extends FragmentActivity { protected NfcAdapter mNfcAdapter; private PendingIntent mPendingIntent; /** * onCreat->onStart->onResume->onPause->onStop->onDestroy * 啟動Activity,界面可見時. */ @Override protected void onStart() { super.onStart(); //此處adapter需要重新獲取,否則無法獲取message mNfcAdapter = NfcAdapter.getDefaultAdapter(this); //一旦截獲NFC消息,就會通過PendingIntent調用窗口 mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()), 0); if (!ifNFCUse()) { ToastUtil.getInstance() .showTips(this, R.mipmap.ic_launcher, "請在系統中打開nfc功能"); } } /**以下是nfc相關的介紹*/ /** * 檢測工作,判斷設備的NFC支持情況 * * @return */ protected boolean ifNFCUse() { if (mNfcAdapter == null) { ToastUtil.getInstance().show(this, "設備不支持NFC!"); return false; } if (mNfcAdapter != null && !mNfcAdapter.isEnabled()) { ToastUtil.getInstance().show(this, "請在系統設置中先啟用NFC功能!"); return false; } return true; } /**nfc介紹結束*/ /** * 獲得焦點,按鈕可以點擊 */ @Override public void onResume() { super.onResume(); //設置處理優於所有其他NFC的處理 if (mNfcAdapter != null) mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, null, null); } /** * 暫停Activity,界面獲取焦點,按鈕可以點擊 */ @Override public void onPause() { super.onPause(); //恢復默認狀態 if (mNfcAdapter != null) mNfcAdapter.disableForegroundDispatch(this); } }
3.新建一個子類SubNfcActivity繼承BaseNfcActivity
public class SubNfcActivity extends BaseNfcActivity { private String mTagText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_ic_card_distinguish); }
//必須要重寫onNewIntent,不然獲取不到ic卡數據 @Override public void onNewIntent(Intent intent) { //1.獲取Tag對象 super.onNewIntent(intent); String icCardString = readNFCAData(intent); Log.e("ic卡號:",icCardString);
} /** * 讀取nfca類型的卡號 * @param intent * @return */ public String readNFCAData(Intent intent){ //1.獲取Tag對象 StringBuilder sb = new StringBuilder(); Bundle datas = intent.getExtras(); Set<String> keys = datas.keySet(); for (String key : keys){ if("android.nfc.extra.ID".equals(key)){ String data = byteArrayToHex((byte[]) datas.get(key)); String replaceSpace = getReverseStr(data); sb.append(Long.parseLong(replaceSpace,16)); } } return sb.toString(); } /** * 得到的data數據取反 * @param data * @return */ private String getReverseStr(String data){ String[] icStrSub = data.split(" "); StringBuilder myResult = new StringBuilder(); for(int i=icStrSub.length-1;i>=0;i--){ myResult.append(icStrSub[i]); } return myResult.toString(); } private String byteArrayToHex(byte[] bytes) { StringBuffer sBuffer = new StringBuffer(); for(byte b : bytes){ int hexInt = b<0?256+b:b; if(hexInt<10){ sBuffer.append("0"+Integer.toHexString(hexInt)+" "); }else{ sBuffer.append(Integer.toHexString(hexInt)+" "); } } return sBuffer.toString().toUpperCase(); } }
4.在AndroidManifest.xml中注冊Activity,並且吧其啟動模式設置給singleTop
<activity android:name=".SubNfcActivity" android:launchMode="singleTop" />
到此就結束了,把代碼往項目中一貼,運行一下做測試就行了。
注意事項:
ic卡識別頁面盡量不要有什么可以獲取焦點的地方(特別是第一項),不然會出現莫名其妙的問題。在上述案例中表現為,如果SubNfcActivity的布局中有一個向左的返回按鈕,則識別過程中有很大概率返回按鈕會被選中,頁面會莫名其妙關閉的情況。