【问题标题】:not getting to onNewIntent after tapping to another NFC enabled device.(android)在点击另一个支持 NFC 的设备后没有进入 onNewIntent。(android)
【发布时间】:2014-08-22 10:34:08
【问题描述】:

主要问题是当我用其他支持 NFC 的手机(NFC 已打开)点击我的手机时,我们无法进入 onNewIntent()。 除了主要意图之外,在任何情况下,我都无法达到 onNewIntent。 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;
}

}

在 android mainfest 中,我也添加了意图过滤器。

 <?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>

【问题讨论】:

  • 查看这里sample
  • 嗨,Michael,您的代码正在运行,但我的 NFC 卡使用 NFCA 技术,因此 toast 显示“不支持卡类型”。我该怎么做才能添加这种类型?

标签: java android android-intent nfc onnewintent


【解决方案1】:

这与您使用的 TAG 过滤器无关。您的onNewIntent 仅在使用launchMode 调用intent 时才被调用:singleTopsingleTask 当然当您自己调用它时。当您的应用程序位于前面时,它不会捕获 NDEF/TECH/TAG 发现。您需要使用ForegroundDispatching 来捕获当前应用中的标签发现事件。

当您的ForegroundDispatch 捕获事件并在您的PendingIntent 中使用带有FLAG_ACTIVITY_SINGLE_TOP 标志的PendingIntent.getActivity 时,它将调用onNewIntent

您应该在onResume 中启用ForegroundDispatch

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

并在onPause 中禁用它:

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

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

要使用ForegroundDispatch 在您当前的代码中捕获 TAG 事件,它将是这样的:

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

另请注意,您应该在清单中添加 NFC 用户权限。

【讨论】:

  • 谢谢,我得到了错误。但现在每当我试图获取 ID 时,每次我得到不同的 ID。 NdefMessage[] msgs = getTechMessages(getIntent()); NdefRecord 记录 = msgs[0].getRecords()[0]; byte[] 有效载荷 = record.getId();
  • payload 给出“null”,而 getID() 给出一些排序为“[B@426fd2a0”的随机值。我们的 nfc 标签中没有数据,主要目的只是获取一个唯一的 ID。
  • [B@426fd2a0 不是真正的 ASCII 输出。您应该使用new String(payload) 打印它。
  • 您不应该同时获取 NDEF 记录的 ID,因为它不会返回设备的 ID。你应该使用myTag.getId()。如果您在另一边使用 HCE,请注意 UID 每笔交易都不同。它是每笔交易随机生成的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-04
  • 1970-01-01
  • 2016-03-28
  • 2011-11-06
  • 1970-01-01
  • 2020-06-21
相关资源
最近更新 更多