Ale*_*mer 2 android nfc intentfilter android-intent android-activity
我目前正在为 Android 编写几个支持 NFC 的应用程序,想知道如何阻止我的应用程序出现在从启动器或非 NFC 应用程序扫描标签时打开的“选择应用程序”列表中。我只希望我的应用程序在打开时能够读取标签。
我目前的意图过滤器:
<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" />
Run Code Online (Sandbox Code Playgroud)
nfc_tech_filter.xml:
<tech-list>
<tech>android.nfc.tech.MifareUltralight</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.Ndef</tech>
</tech-list>
Run Code Online (Sandbox Code Playgroud)
您的应用清单中目前有几个与 NFC 相关的 Intent 过滤器:
<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>
Run Code Online (Sandbox Code Playgroud)
通过将此类 Intent 过滤器添加到您的应用程序清单中,您可以指示应在这些 NFC 标签发现事件时启动某些Activity(或者,如果为同一 Intent 注册了多个 Activity,则在 Intent 选择器中显示为选项)。
因此,如果您不希望您的应用可由这些意图启动,则需要从AndroidManifest.xml 中删除这些意图过滤器。
但是,当您的应用程序的活动在前台时,您也将失去监听这些意图的能力。由于 NFC 意图是活动意图,因此您无法通过动态注册的广播接收器接收它们(参见RubbelDieKatz的回答)。相反,Android API 提供了替代方法来捕获 NFC 相关事件,同时您的应用程序的活动显示在前台(这也允许您的应用程序优先于其他应用程序,这对于基于清单的 NFC 意图过滤器是不可能的):
从 API 级别 10(基本上是从 Android NFC 开始),Android 具有前台调度系统。您可以使用NfcAdapter.enableForegroundDispatch()on方法注册您的前台活动以接收 NFC 事件onResume()(不要忘记在您的活动失去焦点时取消注册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);
}
Run Code Online (Sandbox Code Playgroud)
您甚至可以通过向enableForegroundDispatch().
在前台调度系统注册您的活动后,您将通过onNewIntent()回调接收 NFC 事件:
public void onNewIntent(Intent intent) {
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
...
}
Run Code Online (Sandbox Code Playgroud)从 API 级别 19 开始,有新的 NFC 读取器模式 API。您现在可以注册以接收常规回调(而不是通过有时会导致一些问题的意图调度)。您可以使用以下方法执行此操作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);
}
Run Code Online (Sandbox Code Playgroud)
除了(或代替)使用其他标志,NfcAdapter.FLAG_READER_NFC_A您还可以将阅读器模式设置为侦听其他标签技术。
然后您将在标签发现时接收回调(接收者需要实现回调接口NfcAdapter.ReaderCallback):
public void onTagDiscovered(Tag tag) {
...
}
Run Code Online (Sandbox Code Playgroud)另请参阅enableReaderMode 和 enableForegroundDispatch 之间有什么区别?两个选项之间的更详细的比较。
| 归档时间: |
|
| 查看次数: |
1661 次 |
| 最近记录: |