Trying to ignore all NFC intents while in foreground with enableForegroundDispatch

偶尔善良 提交于 2019-12-11 04:12:15

问题


I'm trying to get my app to ignore nfc commands while running - its launched by an NFC tag with an Android Application Record (AAR), and I dont want it to be able to be launched by that when its already running.. I've tried to carefully follow others examples, but the app is still able to be launched by AARs while running (in foreground).

Manifest.xml:

<application>
    <activity>
        <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.NDEF_DISCOVERED"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <data android:mimeType="application/com.MyApp.frontcam" />
        </intent-filter>
    </activity>
</application>

Activity.java:

private NfcAdapter mAdapter;
private PendingIntent mPendingIntent;
private IntentFilter[] mFilters;
private String[][] mTechLists;

@Override
public void onCreate(Bundle savedInstanceState) {

    mAdapter = NfcAdapter.getDefaultAdapter(this);
    mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
    IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
    try {
        ndef.addDataType("*/*");  
    }
    catch (MalformedMimeTypeException e) {
        throw new RuntimeException("fail", e);
    }
    mFilters = new IntentFilter[] {ndef, };
    mTechLists = new String[][] {
            new String[] { NfcA.class.getName() },
            new String[] { Ndef.class.getName() },
            new String[] { NdefFormatable.class.getName() }
    }; 

}

@Override 
protected void onResume() {
    super.onResume();
    mAdapter.enableForegroundDispatch(this, mPendingIntent, null, null); //ended up setting mFilters and mTechLists to null
}

回答1:


When you use foregroundDispatch a new intent will be given to your activity when you scan a tag. You should overwrite the onNewIntent method. Add something like this:

MainActivity.java

package com.example.nfctest;

import android.app.PendingIntent;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

private NfcAdapter mAdapter;
private PendingIntent mPendingIntent;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mAdapter = NfcAdapter.getDefaultAdapter(this);
    mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

    doSomethingWithIntent(this.getIntent());        
}   

@Override
public void onResume() {
    super.onResume();
    //Enable forground dispatching to get the tags
    mAdapter.enableForegroundDispatch(this, mPendingIntent, null, null); //ended up setting mFilters and mTechLists to null
}   

@Override
public void onPause() {
    super.onPause();
    //You need to disable forgroundDispatching here
    mAdapter.disableForegroundDispatch(this);
}   

@Override
public void onNewIntent(Intent data) {
    //Catch the intent your foreground dispatch has launched
    doSomethingWithIntent(data);    
}

private void doSomethingWithIntent(Intent data) 
{ 
    //Get the tag from the given intent
    Tag tag = data.getParcelableExtra(NfcAdapter.EXTRA_TAG);
    if(tag != null)
    {
        //Tag is found
        Toast.makeText(this, "Enjoy your tag.", 3).show();      
    }
    else
    {
        //This was an intent without a tag
        Toast.makeText(this, "This was an intent without a tag.", 3).show();    
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}
}

AndroidManifest.xml

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

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />
 <uses-permission android:name="android.permission.NFC" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

You don't need to define the SINGLE_TOP mode in your manifest because you already did this in your mPendingIntent. And i beleave, even when you leave the flagg here to, it still will call the onNewIntent instead of the onCreate.




回答2:


You can achieve this by setting launchmode:

<application>
    <activity android:launchmode="singleTask">
    ...

singleTask: The system creates the activity at the root of a new task and routes the intent to it. However, if an instance of the activity already exists, the system routes the intent to existing instance through a call to its onNewIntent() method, rather than creating a new one.



来源:https://stackoverflow.com/questions/25814376/trying-to-ignore-all-nfc-intents-while-in-foreground-with-enableforegrounddispat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!