2013-02-10 18 views
1

我正在寫基於NFC的應用程序,它會使用Url掃描NFC標籤。一旦標籤被掃描,應用程序應該從數據庫中檢索信息並將其顯示在ListView中。NDEF URI有效負載中的非法字符

當我掃描NFC標籤時發生錯誤。

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

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

我用下面的代碼寫地址的標籤:

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記錄的意圖過濾器,如t他:

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

任何幫助,將不勝感激。

回答

3

URI有效負載的第一個字節是URI標識符碼,它是一個URI的前綴等http://www.mailto:。您正確添加了一個字節到有效負載長度,並在複製您的URL時使用了1的偏移量。你永遠不會寫這個字節,所以它仍然是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可以包含一個簡單的開關語句返回一個前綴字符串爲識別碼。

你可以在這裏看到代碼列表: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:[email protected] 
0x08  ftp://ftp. 
0x09  ftps:// 
0x0A  sftp:// 
... 
+0

嗨,我已經試過加入URI標識代碼: 的byte [] =有效載荷新的字節[uriField。長度+ 1]; payload [0] = 0x03; System.arraycopy(uriField,0,有效載荷,1,uriField。長度); 我仍然得到相同的錯誤。 – Sujal 2013-02-10 19:34:36

+0

@Sujal主要觀點是,讀取標識符代碼字節時將包含在有效內容中。我用一個例子更新了答案。 – Kapep 2013-02-10 22:01:28

+0

非常感謝!這解決了這個問題。 – Sujal 2013-02-10 22:47:48

0

您正在解析NDEF記錄不正確。第一個字節不是一個字符。請閱讀NFC論壇標準,或者看看我在這種情況下幫助創建的lib。您可以查看Android源代碼來查看您想要讀取的記錄是如何構建的。

相關問題