2014-09-23 62 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+。如果可能的话,我仍然想要一个可以向后兼容的答案。