高級NFC(Advanced NFC) 根據官網個人翻譯


高級NFC(Advanced NFC)


這篇文檔介紹了高級NFC主題,例如使用各種標籤技術,允許一個應用在前臺處理intent哪怕是其他應用過濾了同一個的前臺分發。

與被支持的標籤協作(Working with Supported Tag Technologies

當安卓設備和NFC標籤交互的時候,大多數時候你在標籤上讀、寫的主要格式是NDEF。當設備掃描到NDEF數據,Android支持在NdefMessage中解析和傳遞消息,在可能的情況下。但是仍然有很多時候你掃描到的標籤不包含NDEF數據或者NDEF數據不能被映射到一個MIME類型或URI。在這些情況下,你需要使用你自己的協議直接與標籤通訊和讀寫信息(在原始字節)。Android通過android.nfc.tech包支持這些情形,在表1有具體描述。你可以使用getTechList()方法確定被支持的標籤技術,用android.nfc.tech包下的類建立相應的TagTechnology對象。
表1. 支持的標籤技術
類(Class) 描述(Description)
TagTechnology 所有標籤技術類都必須實現的接口
NfcA 提供訪問NFC-A (ISO 14443-3A)屬性和I/O操作
NfcB 提供訪問NFC-B (ISO 14443-3B) 屬性和I/O操作
NfcF 提供訪問NFC-F (JIS 6319-4)屬性和I/O操作
NfcV 提供訪問NFC-V (ISO 15693) 屬性和I/O操作
IsoDep 提供訪問ISO-DEP (ISO 14443-4) 屬性和I/O操作
Ndef 提供訪問被格式化的NFC標籤上的NDEF數據和操作
NdefFormatable 提供可能被NDEF格式化的標籤的格式化操作
接下來的標籤技術不是被安卓設備支持的。
表2. 可選的支持標籤
類(Class) 描述(Description)
MifareClassic 提供訪問MIFARE傳統屬性和I/O操作,如果安卓設備支持MIFARE.
MifareUltralight 提供訪問MIFARE的Ultralight屬性和I/O操作,如果安卓設備支持MIFARE.

使用標籤技術和ACTION_TECH_DISCOVERED intent(Working with tag technologies and the ACTION_TECH_DISCOVERED intent

當設備掃描到一個帶有NDEF數據但不能被映射到一個MIME或者URI的標籤,tag dispatch system會試着通過ACTION_TECH_DISCOVERED intent啓動一個activity。當被掃描到帶有non-NDEF數據的標籤的時候ACTION_TECH_DISCOVERED也會被使用。這種保守策略使得當tag dispatch system不能解析你的標籤的時候你仍然能正確處理標籤上的數據。使用標籤技術的基本步驟如下所示:
1. 過濾你想處理的用來說明標籤技術的ACTION_TECH_DISCOVERED intent。更多信息參閱Filtering for NFC intents一般來說,當一個NDEF消息不能被映射到一個MIME類型或者URI,或者掃描到的標籤不帶有NDEF數據的時候,tag dispatch system會啓動一個ACTION_TECH_DISCOVERED intent。想看更多關於如何被決定的,請看The Tag Dispatch System
2. 當你的應用接收到一個intent,得到裏面的Tag對象:
  1. Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
3. 得到一個TagTechnology的實例,通過調用android.nfc.tech包下的類的工廠方法:get。你在調用get工廠方法之前可以調用getTechList()列舉被支持的標籤。例如得到一個Tag中的MifareUltralight的實例,像下面這樣:
  1. MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));

讀寫標籤(Reading and writing to tags

讀寫NFC標籤包括從標籤中得到intent和跟標籤通訊。你必須定義你自己的協議棧來向標籤讀寫數據。然後需要注意的是,當正確處理了一個標籤你仍然可以讀寫NDEF數據。這取決於你如何組織事務。下面的例子展示瞭如何使用MIFARE Ultralight標籤。
  1. package com.example.android.nfc;
  2. import android.nfc.Tag;
  3. import android.nfc.tech.MifareUltralight;
  4. import android.util.Log;
  5. import java.io.IOException;
  6. import java.nio.charset.Charset;
  7. public class MifareUltralightTagTester {
  8. private static final String TAG = MifareUltralightTagTester.class.getSimpleName();
  9. public void writeTag(Tag tag, String tagText) {
  10. MifareUltralight ultralight = MifareUltralight.get(tag);
  11. try {
  12. ultralight.connect();
  13. ultralight.writePage(4, "abcd".getBytes(Charset.forName("US-ASCII")));
  14. ultralight.writePage(5, "efgh".getBytes(Charset.forName("US-ASCII")));
  15. ultralight.writePage(6, "ijkl".getBytes(Charset.forName("US-ASCII")));
  16. ultralight.writePage(7, "mnop".getBytes(Charset.forName("US-ASCII")));
  17. } catch (IOException e) {
  18. Log.e(TAG, "IOException while closing MifareUltralight...", e);
  19. } finally {
  20. try {
  21. ultralight.close();
  22. } catch (IOException e) {
  23. Log.e(TAG, "IOException while closing MifareUltralight...", e);
  24. }
  25. }
  26. }
  27. public String readTag(Tag tag) {
  28. MifareUltralight mifare = MifareUltralight.get(tag);
  29. try {
  30. mifare.connect();
  31. byte[] payload = mifare.readPages(4);
  32. return new String(payload, Charset.forName("US-ASCII"));
  33. } catch (IOException e) {
  34. Log.e(TAG, "IOException while writing MifareUltralight
  35. message...", e);
  36. } finally {
  37. if (mifare != null) {
  38. try {
  39. mifare.close();
  40. }
  41. catch (IOException e) {
  42. Log.e(TAG, "Error closing tag...", e);
  43. }
  44. }
  45. }
  46. return null;
  47. }
  48. }

使用前臺發佈系統Using the Foreground Dispatch System

前臺發佈系統允許activity攔截一個intent並且聲明對處理同一個intent的比其他activity更高的優先權。使用這個系統涉及到構建一些使安卓系統能向你的應用發送合適的intent的數據結構。啓用前臺調度系統:
1. 添加如下代碼到你activity的onCreate()方法中:
        1). 創建一個PendingIntent對象使得當標籤被掃描的時候安卓系統可以用標籤描述來填充它。
  1. PendingIntent pendingIntent = PendingIntent.getActivity(
  2. this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
       2). 聲明一個intent filter來處理你想攔截的intent。前臺發佈系統在設備掃描標籤的時候通過收到的intent檢查被規定的intent filter。如果匹配,你的應用就處理這個intent。如果不匹配,前臺發佈系統落回intent發佈系統。指定一個intent過濾器和technology過濾器的空數組,指定所有回落到TAG_DISCOVERED intent的你想過濾的標籤。下面的代碼片段處理了所有NDEF_DISCOVERED的MIME類型。你應該只處理你需要的那些。
  1. IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
  2. try {
  3. ndef.addDataType("*/*"); /* Handles all MIME based dispatches.
  4. You should specify only the ones that you need. */
  5. }
  6. catch (MalformedMimeTypeException e) {
  7. throw new RuntimeException("fail", e);
  8. }
  9. intentFiltersArray = new IntentFilter[] {ndef, };
        3). 創建你的應用程序想處理的標籤技術的數組。調用Object.class.getName()方法來得到你想支持的技術的類。
  1. techListsArray = new String[][] { new String[] { NfcF.class.getName() } };
2. 重寫下面的activity生命週期方法,在當activity失去(onPause())和重新獲得(onResume())焦點的時候添加邏輯來啓用和禁用前臺發佈系統。enableForegroundDispatch()必須在主線程中且activity在前臺(在onReaume()中調用以保證效果)的時候調用。你也必須實現onNewIntent回調來處理從NFC標籤中的數據。
  1. public void onPause() {
  2. super.onPause();
  3. mAdapter.disableForegroundDispatch(this);
  4. }
  5. public void onResume() {
  6. super.onResume();
  7. mAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray);
  8. }
  9. public void onNewIntent(Intent intent) {
  10. Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
  11. //do something with tagFromIntent
  12. }

想看完整的例子請到API Demos中查看ForegroundDispatch














發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章