2013-02-10 3 views
1

Je suis en train d'écrire une application basée sur NFC qui balayerait une balise NFC avec une URL. Une fois la balise numérisée, l'application doit extraire les informations d'une base de données et les afficher dans un ListView.Caractère illégal dans la charge utile de l'URI NDEF

L'erreur se produit lorsque je numérise la balise NFC.

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

Le logcat affiche quelques ?? étranges personnages avant http://.

J'écris l'URL dans la balise en utilisant le code suivant:

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

Je reçois l'intention de l'étiquette NFC comme ceci:

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

Et je récupérer des informations de base de données en utilisant le code suivant:

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

J'ai le filtre d'intention pour les enregistrements NDEF précédents comme t son:

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

Toute aide serait appréciée.

Répondre

3

Le premier octet de la charge utile URI est le code d'identificateur URI , il est un préfixe URI comme http://www. ou mailto:. Vous avez correctement ajouté un octet à la longueur de la charge utile et utilisé un décalage de 1 lors de la copie de votre URL. Vous n'écrivez jamais cet octet de sorte qu'il reste 0x00 (pas de préfixe), ce qui signifie que vous devez écrire l'intégralité de l'URL. C'est bien, même si vous pouvez le définir à 0x03 pour un préfixe http:// si vous voulez enregistrer quelques octets. Lors de la lecture de la charge utile avec msg.getRecords()[0].getPayload(), vous devez couper cet octet et ajouter vous-même le préfixe

Je ne pense pas qu'il existe une API Android native pour cela, donc vous devrez rechercher vous-même le préfixe ou essayer la bibliothèque mentionnée dans l'autre réponse.

Pour lire le uri correctement, vous devez utiliser quelque chose comme ceci:

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

La méthode getUrlPrefix pourrait contenir une simple déclaration de commutateur pour retourner une chaîne de préfixe pour un code d'identification.

Vous pouvez voir une liste des codes ici: 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

Salut, je l'ai essayé d'ajouter le code URI identifiant comme ceci: octet [] = charge utile nouvel octet [uriField. longueur + 1]; charge utile [0] = 0x03; System.arraycopy (uriField, 0, charge utile, 1, uriField.longueur); Je reçois toujours la même erreur. – Sujal

+0

@Sujal Le point principal était que l'octet de code d'identification est inclus dans la charge utile lors de sa lecture. J'ai mis à jour la réponse avec un exemple. – Kapep

+0

Merci beaucoup! Cela a résolu le problème. – Sujal

0

Vous ne lisez pas correctement l'enregistrement NDEF. Le premier octet n'est pas un caractère. Soit lu dans la norme Forum NFC ou voir ce lib que j'ai créé pour aider dans cette situation. Vous pouvez consulter le code source Android pour voir comment l'enregistrement que vous essayez de lire est construit.

Questions connexes