NFC教學 哈哈哈哈哈!!
NFC簡介 支持NDEF NFC Data Exchange Format (NDEF) 格式為主,它支持devices之間或device與tag之間 互相交換小型資料,是屬於近距離的無線技術。 主要偵測到的三種格式 ACTION_NDEF_DISCOVERED ACTION_TECH_DISCOVERED ACTION_TAG_DISCOVERED 這次教學使用的是Mifare Tag 屬於ACTION_TECH_DISCOVERED
NFC所需設定(一) 給予權限 <uses-permission android:name="android.permission.NFC"/> 指定最低的SDK版本 <uses-sdk android:minSdkVersion="10"/> (Android 2.3.3 (API Level 10)才有支援完整的NFC功能) 指定程式必需具有NFC晶片 <uses-feature android:name="android.hardware.nfc" android:required="true" />
NFC所需設定(二) 讀取 ACTION_TECH_DISCOVERED 格式 如果要讀取 ACTION_TECH_DISCOVERED 格式,需要在專案中增加一個新的XML檔案,定義該應用程式支持的 tech-list sets。 <intent-filter> <action android:name="android.nfc.action.TECH_DISCOVERED" /> </intent-filter> <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc" /> 這邊指定xml/nfc為需要讀取的檔案,所以我們要在專案中新增xml目錄並且在底下新增名為nfc的xml <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- capture anything using NfcF --> <tech-list> <tech>android.nfc.tech.IsoDep</tech> <tech>android.nfc.tech.NfcA</tech> <tech>android.nfc.tech.NfcB</tech> <tech>android.nfc.tech.NfcF</tech> <tech>android.nfc.tech.NfcV</tech> <tech>android.nfc.tech.Ndef</tech> <tech>android.nfc.tech.NdefFormatable</tech> <tech>android.nfc.tech.MifareClassic</tech> <tech>android.nfc.tech.MifareUltralight</tech> </tech-list> </resources>
偵測卡片(一) 讓應用程式的Activity負責處理所有接受到的NFC intents 宣告 PendingIntent mPendingIntent; MifareClassic mfc; Intent intent; NfcAdapter mAdapter; IntentFilter ndef; IntentFilter[] mFilters; String[][] mTechLists; String tag_id, tag_msg, tag_data; 讓Activity負責處理所有接收到的NFC Intents。 mAdapter = NfcAdapter.getDefaultAdapter(this); mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); //new.... 指定該Activity為應用程式中的最上層Activity↑ ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); try { ndef.addDataType("*/*"); } catch (IntentFilter.MalformedMimeTypeException e) { throw new RuntimeException("fail", e); } mFilters = new IntentFilter[]{ndef,}; mTechLists = new String[][]{new String[]{MifareClassic.class.getName()}};
偵測卡片(二) 處理由系統送來的intent @Override public void onNewIntent(Intent intent) { msg.setText("NFC有反應喔喔"); } protected void onResume() { super.onResume(); mAdapter.enableForegroundDispatch(this, mPendingIntent, mFilters, mTechLists);
Mifare TAG 簡介 分為16個磁區,每個磁區為4塊,每塊16個位元組,以塊 為存取單位。 每個磁區有獨立的一組密碼及訪問控制。 分為16個磁區,每個磁區為4塊,每塊16個位元組,以塊 為存取單位。 每個磁區有獨立的一組密碼及訪問控制。 每張卡有唯一序列號,為32位。
Mifare TAG讀取表頭 在onNewIntent底下新增 String action = intent.getAction(); if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) { Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); mfc = MifareClassic.get(tagFromIntent); boolean auth = false; tag_data = ""; try{ mfc.connect(); tagFromIntent = mfc.getTag(); auth = mfc.authenticateSectorWithKeyA(0, MifareClassic.KEY_DEFAULT); if (!auth) tag_data = "無法讀取"; tag_id = output(tagFromIntent.getId()); msg.setText("TagId:" + tag_id); } catch (IOException e) { msg.setText("No Get Tech: \n" + e); else msg.setText("本程式不支援此種類卡");
處理Byte public String output(byte[] data){ String out=""; for(int i=0;i<data.length;i++) out = out +data[i]; return out; }
Mifare TAG 讀取Block tag_data = new String(mfc.readBlock(1), Charset.forName("UTF-8")); msg.setText("TagId:" + tag_id + "\n Block:" + tag_data);
Mifare TAG 寫入Block 宣告int nfc_s = 0; 控制寫入或讀取 做兩個按鈕控制nfc_s變數(0為讀取,1為寫入) 寫入程式碼 if (!auth) tag_data = "無法寫入"; else{ byte[] value = getmsg.getText().toString().trim().getBytes("UTF-8"); byte[] toWrite = new byte[MifareClassic.BLOCK_SIZE]; for (int i = 0; i < MifareClassic.BLOCK_SIZE; i++) { if (i < value.length) toWrite[i] = value[i]; else toWrite[i] = 0; } mfc.writeBlock(1, toWrite); mfc.close(); msg.setText("寫進去囉!!嘿嘿");