2016-07-01 14 views
1

Ich habe eine App, die die Nutzlast eines NDEF-Datensatzes auf MIFARE Ultralight-Tags liest.Android NFC: 'd' vorangestellt NDEF Nutzlast

Die Nutzlast in einen NDEF Text Datensatz gepackt und der Textwert ist in folgendem Format:

1,10,200,Arthur smith 

So gibt es immer drei Kommas, die die 3-Nummern und den Namen trennen.

Ich benutze NXP TagWriter, um das Tag zu formatieren, und meine App kann die Nutzlast korrekt lesen. Das Problem ist, dass die Firma, für die ich arbeite, eine separate Firma verwendet hat, um die Tags für uns zu formatieren. Wenn meine App diese Tags scannt, liegt ein Problem vor. Die Payload liest dann:

Dies bewirkt, dass meine App das Tag nicht verarbeiten.

Die NXP App kann erfolgreich lesen Sie das das Tag und wenn ich das Tag mit den gleichen Daten mit NXP TagWriter formatieren, dann wird meine App das Tag korrekt lesen.

Es scheint, dass es ein 'd' vor der Nutzlast gibt, wenn es von der Formatierungsfirma kommt, die nur meine App sehen kann.

Hat jemand irgendwelche Ideen, was das "d" ist und wie ich das beheben kann? Hier

ist der Code, den ich verwende, um die Nutzlast zu lesen:

if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(i.getAction()) || NfcAdapter.ACTION_TAG_DISCOVERED.equals(i.getAction())) { 
    if(NfcScannerApplication.isCanScanNfcTag() == true){ 
     messages = i.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); 
     if (messages != null) { 
      //setContentView(R.layout.successfulnfc); 
      NfcScannerApplication.startNfcTimer(); 
      //Toast.makeText(this, "NFC timer set", Toast.LENGTH_LONG).show(); 
      Log.e(TAG, "Found " + messages.length + " NDEF messages"); // is almost always just one 
      vibrate(); // signal found messages :-) 

      // parse to records 
      for (int i = 0; i < messages.length; i++) { 
       List<Record> records = null; 
       try { 
        records = new Message((NdefMessage)messages[i]); 
       } catch (FormatException e) { 
        e.printStackTrace(); 
       } 
       Log.e(TAG, "Found " + records.size() + " records in message " + i); 

       for(int k = 0; k < records.size(); k++) { 
        Log.e(TAG, " Record #" + k + " is of class " + records.get(k).getClass().getSimpleName()); 

        Record record = records.get(k); 
        NdefRecord ndefRecord = record.getNdefRecord(); 
        byte[] arr = ndefRecord.getPayload(); 

        String payload = new String(arr); 

        if(payload.length() > 0){ 
         payload = payload.substring(3, payload.length()); 

         Log.e(TAG, "payload = " + payload); 

         int counter = 0; 
         for(int z = 0; z < payload.length(); z++) { 
          if(payload.charAt(z) == ',') { 
           counter++; 
          } 
         } 

         if(counter == 3){ 
          //Toast.makeText(this, "comma count = 3 ", Toast.LENGTH_SHORT).show(); 
          String[] splitPayload = payload.split(","); 
          String tagType = splitPayload[0]; 
          String tagCompany = splitPayload[1]; 
          String tagClientID = splitPayload[2]; 
          String tagClientName = splitPayload[3]; 
+0

Wie Sie die Nutzlast lesen Sie in Ihrem App? Wie schreiben Sie die Payload (d. H. Welches Format haben Sie gewählt) mit NXP TagWriter? –

+0

Ich habe ein wenig Forschung mit der NFC-Tag-Formatierung Firma getan und sie laden die Daten auf dem Tag über .csv-Datei in NXP TagWriter. Wenn sie die Daten manuell einzeln in die Tags schreiben, wird kein 'd' vorangestellt. Es scheint, dass das "d" erscheint, wenn es von einem Excel-Blatt geladen wird. – turtleboy

+0

Das Format, das ich benutze, wenn ich NXP-Tagwriter benutze, ist reiner Text. Ich kann Ihnen meinen Quellcode in Bezug auf den Code posten, den ich benutze, um die Nutzlast zu lesen. [EDIT1] – turtleboy

Antwort

0

Meine Vermutung ist, dass es etwas sein könnte, dass die Formatierung Unternehmen auf die Tags tun sie so erstellen, um sicherzustellen, dass Ihr Unternehmen kann nicht Wechsel von ihnen so leicht.

Ich sehe jedoch nicht, warum Sie nicht einfach die Nutzlast für die erste "d" überprüfen und dann nur abziehen, wenn es gefunden wird.

+0

K Hallo, ja, ich versuche nur eine Quellcodeänderung zu vermeiden, da etwa 4000 Geräte derzeit meine App darauf haben und es logistisch ein Albtraum ist – turtleboy

+0

Ich würde es für heute am besten halten, solange es noch früh ist . Es scheint jedoch, dass es bereits nicht funktioniert, wenn Ihre App eines der anderen Tags scannt, sodass ein Update nur von Vorteil ist. –

0

Es stellt sich heraus, dass es einen Fehler in der NXP TagWiter App gibt, der das 'd' voraussetzt. Ich bin gezwungen, auf das Update von NXP zu warten, das dieses Problem behebt.

Danke für Ihre Hilfe.

1

Ihr Code dekodiert nicht ordnungsgemäß die Nutzlast des NDEF-Textdatensatzes. Sie sind unter der Annahme, dass die Nutzlast UTF-8 codiert (Standard-Kodierung auf Android), und daß der eigentliche Text Wert beginnt bei 3 der decodierten String-Offset:

NdefRecord ndefRecord = record.getNdefRecord(); 
byte[] arr = ndefRecord.getPayload(); 
String payload = new String(arr); 
payload = payload.substring(3, payload.length()); 

jedoch diese Annahmen falsch sind. Ein Textdatensatz besteht aus einem Statusbyte, gefolgt von einem Sprachencode (!) Mit variabler Länge (US-ASCII-codiert) und dem Textwert selbst (entweder in UTF-8 oder UTF-16 codiert). Folglich kann das zusätzliche "d", das Sie sehen, tatsächlich Teil des Sprachcodes sein oder ein Ergebnis der Decodierung inkorrekter Zeichencodes (z. B. des Werts des Statusbytes) in eine UTF-8-Zeichenfolge sein.

Deshalb, um den Textwert zu erhalten, müssen Sie zuerst Statusbyte die Länge des Sprachcode und die Codierung des Textwertes zu finden:

byte[] payloadBytes = ndefRecord.getPayload(); 
boolean isUTF8 = (payloadBytes[0] & 0x080) == 0; //status byte: bit 7 indicates encoding (0 = UTF-8, 1 = UTF-16) 
int languageLength = payloadBytes[0] & 0x03F;  //status byte: bits 5..0 indicate length of language code 
int textLength = payloadBytes.length - 1 - languageLength; 
String languageCode = new String(payloadBytes, 1, languageLength, "US-ASCII"); 
String payloadText = new String(payloadBytes, 1 + languageLength, textLength, isUTF8 ? "UTF-8" : "UTF-16");