在NDEF URI有效载荷非法字符 [英] Illegal character in NDEF URI payload

查看:247
本文介绍了在NDEF URI有效载荷非法字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在写基于NFC的应用程序,将扫描一个URL的NFC标签。有一次,标签被扫描,应用程序应该从数据库中检索信息,并在ListView显示。

当我扫描NFC标签时,会出现错误。

 错误的HTTP连接java.lang.IllegalArgumentException异常:索引0计划中非法字符:?? HTTP://abc.com/~090123/get_items.php

在logcat中显示前 HTTP一些奇怪的 ?? 字符://

我用写的地址在标签下面code:

 私人布尔writeTag(标签标签){
    字节[] uriField =htt​​p://abc.com/~090123/get_items.php\".getBytes(Charset.forName(\"US-ASCII));
    字节[] =有效载荷新的字节[uriField.length + 1];    System.arraycopy(uriField,0,有效载荷,1,uriField.length);    NdefRecord uriRecord =新NdefRecord(NdefRecord.TNF_WELL_KNOWN,
                NdefRecord.RTD_URI,新的字节[0],负载);
    NdefMessage消息=新NdefMessage(新NdefRecord [] {uriRecord});
    // ....
}

我收到意图从NFC标签是这样的:

 保护无效的onCreate(捆绑savedInstanceState){
     super.onCreate(savedInstanceState);
    的setContentView(R.layout.content_display);    意向意图= getIntent();    如果(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent()。的getAction())){        Parcelable [] = rawMsgs intent.getParcelableArrayExtra(
            NfcAdapter.EXTRA_NDEF_MESSAGES);        如果(rawMsgs!= NULL){            NdefMessage味精=(NdefMessage)rawMsgs [0];            动画検=新的GetData(本);
                getData.execute(新的String(msg.getRecords()[0] .getPayload()));
        }
    }
}

和我是从数据库中使用以下code检索信息:

 受保护的BufferedReader doInBackground(字符串... PARAMS){
    ArrayList的<&的NameValuePair GT; namevaluepairs中=新的ArrayList<&的NameValuePair GT;();
    尝试{
        HttpClient的HttpClient的=新DefaultHttpClient();        的for(int i = 0; I< params.length;我++)
        {
            HttpPost httppost =新HttpPost(PARAMS [I]);
            httppost.setEntity(新UrlEn codedFormEntity(namevaluepairs中));
            HTT presponse响应= httpclient.execute(httppost);
            HttpEntity实体= response.getEntity();
             是= entity.getContent();
        }    }赶上(例外五){
            Log.e(log_tag,在HTTP连接错误+ e.toString());
    }    Log.e(输入流,输入流:+是);    的BufferedReader myReader =新的BufferedReader(新的InputStreamReader(是));    返回myReader;
}

我对previous NDEF记录这样的意图过滤器:

 <活动
            机器人:名字=。DisplayContentActivity
            机器人:标签=@字符串/ APP_NAME>            &所述;意图滤光器>
                <作用机器人:名字=android.nfc.action.NDEF_DISCOVERED/>
                <数据
                    机器人:主机=abc.com
                    机器人:路径preFIX =/〜090123 / get_items.php
                    机器人:计划=HTTP/>                <类机器人:名字=android.intent.category.DEFAULT/>
            &所述; /意图滤光器>
        < /活性GT;
    < /用途>

任何帮助将是AP preciated。


解决方案

URI有效载荷的第一个字节是的 URI标识code 的,它像<$一个URI preFIX C $ C> HTTP:// WWW 或至mailto:。您正确添加到有效载荷长度的字节,用于复制您的网址时 1 的偏移量。所以它仍然是你从来不写这个字节 0×00 没有preFIX 的),这意味着你需要写全URL。这是好的,但你可以将其设置为 0×03 的http:// preFIX,如果你想节约几个字节。

在读取与的有效载荷msg.getRecords()[0] .getPayload(),你需要切断该字节,并添加preFIX自己。我不认为有这个一个原生的Andr​​oid API,所以你必须来查找preFIX自己或尝试在其他的答案中提到的库。

要读取的URI正确,你应该使用这样的:

 字节[] =有效载荷msg.getRecords()[0] .getPayload();
字节的标识符code =负载[0];字符串preFIX =的getURL preFIX(标识符code); //你需要实现这一个
字符串URL = preFIX +
    新的String(有效载荷,1,-1 payload.length,Charset.forName(US-ASCII));getData.execute(URL);

该方法的getURL preFIX 可以包含一个简单的开关语句返回preFIX字符串标识符code。

您可以看到codeS这里的列表:关于NDEF格式


 值协议
----- --------
为0x00无prepending完成...的整个URI包含在URI字段
0×01 HTTP:// WWW。
0X02的https:// WWW。
×03的http://
0x04访问https://开头
0×05电话:
0×06至mailto:
0×07的ftp://匿名:匿名@
0x08的FTP:// FTP。
为0x09 FTPS://
0x0A的SFTP://
...


I'm writing NFC based app that would scan a NFC tag with a Url. Once, the tag is scanned, the app should retrieve information from a database and display it in a ListView.

The error occurs when I scan the NFC tag.

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

The logcat displays some weird ?? characters before http://.

I'm writing the Url in the tag using following code:

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});
    // ....
}

I'm receiving intent from the NFC tag like this:

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()));
        }
    }
}

And I'm retrieving information from database using the following code:

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;
}

I have the intent filter for the previous NDEF records like this:

<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>

Any help would be appreciated.

解决方案

The first byte of URI payload is the URI identifier code, it is an URI prefix like http://www. or mailto:. You correctly added a byte to the payload length and used an offset of 1 when copying your URL. You never write this byte so it remains 0x00 (no prefix), which means you need write the whole URL. This is fine, though you could set it to 0x03 for a http:// prefix if you want to save a few bytes.

When reading the payload with msg.getRecords()[0].getPayload(), you need to cut off that byte and add the prefix yourself. I don't think there's a native Android API for this, so you would have to lookup the prefix yourself or try the library mentioned in the other answer.

To read the uri correctly you should use something like this:

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);

The method getUrlPrefix could contain a simple switch statement to return a prefix string for an identifier code.

You can see a list of codes here: About the NDEF Format

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://
...

这篇关于在NDEF URI有效载荷非法字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆