在NDEF URI有效载荷非法字符 [英] Illegal character in NDEF URI payload
问题描述
我在写基于NFC的应用程序,将扫描一个URL的NFC标签。有一次,标签被扫描,应用程序应该从数据库中检索信息,并在ListView显示。
当我扫描NFC标签时,会出现错误。
错误的HTTP连接java.lang.IllegalArgumentException异常:索引0计划中非法字符:?? HTTP://abc.com/~090123/get_items.php
在logcat中显示前 HTTP一些奇怪的
。 ??
字符://
我用写的地址在标签下面code:
私人布尔writeTag(标签标签){
字节[] uriField =http://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自己。我不认为有这个一个原生的Android 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 beforehttp://
.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.
ormailto:
. You correctly added a byte to the payload length and used an offset of1
when copying your URL. You never write this byte so it remains0x00
(no prefix), which means you need write the whole URL. This is fine, though you could set it to0x03
for ahttp://
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屋!