2

I am having an issue with NFC in a project I am currently making for school. It is the first time I try to use NFC in an application and might therefore not have a proper understanding of how it works.

The issue is that we have been testing the application on a HTC One M8 for the past week, where our application had no problems reading the string on our chip.

However when I'm now trying with a family member's LG Nexus 5, the string does not get passed to the application.

Here is the code:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_app);
    //NFC Adapter
    nfcAdapter = NfcAdapter.getDefaultAdapter(this);
}

@Override
protected void onResume() {
    super.onResume();
    enableForegroundDispatchSystem();
}

@Override
protected void onPause() {
    super.onPause();
    disableForegroundDispatchSystem();
}

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);

    if (intent.hasExtra(NfcAdapter.EXTRA_TAG)) {
        Toast.makeText(this, "NfcIntent!", Toast.LENGTH_SHORT).show();

        Parcelable[] parcelables = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
        if (parcelables != null && parcelables.length > 0) {
            // this part gets executed on the HTC Once m8
            readTextFromMessage((NdefMessage) parcelables[0]);
        } else {
            // this part gets executed on the LG Nexus 5
            Toast.makeText(this, "No NDEF messages found!", Toast.LENGTH_SHORT).show();
        }
    }
}

private void readTextFromMessage(NdefMessage ndefMessage) {
    NdefRecord[] ndefRecords = ndefMessage.getRecords();
    if (ndefRecords != null && ndefRecords.length>0) {
        NdefRecord ndefRecord = ndefRecords[0];

        String tagContent = getTextFromNdefRecord(ndefRecord);
        if (tagContent.toString().equals("Kasse")) {
            //scanBtn.setVisibility(View.VISIBLE);
        } else {
            //addItem(tagContent);
            //cartArrayDisplay.addView(nameList.get(cartAmount));
            //priceArrayDisplay.addView(priceList.get(cartAmount));
            //cartAmount++;
        }
    } else {
        Toast.makeText(this, "No NDEF records found!", Toast.LENGTH_SHORT).show();
    }
}

private void enableForegroundDispatchSystem() {
    Intent intent = new Intent(this, AppActivity.class).addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
    IntentFilter[] intentFilters = new IntentFilter[]{};
    nfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFilters, null);
}

private void disableForegroundDispatchSystem() {
    nfcAdapter.disableForegroundDispatch(this);
}

public String getTextFromNdefRecord(NdefRecord ndefRecord) {
    String tagContent = null;
    try {
        byte[] payload = ndefRecord.getPayload();
        String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16";
        int languageSize = payload[0] & 0063;
        tagContent = new String(payload, languageSize + 1,
                payload.length - languageSize - 1, textEncoding);
    } catch (UnsupportedEncodingException e) {
        Log.e("getTextFromNdefRecord", e.getMessage(), e);
    }
    return tagContent;
}

When run the app on the HTC One m8 it would always run this part:

if (parcelables != null && parcelables.length > 0) {
    readTextFromMessage((NdefMessage) parcelables[0]);

However, when run the app on the LG Nexus 5 it runs this part:

} else {
    Toast.makeText(this, "No NDEF messages found!", Toast.LENGTH_SHORT).show();

I have been told that it is most likely due to the tags we're using not being compatible with all devices. However, I thought it could also be something programmatically, since I am not experienced working with Android and NFC.

The tags are student IDs. A tag reader app identified one of them as

  • Tag Type: Mifare Classic 1k
  • NUID[4]: dbc3f12d
  • ATQA: 0004
  • SAK: 08
  • Target technology: android.nfc.tech.NfcA
Michael Roland
  • 39,663
  • 10
  • 99
  • 206
  • In order to guess what could probably go wrong, you would need to show us how you write the message onto the tag and what type of tag you use. Even better, scan the tag with one of the available apps for analyzing NFC tags (e.g. NFC TagInfo) and show us what it displays about the type of tag and the NDEF message stored on it. – Michael Roland Dec 17 '15 at 23:23
  • I just did. The Tag Type is Mifare Classic 1k. There is other information like NUID[4] = dbc3f12d, ATQA = 0004, SAK = 08, Target technology = android.nfc.tech.NfcA – Jonas Mohr Pedersen Dec 18 '15 at 16:08

2 Answers2

1

The problem you are experiencing is a result of the NFC chipset in your device not being compatible with MIFARE Classic. Typically, only devices with an NFC chipset from NXP are capable of reading MIFARE Classic (NXP is the owner of the MIFARE technology).

MIFARE Classic uses the anti-collision and activation mechanism defined in ISO/IEC 14443 Type A (and also ISO/IEC 18092). Therefore, that part matches the way other contactless smartcards and NFC tags work. As a result, all (most!) Android NFC devices will detect such cards/tags. However, the communication protocol and framing deviates from that defined for other NFC tags and contactless smartcards. This non-standard protocol is not available on other chipsets than those by NXP and therefore, no data can be read from MIFARE Classic cards on devices with non-NXP NFC controllers.

The HTC One m8 contains NXP's PN544 NFC controller and can therefore discover your tag and read data from it. The LG Nexus 5 contains Broadcom's BCM20793 NFC controller and can therefore discover your tag but is unable to read data from it.

Michael Roland
  • 39,663
  • 10
  • 99
  • 206
1

On top of what Michael said, you can check whether your device supports Mifare Classic with

PackageManager.hasSystemFeature("com.nxp.mifare");
Martijn Coenen
  • 971
  • 6
  • 8
  • Be aware though that there are still some devices out there where the manufacturers "forgot" to declare that system feature eventhough the device supports MIFARE Classic. – Michael Roland Dec 23 '15 at 14:29