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.ormailto:. You correctly added a byte to the payload length and used an offset of1when 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 to0x03for 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:
The method
getUrlPrefixcould 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