1

我正在编写基于 NFC 的应用程序,该应用程序将使用 Url 扫描 NFC 标签。扫描标签后,应用程序应从数据库中检索信息并将其显示在 ListView 中。

扫描 NFC 标签时发生错误。

 Error in http connection java.lang.IllegalArgumentException: Illegal character in scheme at index 0: ??http://abc.com/~090123/get_items.php

logcat??之前会显示一些奇怪的字符http://

我正在使用以下代码在标签中编写 Url:

private boolean writeTag(Tag tag) {         
    byte[] uriField = "http://abc.com/~090123/get_items.php".getBytes(Charset.forName("US-ASCII"));
    byte[] payload = new byte[uriField.length + 1];

    System.arraycopy(uriField, 0, payload, 1, uriField.length);         

    NdefRecord uriRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
                NdefRecord.RTD_URI, new byte[0], payload);
    NdefMessage message = new NdefMessage(new NdefRecord[] { uriRecord});
    // ....
}

我收到来自 NFC 标签的意图,如下所示:

protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
    setContentView(R.layout.content_display);           

    Intent intent =  getIntent();    

    if(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {

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

        if(rawMsgs != null) {           

            NdefMessage msg = (NdefMessage) rawMsgs[0];        

            GetData getData = new GetData(this);
                getData.execute(new String(msg.getRecords()[0].getPayload()));
        }
    }
}

我正在使用以下代码从数据库中检索信息:

protected BufferedReader doInBackground(String... params) {
    ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
    try {
        HttpClient httpclient = new DefaultHttpClient();

        for (int i = 0; i < params.length; i++) 
        {
            HttpPost httppost = new HttpPost(params[i]);
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
             is = entity.getContent();
        }

    } catch (Exception e) {
            Log.e("log_tag", "Error in http connection " + e.toString());
    }

    Log.e("Input Stream", "Input Stream:" + is);

    BufferedReader myReader = new BufferedReader(new InputStreamReader(is));

    return myReader;
}

我对以前的 NDEF 记录有这样的意图过滤器:

<activity
            android:name=".DisplayContentActivity"
            android:label="@string/app_name" >

            <intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />
                <data
                    android:host="abc.com"
                    android:pathPrefix="/~090123/get_items.php"
                    android:scheme="http" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>

任何帮助,将不胜感激。

4

2 回答 2

3

URI 有效负载的第一个字节是URI 标识符代码,它是一个 URI 前缀,例如http://www.or mailto:。您在有效负载长度中正确添加了一个字节,并1在复制 URL 时使用了偏移量。你永远不会写这个字节,所以它仍然存在0x00没有前缀),这意味着你需要写整个 URL。这很好,但如果您想保存几个字节,您可以将其设置0x03为前缀。http://

使用 读取有效负载时msg.getRecords()[0].getPayload(),您需要切断该字节并自己添加前缀。我认为没有本机 Android API,因此您必须自己查找前缀或尝试其他答案中提到的库。

要正确读取 uri,您应该使用以下内容:

byte[] payload = msg.getRecords()[0].getPayload();
byte identifierCode = payload[0];

String prefix = getUrlPrefix(identifierCode); // you need to implement this one
String url = prefix +
    new String(payload, 1, payload.length -1, Charset.forName("US-ASCII"));

getData.execute(url);

该方法getUrlPrefix可以包含一个简单的 switch 语句来返回标识符代码的前缀字符串。

您可以在此处查看代码列表:关于 NDEF 格式

Value    Protocol
-----    --------
0x00     No prepending is done ... the entire URI is contained in the URI Field
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://
...
于 2013-02-10T14:52:23.533 回答
0

您正在错误地解析 NDEF 记录。第一个字节不是字符。要么阅读 NFC 论坛标准,要么查看我为在这种情况下提供帮助而创建的这个库。您可以查看 Android 源代码以了解您尝试读取的记录是如何构建的。

于 2013-02-10T14:46:46.487 回答