I have just migrated from Android 8 to 10, and my NFC test app now starts throwing an NPE whenever reading a Mifare tag. Other tags seem to work (specifically one supporting NfcV, NdefFormatable).
Stack trace:
E/AndroidRuntime( 1277): java.lang.NullPointerException: Attempt to invoke virtual method 'short android.os.Bundle.getShort(java.lang.String)' on a null object reference
E/AndroidRuntime( 1277): at android.nfc.tech.NfcA.<init>(NfcA.java:76)
E/AndroidRuntime( 1277): at android.nfc.tech.NfcA.get(NfcA.java:62)
E/AndroidRuntime( 1277): at android.nfc.tech.MifareClassic.<init>(MifareClassic.java:150)
E/AndroidRuntime( 1277): at android.nfc.tech.MifareClassic.get(MifareClassic.java:140)
E/AndroidRuntime( 1277): at myapp.nfc_reader.TagViewer.dumpTagData(TagViewer.java:201)
Upon receiving an NFC intent, the app does this:
Parcelable p = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Tag tag = (Tag) p;
for (String tech : tag.getTechList()) {
if (tech.equals(MifareClassic.class.getName())) {
MifareClassic mifareTag = MifareClassic.get(tag);
// more code here
}
}
Apparently Tag
has a non-public Bundle
member, which is null on Android 10 and causes the NPE. This has worked on Android 8 (LineageOS 15.1) but fails on Android 10 (LineageOS 17.1; the device is a OnePlus One).
Is that a bug in the OS or am I doing something wrong?
Looks like an OS Bug
This change looks suspect https://review.lineageos.org/c/LineageOS/android_frameworks_base/+/256596/5/core/java/android/nfc/tech/NfcA.java
First introduced in lineage-17.0 (Android 10 release)
why the code below has the useless if
statement I've no idea that does nothing useful because mSak
and mAtqa
are reset using the stock Android code straight after the useless if
and line 76 is in the useless if
public NfcA(Tag tag) throws RemoteException {
super(tag, TagTechnology.NFC_A);
Bundle extras;
mSak = 0;
if(tag.hasTech(TagTechnology.MIFARE_CLASSIC))
{
extras = tag.getTechExtras(TagTechnology.MIFARE_CLASSIC);
mSak = extras.getShort(EXTRA_SAK);
}
extras = tag.getTechExtras(TagTechnology.NFC_A);
mSak |= extras.getShort(EXTRA_SAK);
mAtqa = extras.getByteArray(EXTRA_ATQA);
}
this is not what is in stock Android https://android.googlesource.com/platform/frameworks/base/+/refs/heads/android10-release/core/java/android/nfc/tech/NfcA.java
[Following edited by another user] This is fixed with this patch. https://review.lineageos.org/c/LineageOS/android_packages_apps_Nfc/+/306229