【问题标题】:Trying to ignore all NFC intents while in foreground with enableForegroundDispatch尝试在前台使用 enableForegroundDispatch 忽略所有 NFC 意图
【发布时间】:2014-09-12 18:15:47
【问题描述】:

我试图让我的应用程序在运行时忽略 nfc 命令 - 它由带有 Android 应用程序记录 (AAR) 的 NFC 标签启动,我不希望它能够在它已经运行时启动.. 我已尝试仔细关注其他人examples,但该应用程序仍然可以在运行时由 AAR 启动(在前台)。

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
}

【问题讨论】:

    标签: android nfc android-applicationrecord


    【解决方案1】:

    您可以通过设置启动模式来实现:

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

    singleTask:系统在新任务的根部创建活动并将意图路由到它。但是,如果 Activity 的实例已经存在,系统会通过调用其 onNewIntent() 方法将 Intent 路由到现有实例,而不是创建一个新实例。

    【讨论】:

    • 尝试将其添加到 Manifest.xml 但保留了我的 activity.java 文件,但它仍然无法正常工作。我的 activity.java 编码有问题吗?
    • 这适用于在内部使用 NFC 的 react-native 应用程序。
    【解决方案2】:

    当您使用foregroundDispatch 时,您会在扫描标签时为您的活动提供新的意图。您应该覆盖onNewIntent 方法。添加如下内容:

    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>
    

    您无需在清单中定义 SINGLE_TOP 模式,因为您已经在 mPendingIntent 中执行了此操作。而且我相信,即使您将标记留在这里,它仍然会调用onNewIntent 而不是onCreate

    【讨论】:

    • 还没有。我想我不需要指定过滤器或技术列表,因为我想忽略所有 nfc 意图?
    • 对不起,应该是早了。让我给你一个新的答案!
    • 有趣的代码片段!奇怪的是,该应用程序告诉我“这是一个没有标签的意图。”,即使我重新启动带有标签的程序也是如此。我试过用 ACTION_TAG_DISCOVERED 和 ACTION_NDEF_DISCOVERED 分配标签,也没有运气..
    • 它与您在清单中使用的意图过滤器无关,因为该标签将被前景调度系统捕获,该系统被定义为通配符(捕获所有标签)。我用一些代码更新了我的答案。如果你把它放在你的 MainActivity 中,这应该可以工作。希望对您有所帮助!
    • 太棒了!现在检测到标签,但仍会重新启动应用程序(仅使用“享受您的标签。”)写入。我怎样才能让它完全忽略意图?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-07
    • 1970-01-01
    相关资源
    最近更新 更多