简体   繁体   中英

NFC Tag Reading Activity not receiving intent

I have an activity to read NFC Type A tags (non-NDEF). I am running Android Studio with Android phone in developer mode.

The project launches the application correctly on the developer Android phone with NFC switched on on the phone. When I tap my NFC contactless card on the phone, the phone detects the NFC card but shows an options list of other NFC reader application installed on the phone instead of passing the intent to the foreground application.

How do I get the foreground project's application to receive the NFC intent instead of having a suggestions list popout?

Here's my AndroidManifest.xml file:

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".TapTagActivity">
            <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>
        <activity android:name=".ManageTagActivity"></activity>
        <activity android:name=".EnquireTagActivity"></activity>
        <activity android:name=".SelectTagActionActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".TestActivity" />
    </application>
    <uses-permission android:name="android.permission.NFC" />
    <uses-sdk android:minSdkVersion="10" />
    <uses-feature
        android:name="android.hardware.nfc"
        android:required="true" />
</manifest>

Here's the Activity Java class:

package testtag;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.NfcManager;
import android.nfc.Tag;
import android.os.Bundle;
import android.util.Log;

public class TapTagActivity extends AppCompatActivity {

    private static Class targetActivity = null;
    private NfcAdapter nfcAdapter = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tap_tag);

        System.out.println("Tap Tag window ready ...");

        NfcManager nfcManager = (NfcManager) getSystemService(Context.NFC_SERVICE);
//        nfcAdapter = nfcManager.getDefaultAdapter();
        nfcAdapter = NfcAdapter.getDefaultAdapter(this);

        if (nfcManager != null) {
            System.out.println("NFC Manager ready ...");
        }

        if (nfcAdapter != null) {
            System.out.println("NFC Adapter ready ...");
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent nfcPendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
        if (nfcAdapter != null) {
            nfcAdapter.enableForegroundDispatch(this, nfcPendingIntent, null, null);
        }
    }

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

        if (nfcAdapter != null) {
            try {
                nfcAdapter.disableForegroundDispatch(this);
            } catch (IllegalStateException ex) {
                Log.e("ATHTAG","Error disabling NFC foreground dispatch", ex);
            }
        }
    }

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

        System.out.println("Doing onNewIntent() ...");

        // Use NFC to read tag
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

        if (tag != null) {
            System.out.println("New tag found !!!");
        } else {
            System.out.println("No new tag found !!!");
        }
    }

    public static void setTargetRedirectIntent(Class activity) {
        targetActivity = activity;
    }
}

The console manages to print the:

I/System.out: Tap Tag window ready ...
I/System.out: NFC Manager ready ...
    NFC Adapter ready ...

How do I read the NFC card from the foreground without having the suggestions list with installed NFC reader apps appear?

I figured out that I have to set enableForegroundDispatch() parameters in the onResume() instead of leaving null values.

Working code:

package testtag;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NfcAdapter;
import android.nfc.NfcManager;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.nfc.tech.NfcA;
import android.nfc.tech.NfcB;
import android.os.Bundle;
import android.util.Log;

public class TapTagActivity extends AppCompatActivity {

    private static Class targetActivity = null;
    private NfcAdapter nfcAdapter = null;
    private IntentFilter[] intentFiltersArray = null;
    private String[][] techListsArray = null;
    private PendingIntent pendingIntent = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tap_tag);

        System.out.println("Tap Tag window ready ...");

        NfcManager nfcManager = (NfcManager) getSystemService(Context.NFC_SERVICE);
//        nfcAdapter = nfcManager.getDefaultAdapter();
        nfcAdapter = NfcAdapter.getDefaultAdapter(this);

        if (nfcManager != null) {
            System.out.println("NFC Manager ready ...");
        }

        if (nfcAdapter != null) {
            System.out.println("NFC Adapter ready ...");
        }

        pendingIntent = PendingIntent.getActivity(
                this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        intentFiltersArray = new IntentFilter[]{new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED)};
        techListsArray = new String[][]{new String[]{NfcA.class.getName()}, new String[]{NfcB.class.getName()}, new String[]{IsoDep.class.getName()}};
    }

    @Override
    protected void onResume() {
        super.onResume();
        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent nfcPendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
        if (nfcAdapter != null) {
            nfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray);
        }
    }

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

        if (nfcAdapter != null) {
            try {
                nfcAdapter.disableForegroundDispatch(this);
            } catch (IllegalStateException ex) {
                Log.e("ATHTAG", "Error disabling NFC foreground dispatch", ex);
            }
        }
    }

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

        System.out.println("Doing onNewIntent() ...");

        // Use NFC to read tag
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

        if (tag != null) {
            System.out.println("New tag found !!!");
        } else {
            System.out.println("No new tag found !!!");
        }
    }

    public static void setTargetRedirectIntent(Class activity) {
        targetActivity = activity;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM