2014-09-23 66 views
1

我正在編寫一個應用程序,可以使用URI方案來偵聽NFC標籤。從Android NFC獲取URI意圖

我有一個意圖過濾器:

<intent-filter> 
    <action android:name="android.nfc.action.NDEF_DISCOVERED" /> 
    <category android:name="android.intent.category.DEFAULT" /> 
    <data android:scheme="[theschemeofmyuri]" /> 
</intent-filter> 

和活動被正確地推出了針對我的NFC標籤。現在我寫的代碼邪惡塊,試圖提取URI,雖然我已刪除了錯誤處理,以使其更容易因此,閱讀:

Intent intent = getIntent(); 
Bundle bundle = intent.getExtras(); 

NdefMessage[] msgs; 

Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); 

msgs = new NdefMessage[rawMsgs.length]; 
for (int i = 0; i < rawMsgs.length; i++) { 
    msgs[i] = (NdefMessage) rawMsgs[i]; 
} 

NdefRecord[] recs = msgs[0].getRecords(); 

Log.i(TAG, new String(recs[0].getPayload(), "UTF-8")); 

這似乎是打印出來了空字節在開始。

事情是,我知道URI已經被意圖過濾器的系統解析。我現在需要再次解析嗎?那麼這個空字節呢?我可以忽略它嗎?

真正的問題是,有沒有更簡單的方法?

回答

2

當使用NDEF_DISCOVERED意圖過濾器來觸發在與URI記錄,檢索觸發該應用程序是查詢其數據的意圖URI的URI的最簡單的方法標籤的應用:

Intent intent = getIntent(); 
Uri uri = intent.getData();     // retrieve a Uri object instance or 
String uriString = intent.getDataString(); // retrieve the string representation of the URI 

另外,您可以處理從標記接收到的完整NDEF消息並從中解碼URI。請注意,在某些情況下,這可能會變得複雜(例如,如果使用智能海報記錄)。假設您已經從NDEF消息中提取URI記錄(如果第一條記錄是智能海報記錄,則是第一條記錄或嵌套在第一條記錄中的URI記錄),則您需要根據NFC解碼記錄的有效負載論壇的URI記錄類型定義規格:

NdefRecord uriRecord = ...; 
byte[] payload = uriRecord.getPayload(); 

int prefixCode = payload[0] & 0x0FF; 
if (prefixCode >= URI_PREFIX.length) prefixCode = 0; 

String reducedUri = new String(payload, 1, payload.length - 1, Charset.forName("UTF-8")); 

String uri = URI_PREFIX[prefixCode] + reducedUri; 

隨着URI_PREFIX定義爲:

final String[] URI_PREFIX = new String[] { 
    /* 0x00 */ "", 
    /* 0x01 */ "http://www.", 
    /* 0x02 */ "https://www.", 
    /* 0x03 */ "http://", 
    /* 0x04 */ "https://", 
    /* 0x05 */ "tel:", 
    /* 0x06 */ "mailto:", 
    /* 0x07 */ "ftp://anonymous:[email protected]", 
    /* 0x08 */ "ftp://ftp.", 
    /* 0x09 */ "ftps://", 
    /* 0x0A */ "sftp://", 
    /* 0x0B */ "smb://", 
    /* 0x0C */ "nfs://", 
    /* 0x0D */ "ftp://", 
    /* 0x0E */ "dav://", 
    /* 0x0F */ "news:", 
    /* 0x10 */ "telnet://", 
    /* 0x11 */ "imap:", 
    /* 0x12 */ "rtsp://", 
    /* 0x13 */ "urn:", 
    /* 0x14 */ "pop:", 
    /* 0x15 */ "sip:", 
    /* 0x16 */ "sips:", 
    /* 0x17 */ "tftp:", 
    /* 0x18 */ "btspp://", 
    /* 0x19 */ "btl2cap://", 
    /* 0x1A */ "btgoep://", 
    /* 0x1B */ "tcpobex://", 
    /* 0x1C */ "irdaobex://", 
    /* 0x1D */ "file://", 
    /* 0x1E */ "urn:epc:id:", 
    /* 0x1F */ "urn:epc:tag:", 
    /* 0x20 */ "urn:epc:pat:", 
    /* 0x21 */ "urn:epc:raw:", 
    /* 0x22 */ "urn:epc:", 
    /* 0x23 */ "urn:nfc:" 
}; 
1

在重新閱讀文檔時發現它。

record.toUri() - 這條記錄映射到一個URI,或返回null如果它不能被映射

不幸的是,這是從API級別16,我希望支持15+。如果可能的話,我仍然想要一個可以向後兼容的答案。