本文介绍了从“选择应用程序"中隐藏NFC应用程序;列表/通过外部NFC意图禁用启动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在为Android编写几个启用NFC的应用程序,想知道如何阻止我从启动器或非NFC扫描标签时打开的选择应用程序"列表中的应用程序应用程序.我只希望我的应用在打开时能够读取标签.

I'm currently writing a couple of NFC enabled apps for Android and wanted to know how I can stop my application from being in the "choose application" list that's opened whenever a tag is scanned from the launcher or a non-NFC app. I only want my apps to be able to read the tags when they are open.

我当前的意图过滤器:

<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="text/plain" />
</intent-filter>
<intent-filter>
    <action android:name="android.nfc.action.TECH_DISCOVERED"/>
    <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc_tech_filter" />

nfc_tech_filter.xml:

nfc_tech_filter.xml:

<tech-list>
    <tech>android.nfc.tech.MifareUltralight</tech>
</tech-list>
<tech-list>
    <tech>android.nfc.tech.Ndef</tech>
</tech-list>

推荐答案

您当前在应用的清单中有几个与NFC相关的意图过滤器:

You currently have a couple of NFC related intent filters in your app's manifest:

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
    <action android:name="android.nfc.action.TECH_DISCOVERED"/>
    <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>

通过将此类意图过滤器添加到应用程序的清单中,表明您应在以下时间启动(或如果为同一意图注册了多个活动,则在意图选择器中作为选项显示).这些NFC标签发现事件.

By adding such intent filters to the manifest of your app, you indicate that certain activities should be started (or presented as options in the intent chooser if multiple activities are registered for the same intents) upon these NFC tag discovery events.

因此,如果您不希望这些意图可启动您的应用,则需要从 AndroidManifest.xml 删除这些意图过滤器.

Consequently, you need to remove those intent filters from the AndroidManifest.xml if you don't want your app to be launchable by those intents.

但是,当应用程序的活动处于前台时,您也将失去听这些意图的能力.由于NFC意图是活动意图,因此您无法通过动态注册的广播接收器接收它们(请参见 RubbelDieKatz 的回答) .取而代之的是,Android API提供了另一种方式来捕获您的应用程序的活动在前台显示时捕获NFC相关事件(这也使您的应用程序可以优先于其他应用程序,而基于清单的NFC意图过滤器则无法实现):

However, you would then also lose the ability to listen for those intents while an activity of your app is in the foreground. Since NFC intents are activity intents, you can't receive them through dynamically registered broadcast receivers (cf. RubbelDieKatz's answer). Instead, the Android API provides alternative means to catch NFC related events while an activity of your app is displayed in the foreground (this also allows your app to get precedence over other apps, which is not possible with manifest-based NFC intent filters):

  1. 自API级别10(基本上自Android NFC诞生以来)开始,Android就采用了前台调度系统.您可以在onResume()上使用NfcAdapter.enableForegroundDispatch()方法注册前台活动以接收NFC事件(当您的活动失去对onPause()的关注时,请不要忘记注销):

  1. Since API level 10 (basically since the beginning of Android NFC), Android features the foreground dispatch system. You can register your foreground activity to receive NFC events by using the method NfcAdapter.enableForegroundDispatch() upon onResume() (don't forget to unregister when your activity loses focus in onPause()):

public void onResume() {
    super.onResume();
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
    NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
    adapter.enableForegroundDispatch(this, pendingIntent, null, null);
}

public void onPause() {
    super.onPause();
    NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
    adapter.disableForegroundDispatch(this);
}

您甚至可以通过向enableForegroundDispatch()提供可选的tech-list和intent-filters参数来注册以仅接收特定的NFC发现事件子集.

You could even register to receive only a specific subset of NFC discovery events by providing the optional tech-list and intent-filters arguments to enableForegroundDispatch().

在前台调度系统中注册活动后,您将通过onNewIntent()回调接收NFC事件:

Once you registered your activity with the foreground dispatch system, you will receive NFC events through the onNewIntent() callback:

public void onNewIntent(Intent intent) {
    Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

    ...
}

  • 从API级别19开始,提供了新的NFC读取器模式API.现在,您可以注册以接收常规回调(而不是通过意向分派(有时会导致速成组)进行).您可以使用NfcAdpater.enableReaderMode()方法来实现:

  • Starting with API level 19, there is the new NFC reader mode API. You can now register to receive regular callbacks (instead of going through the intent dispatch which sometimes causes soome hickups). You can do this by using the method NfcAdpater.enableReaderMode():

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        ...
    
        NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
        adapter.enableReaderMode(this, this, NfcAdapter.FLAG_READER_NFC_A, null);
    }
    

    除了(或代替NfcAdapter.FLAG_READER_NFC_A)使用其他标志之外,您还可以设置为读取器模式来监听其他标签技术.

    By using other flags in addition to (or instead of) NfcAdapter.FLAG_READER_NFC_A you could set to reader mode to listen for other tag technologies as well.

    然后您将在发现标签后接收回调(接收者需要实现回调接口NfcAdapter.ReaderCallback):

    You will then receive callbacks upon tag discovery (the receiver needs to implement the callback interface NfcAdapter.ReaderCallback):

    public void onTagDiscovered(Tag tag) {
        ...
    }
    

  • 另请参阅 enableReaderMode和enableForegroundDispatch之间有什么区别?,以获得这两个选项之间的详细比较.

    Also see What's the difference between enableReaderMode and enableForegroundDispatch? for a more detailed comparison between the two options.

    这篇关于从“选择应用程序"中隐藏NFC应用程序;列表/通过外部NFC意图禁用启动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    08-05 06:06