How to make android application listen to specific

2019-09-11 12:35发布

问题:

This question already has an answer here:

  • How to use NFC ACTIONS 5 answers

I'm creating application that do some action if hit NFC chip , I know the following information about NFC in Android please correct me if I am wrong

  1. you can't register actions of the NFC to receiver in the manifest file , only activities .
  2. each NFC chip has it's own unique id .

what I want to do is
while the Application is in the background or it's closed , if I hit NFC chip with id (ex 1234) my app lunched and do some action.

is that possible ? if yes, how it can be achieved?

edit here is my code , it does open when you check any NFC chip and get this action android.nfc.action.TECH_DISCOVERED but when it open the action is android.intent.action.MAIN MainActivity.java

    public class MainActivity extends AppCompatActivity {
    public static final String ACTION_CHECK_IN= "checked";
    public static final String ACTION_CHECK_OUT= "unchecked";
    private NfcAdapter mNfcAdapter;
    boolean isCheckedIn = false;

    private static final String TAG = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
        isCheckedIn = Pref.getBoolean("check", false);
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume() called with: " + "");
        String action = getIntent().getAction();
        if (action != null) {
            Log.d("MainActivity", "onCreate(" + action + ")");
            if (action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED) || action.equals(NfcAdapter.ACTION_TAG_DISCOVERED) || action.equals(NfcAdapter.ACTION_TECH_DISCOVERED)) {

                if (!isCheckedIn) {
                    isCheckedIn = true;
                    Pref.putBoolean("check", true);
                    Log.d("checking","IN");
                } else {
                    isCheckedIn = false;
                    Pref.putBoolean("check", false);
                    Log.d("checking","Out");
                }

            }

        }

        if (!mNfcAdapter.isEnabled()) {

            Toast.makeText(MainActivity.this, "Please open it ", Toast.LENGTH_SHORT).show();
        }


        /**
         * It's important, that the activity is in the foreground.
         * Otherwise an IllegalStateException is thrown.
         */
        setupForegroundDispatch(this, mNfcAdapter);
    }

    @Override
    protected void onPause() {
        /**
         * Call this before onPause, otherwise an IllegalArgumentException is thrown.
         */
        stopForegroundDispatch(this, mNfcAdapter);

        super.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }


    public static void setupForegroundDispatch(Activity activity, NfcAdapter adapter) {
        final Intent intent = new Intent(activity.getApplicationContext(), activity.getClass());
        intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

        final PendingIntent pendingIntent = PendingIntent.getActivity(
                activity.getApplicationContext(), 0, intent, 0);

        IntentFilter[] filters = new IntentFilter[2];
        String[][] techList = new String[][]{};

        // same filter as manifest - action, category
        filters[0] = new IntentFilter();
        filters[0].addAction(NfcAdapter.ACTION_TAG_DISCOVERED);
        filters[1] = new IntentFilter();
        filters[1].addAction(NfcAdapter.ACTION_TECH_DISCOVERED);

        adapter.enableForegroundDispatch(activity, pendingIntent, filters, techList);
    }

    public static void stopForegroundDispatch(Activity activity, NfcAdapter adapter) {
        adapter.disableForegroundDispatch(activity);
    }
}

manifest

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

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

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

    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">


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

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

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

        </activity>

    </application>

</manifest>

回答1:

According the the Android Developer site, it is possible for your app to filter NFC intents such as ACTION_NDEF_DISCOVERED.



回答2:

First register your app in the manifest

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.survivingwithandroid.nfc" >

....
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain"/>
</intent-filter>
<manifest>

Then you should use foreground dispatch (foreground app). Finally you use NFCAdapter to read the content (onNewIntent). I wrote a detailed posts about NFC if you like give a look.