问题
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.
回答1:
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:// ...
回答2:
You are parsing the NDEF Record incorrectly. The first byte is not a character. Either read in the NFC Forum standard or see this lib I've created for helping in this situation. You might check out the Android source code to see how the record you're trying to read is constructed.
来源:https://stackoverflow.com/questions/14798731/illegal-character-in-ndef-uri-payload