如何使用 NFC 操作 [英] How to use NFC ACTIONS

查看:23
本文介绍了如何使用 NFC 操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试以编程方式注册接收器,以便在检测到 NFC 标签后收到通知.如我的代码所示,我注册了所需的操作,并以编程方式创建了广播接收器.我还在清单文件中添加了所需的权限,但问题是从不调用 onReceive.

I am trying to register a receiver programmatically to get notified once an NFC tag is detected. As shown in my code I registered for the desired action and I created the broadcast receiver programmatically. I also added the required permission in the manifest file but the problem is that onReceive is never called.

请告诉我我做错了什么以及如何解决.

Please let me know what I am doing wrong and how to fix it.

IntentFilter intentFilter1 = new IntentFilter();
intentFilter1.addAction("android.nfc.action.TAG_DISCOVERED");
registerReceiver(mBCR_TAG_DISCOVERED, intentFilter1);

private BroadcastReceiver mBCR_TAG_DISCOVERED = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        mTv.setText("mBCR_TAG_DISCOVERED");
    }
};

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="example.com.myapplication">

<uses-permission android:name="android.permission.NFC" />

<uses-feature
    android:name="android.hardware.nfc"
    android:required="true" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

    </activity>
</application>

</manifest>

推荐答案

Intent android.nfc.action.TAG_DISCOVERED 与所有 NFC Intent 一样,是一个活动 Intent,而不是广播 Intent.根本不可能为它注册广播接收器.您可以做的是注册一个活动来接收 NFC 意图.这可以通过清单、NFC 前台调度系统或通过 NFC 读取器模式 API 在 Android 4.4+ 上完成.

The intent android.nfc.action.TAG_DISCOVERED, just as all NFC intents, is an activity intent and not a broadcast intent. It's simply not possible to register a broadcast receiver for it. What you can instead do is register an activity to receive NFC intents. This can be either done through the manifest, through the NFC foreground dispatch system, or on Android 4.4+ through the NFC reader mode API.

根据您的标签上有哪些数据,您可能想要注册 NDEF_DISCOVERED 意图(如果标签上有 NDEF 结构化数据)或 TECH_DISCOVERED 意图(如果您只想侦听某些标签技术,而不管标签上的数据).您通常不希望注册 TAG_DISCOVERED 意图过滤器,因为当通过 AndroidManifest.xml 使用时,这只是一种回退机制(用于捕获未由任何其他应用处理的事件).

Depending on what data is on your tag you would either want to register for the NDEF_DISCOVERED intent (if there is NDEF structured data on the tag) or for the TECH_DISCOVERED intent (if your just want to listen for certain tag technologies regardless of the data on the tags). You typically do not want to register for the TAG_DISCOVERED intent filter since that is only meant as a fallback mechanism (to catch events not handled by any other app) when used through the AndroidManifest.xml.

例如如果您的标签包含网址 http://www.example.com/,您可以使用以下意图过滤器:

E.g. if your tag contains a URL http://www.example.com/, you could use the following intent filter:

<activity android:name=".MainActivity">
    ...
    <intent-filter>
        <action android:name="android.nfc.action.NDEF_DISCOVERED" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="http" android:host="www.example.com" />
    </intent-filter>
</activity>

如果您的标签不包含任何特定数据并且可能属于任何标签技术,您可以使用以下意图过滤器:

If your tag does not contain any specific data and may be of any tag technology, you could use the following intent filter:

<activity android:name=".MainActivity">
    ...
    <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" />
</activity>

要使这个意图过滤器工作,您还需要在应用程序的 res/ 目录内有一个 XML 资源 xml/nfc_tech_filter.xml.如果技术过滤器只匹配任何标签,则该文件将包含以下内容:

For this intent filter to work, you will aslo need an XML resource xml/nfc_tech_filter.xml inside the res/ directory of your app. If the tech filter should match just any tag, that file would contain this:

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.NfcA</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcB</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcF</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcV</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcBarcode</tech>
    </tech-list>
</resources>

一旦您的 Activity 注册以接收这些事件,您就可以通过 onCreate()(如果您的 Activity 由 NFC 事件启动)或通过 onNewIntent 在您的 Activity 中接收这些意图()(如果您的 Activity 在打开时收到后续 NFC Intent):

Once your activity is registered to receive those events, you can receive these intents within your activity through either onCreate() (if your activity is started by an NFC event) or through onNewIntent() (if your activity receives a subsequent NFC intent while open):

@Override
public void onCreate(Bundle savedInstanceState) {

    [...]

    Intent startIntent = getIntent();
    if ((startIntent != null) &&
        (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(startIntent.getAction()) ||
        NfcAdapter.ACTION_TECH_DISCOVERED.equals(startIntent.getAction()))) {
        // TODO: process intent
    }
}

@Override
protected void onNewIntent(Intent intent) {
    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()) ||
        NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) {
        // TODO: process intent
    }
}

2.前台调度系统

如果您只对接收 NFC 发现意图感兴趣,而您的活动在前台可见,则最好使用 NFC 前台调度系统,而不是通过清单注册接收 NFC 事件.您可以通过在 onResume() 期间注册您的活动来做到这一点:

2. Foreground Dispatch System

If you are only interested in receiving NFC discovery intents while your activity is visible in the foreground, you are better off using the NFC foreground dispatch system instead of registering to receive NFC events through the manifest. You do this by registering your activity during onResume():

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

    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
    NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
    nfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null);
}

您还必须确保在 onPause() 期间取消注册:

You also have to make sure to unregister during onPause():

@Override
public void onPause() {
    super.onPause();
    NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
    nfcAdapter.disableForegroundDispatch(this);
}

然后您将通过 onNewIntent() 将 NFC 事件作为 TAG_DISCOVERED 意图接收:

You will then receive NFC events as TAG_DISCOVERED intents through onNewIntent():

@Override
public void onNewIntent(Intent intent) {
    if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
        // TODO: process intent
    }
}

3.读者模式API

如果您只对检测 NFC 标签感兴趣,并且仅当您的活动在前台可见并且您只需要针对 Android 4.4+ 时,最好的方法可能是使用 NFC 读取器模式 API.您可以通过在 onStart() 期间注册您的活动来实现:

3. Reader Mode API

If you are only interested in detecting NFC tags and only while your activity is visible in the foreground and you only need to target Android 4.4+, the best method is probably to use the NFC reader mode API. You do this by registering your activity during onStart():

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

    NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
    nfcAdapter.enableReaderMode(this, new NfcAdapter.ReaderCallback() {
        @Override
        public void onTagDiscovered(Tag tag) {
            // TODO: use NFC tag
        }
    }, NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_NFC_B | NfcAdapter.FLAG_READER_NFC_F | NfcAdapter.FLAG_READER_NFC_V | NfcAdapter.FLAG_READER_NFC_BARCODE, null);
}

您还应该确保在 onStop() 期间取消注册:

You also should make sure to unregister during onStop():

@Override
public void onStop() {
    super.onStop();
    NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
    nfcAdapter.disableReaderMode(this);
}

您通过 onTagDiscovered(Tag tag) 回调方法接收发现的标签句柄.

You receive discovered tag handles through the onTagDiscovered(Tag tag) callback method.

这篇关于如何使用 NFC 操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆