0

I am trying to read smartcards via NFC on Android. I had a solution working in Eclipse, but after migrating to Android Studio it only works once, reads all the data from the card, but then freezes and repeats this error over and over:

Attempt to invoke virtual method 'boolean android.nfc.Tag.hasTech(int)' on a null object reference

W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.nfc.Tag.hasTech(int)' on a null object reference

W/System.err: at android.nfc.tech.IsoDep.get(IsoDep.java:61)

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="packageName"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="17"
        android:targetSdkVersion="23" />

    <uses-permission android:name="android.permission.NFC" />

    <uses-feature
        android:name="android.hardware.nfc"
        android:required="false" />

    <application
        android:allowBackup="true"
        android:label="@string/app_name"
        android:supportsRtl="true" >

        <activity
            android:name=".NFCReader"
            android:label="@string/app_name"
            android:launchmode="singleTask" >

            <intent-filter>
                <action android:name="android.nfc.action.TECH_DISCOVERED" />
            </intent-filter>

            <meta-data
                android:name="android.nfc.action.TECH_DISCOVERED"
                android:resource="@xml/nfc_tech_filter" />
        </activity>
    </application>

</manifest>

NFCReader:

public class NFCReader extends Activity {

private NfcAdapter mNfcAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mNfcAdapter = NfcAdapter.getDefaultAdapter(this);

    if (mNfcAdapter == null) {
        finish();
        return;
    }

    if (!mNfcAdapter.isEnabled()) {
        Log.e(TAG, "NFC is disabled.");
    } else {
    }

    final Tag tagFromIntent = this.getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
    new ReadCardTask().execute(tagFromIntent);

    handleIntent(getIntent());
    this.finish();
}

private void handleIntent(Intent intent) {
    String action = intent.getAction();

    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
        String type = intent.getType();
        if (MIME_TEXT_PLAIN.equals(type)) {
            Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
            new NdefReaderTask().execute(tag);
        } else {
            Log.d(TAG, "Wrong mime type: " + type);
        }
    } else if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        String[] techList = tag.getTechList();
        String searchedTech = Ndef.class.getName();

        for (String tech : techList) {
            if (searchedTech.equals(tech)) {
                new NdefReaderTask().execute(tag);
                break;
            }
        }
    }
}

protected Void doInBackground(Tag... params) {
    IsoDep tag = IsoDep.get(params[0]);
    tag.connect();
    // [...] transmit APDUs
}

}
Community
  • 1
  • 1
IAmCoder
  • 3,179
  • 2
  • 27
  • 49

1 Answers1

0

For some reason the doInBackground() function is being called twice, once with the tag, where the read works, but then again with null in the tag which causes the error. A null check on the tag parameter fixed it:

protected Void doInBackground(Tag... params) {
    if (params[0] == null)
    {
        return null;
    }

    IsoDep tag = IsoDep.get(params[0]);
    tag.connect();
    // [...] transmit APDUs
}
IAmCoder
  • 3,179
  • 2
  • 27
  • 49