方法onNewIntent(intent)在NFC中没有执行

14

我正在Android项目中实现NFC功能。我已经在AndroidManifest.xml文件和Java代码中编写了所需的条目。

当任何标签靠近设备时,我的应用程序会检测到该标签,然后打开活动。但是这里我只能获取到NFC标签信息,却无法执行onNewIntent方法。

请大家分享你们的看法。

public class NFCActivity extends Activity {

    private NfcAdapter mNFCAdapter;
    private PendingIntent mNfcPendingIntent;

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

        // Create the OpenSqliteHelper object. It always best to create only
        // once instance of this OpenSqliteHelper
        DatabaseManager.init(this);

        mNFCAdapter = NfcAdapter.getDefaultAdapter(this);

        if (mNFCAdapter == null) {
            // Device does not support NFC
            Toast.makeText(this,
                    getString(R.string.device_does_not_support_nfc),
                    Toast.LENGTH_LONG).show();
        } else {
            if (!mNFCAdapter.isEnabled()) {
                // NFC is disabled
                Toast.makeText(this, getString(R.string.enable_nfc),
                        Toast.LENGTH_LONG).show();
            } else {
                mNfcPendingIntent = PendingIntent.getActivity(NFCActivity.this,
                        0, new Intent(NFCActivity.this, NFCActivity.class)
                                .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
            }
        }
        finish();
    }

    @Override
    protected void onNewIntent(Intent intent) {
        Tag mTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mNFCAdapter.disableForegroundDispatch(this);
    }

    @Override
    public void onResume() {
        super.onResume();
        mNFCAdapter.enableForegroundDispatch(this, mNfcPendingIntent, null,
                null);
    }
}

AndroidManifest.xml

:Android 应用程序的清单文件。
<activity
    android:name="net.livepatrols.thepartnerSA.NFCActivity"
    android:theme="@android:style/Theme.NoDisplay" >
    <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" />

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

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

2
如果问题与onNewIntent有关,尝试添加activity标签android:launchMode="singleInstance"或android:launchMode="singleTop",它会解决问题。 - TheLittleNaruto
这里已经是 singleTop 模式了 .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); - N Sharma
将意图和清单中的singleTop标志都设置为true。参考 - TheLittleNaruto
不起作用。我尝试了你的观点,设置了android:launchMode="singleInstance"或android:launchMode="singleTop"。 - N Sharma
@TheLittleNaruto的解决方案对我有用,但不知道为什么... - Burak Karakuş
@BurakKarakuş http://i.stack.imgur.com/6C8D9.gif - TheLittleNaruto
2个回答

17

当您的活动处于前台时,您的代码可以正常工作,但是当活动被一个带有android.nfc.action.XXX_DISCOVERED操作的Intent启动时,它将无法工作。因为这是第一个意图,onNewIntent()将不会被调用,但您可以在onCreate()方法中使用该意图。您应该从onCreate()onNewIntent()调用NFC逻辑,在访问标签之前验证操作。

public class NFCActivity extends Activity {

    private NfcAdapter mNFCAdapter;
    private PendingIntent mNfcPendingIntent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        performTagOperations(getIntent());
    }

    @Override
    protected void onNewIntent(Intent intent) {
        performTagOperations(intent);
    }

    private void performTagOperations(Intent intent){
        String action = intent.getAction();
        if(action.equals(NfcAdapter.ACTION_TAG_DISCOVERED) ||
        action.equals(NfcAdapter.ACTION_TECH_DISCOVERED) ){
            //PERFORM TAG OPERATIONS
        }
    }
    ...
}

这没有意义。为什么要调用 performTagOperations 两次? - IgorGanapolsky
2
@IgorGanapolsky - 这种方法不会调用performTagOperations两次。这涵盖了两种不同的情况。1)当活动启动时,如果检测到一个标签;2)当活动是前台活动时。请记住,只有当活动可见时,才会调用onNewIntent。 - xilosada

2
在我的情况下,问题在于我盲目地按照nfcAdapter.enableForegroundDispatch(...)的文档说明,并将此代码粘贴到片段中:
pendingIntent = PendingIntent.getActivity(
            this,
            0,
            new Intent(this, getClass())
                .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

由于它实际上需要活动,因此只需将所有内容更改为getContext(),特别是getClass()

pendingIntent = PendingIntent.getActivity(
            getContext(),
            0,
            new Intent(getContext(), getContext().getClass())
                .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

enableForegroundDispatch 需要一个活动作为参数。 - IgorGanapolsky
getContext()代替this真是救了我的一天! - iluxa.b
getContext()不存在 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接