简体   繁体   中英

not getting to onNewIntent after tapping to another NFC enabled device.(android)

The main problem is that we are unable to go to onNewIntent() when i tap my phone with other NFC enabled phone(NFC is ON). Under no circumstances other than the main intent, i am unable to reach onNewIntent. I have tried all the three filters NDEF,TECH, TAG.

package com.example.nfctry;

import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Bundle;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.view.Menu;
import android.widget.Toast;

public class MainActivity extends Activity {
NfcAdapter adapter;
PendingIntent pendingIntent;
IntentFilter writeTagFilters[];
boolean writeMode;
Tag myTag;
Context ctx;



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

    ctx = this;

    adapter = NfcAdapter.getDefaultAdapter(this);
    pendingIntent = PendingIntent.getActivity(this,0,new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0);
    IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
    tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
    writeTagFilters = new IntentFilter[] {tagDetected};

    onNewIntent(getIntent());



}

@Override
protected void onNewIntent(Intent intent)
{
    Toast.makeText(this,""+intent.getAction(), Toast.LENGTH_LONG).show();
    super.onNewIntent(intent);
    // getIntent() should always return the most recent
    if(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()))
    {
        myTag= intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        Toast.makeText(this,"DETECTED muahhhhh"  + myTag.toString(), Toast.LENGTH_LONG).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;
}

}

and in android mainfest i have added the intentfilters as well.

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

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

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.example.nfctry.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
        <action android:name="android.nfc.action.NDEF_DISCOVERED" />

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

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

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

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

It's indepent off which TAG filter you use. Your onNewIntent only get's called when an intent is called using the launchMode : singleTop or singleTask and ofcourse when you call it yourself. When your application is in the front it doesn't catch the NDEF/TECH/TAG discovery. You need to use ForegroundDispatching to catch the tag discovery events in your current app.

When your ForegroundDispatch catch the event and you use PendingIntent.getActivity with the flag FLAG_ACTIVITY_SINGLE_TOP in your PendingIntent it will call onNewIntent .

You should enable the ForegroundDispatch in onResume :

@Override
public void onResume()
{
    super.onResume();

    PendingIntent pendingIntent     = PendingIntent.getActivity(this,0,new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0);     
    IntentFilter[] intentFilters    = { new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED) };      

    adapter.enableForegroundDispatch(   this,
            pendingIntent, 
            intentFilters,
            new String[][]{
            new String[]{"android.nfc.tech.NfcA"}
        });     
}

And disable it in onPause :

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

    if (adapter != null) 
    {
        try {
            adapter.disableForegroundDispatch(this);
        } 
        catch (NullPointerException e) {
        }
    }
}  

To catch the TAG event in your current code with ForegroundDispatch it will be something like this:

public class MainActivity extends Activity {

    NfcAdapter adapter;
    PendingIntent pendingIntent;
    IntentFilter writeTagFilters[];
    boolean writeMode;
    Tag myTag;
    Context ctx;    

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

        ctx = this;
        adapter = NfcAdapter.getDefaultAdapter(this);
        onNewIntent(this.getIntent());      
    }


    @Override
    public void onNewIntent(Intent data) 
    {
        Toast.makeText(this,""+intent.getAction(), Toast.LENGTH_LONG).show();
        super.onNewIntent(intent);
        // getIntent() should always return the most recent
        if(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()))
        {
            myTag= intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
            Toast.makeText(this,"DETECTED muahhhhh"  + myTag.toString(), Toast.LENGTH_LONG).show();

        }
    }   

    @Override
    public void onResume()
    {
        super.onResume();

        PendingIntent pendingIntent     = PendingIntent.getActivity(this,0,new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0);     
        IntentFilter[] intentFilters    = { new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED) };      

        adapter.enableForegroundDispatch(   this,
                pendingIntent, 
                intentFilters,
                new String[][]{
                new String[]{"android.nfc.tech.NfcA"}
            });     
    }

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

        if (adapter != null) 
        {
            try {
                adapter.disableForegroundDispatch(this);
            } 
            catch (NullPointerException e) {
            }
        }
    }    

    @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;
    }
}

Also note that you should add the NFC user permissions in your manifest.

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