【问题标题】:Getting the URI from an Android NFC Intent从 Android NFC Intent 获取 URI
【发布时间】:2014-09-23 21:51:09
【问题描述】:

我正在编写一个可以使用 URI 方案侦听 NFC 标签的应用程序。

我有一个意图过滤器:

<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,尽管我已经删除了错误处理以使其更易于在 SO 上阅读:

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。我现在需要再次解析它吗?这个空字节呢。我可以忽略它吗?

真正的问题是,有没有更简单的方法?

【问题讨论】:

    标签: android android-intent uri nfc ndef


    【解决方案1】:

    当使用NDEF_DISCOVERED Intent 过滤器根据带有 URI 记录的标签触发应用程序时,检索触发应用程序的 URI 的最简单方法是查询 Intent 以获取其数据 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:anonymous@",
        /* 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:"
    };
    

    【讨论】:

      【解决方案2】:

      在重新阅读文档时找到它。

      record.toUri() - 将此记录映射到 URI,如果无法映射则返回 null

      不幸的是,这是从 API 级别 16 开始的,我希望支持 15+。如果可能的话,我仍然想要一个向后兼容的答案。

      【讨论】:

        猜你喜欢
        • 2017-02-05
        • 1970-01-01
        • 1970-01-01
        • 2014-07-22
        • 2012-09-21
        • 2023-03-09
        • 1970-01-01
        • 2018-10-31
        • 1970-01-01
        相关资源
        最近更新 更多