没有为NFC意图显示正确的操作

时间:2014-05-28 08:46:39

标签: android android-intent nfc intentfilter

我正在处理Android NFC设备,只是尝试读取标签并从活动中接收信息。标签属于MifareUltralight类型。只需在Android docs中阅读该案例,我首先必须注册Intent以在清单文件中启动我的Activity,然后我将能够从中接收NFC Intent。这就是我的清单文件的样子:

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

    <uses-feature android:name="android.hardware.nfc" android:required="false" />
    <uses-permission android:name="android.permission.NFC" />

    <application
        android:allowBackup="true"
        android:label="Test">

        <activity
            android:name="com.mycompany.android.activities.NfcTestActivity"
            android:launchMode="singleTop"
            android:label="Test">
            <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"/>
            </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"/>
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>

我将nfc功能设置为不需要,因为这对我的应用程序不起作用。关于NFC技术过滤器,这是我的nfc_tech_filter.xml文件:

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

嗯,配置完成后,似乎我的NfcTestActivity应该能够接收NFC意图。这就是我实现它的方式:

public class NfcTestActivity  extends Activity {

    final String TAG = NfcTestActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "IntentAction (onCreate): " + getIntent().getAction());
        NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE);
        NfcAdapter adapter = manager.getDefaultAdapter();
        if (adapter != null && adapter.isEnabled()) {
            Log.i(TAG, "NFC adapter is enabled");
        } else {
            Log.i(TAG, "NFC adapter is disabled");
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.i(TAG, "IntentAction (onNewIntent): " + getIntent().getAction());
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.i(TAG, "IntentAction (onResume): " + getIntent().getAction());
    }

}

当我启动应用程序时,我得到以下日志:

05-28 10:41:52.044  31182-31182/com.mycompany.android I/NfcTestActivity? IntentAction (onCreate): android.intent.action.MAIN
05-28 10:41:52.054  31182-31182/com.mycompany.android I/NfcTestActivity? NFC adapter is enabled
05-28 10:41:52.054  31182-31182/com.mycompany.android I/NfcTestActivity? IntentAction (onResume): android.intent.action.MAIN

稍后,我读了我的标签,显示了这个日志:

05-28 10:41:59.661  31182-31182/com.mycompany.android I/NfcTestActivity? IntentAction (onResume): android.intent.action.MAIN

这意味着在读取标记时会调用Activity#onResume方法,正如文档所述,但是,我在这里得到的是android.intent.action.MAIN而不是NFC ACTION_NDEF_DISCOVEREDACTION_TECH_DISCOVEREDACTION_TAG_DISCOVERED)。

此外,作为线索,当我从我的活动声明中删除此代码片段时,我在阅读标记时没有显示onResume日志:

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

所以似乎TAG_DISCOVERED动作是以某种方式定义的,而不是其他动作,但是我无法从活动中正确地捕捉它。

有人知道吗?

2 个答案:

答案 0 :(得分:2)

经过一番头脑风暴,我意识到默认android.nfc.action.TAG_DISCOVERED代替android.nfc.action.NDEF_DISCOVERED为我做了工作:

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

当我的标签类型被TAG_DISCOVERED覆盖时,我仍然不知道为什么我应该使用TECH_DISCOVERED,这是最好使用的。无论如何,这是我后来用来获取标签ID的代码:

@Override
public void onResume() {
    super.onResume();
    Log.d(TAG, "onResume: action-"+getIntent().getAction());
    if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(getIntent().getAction())) {
        Tag tag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
        String tagId = bytesToHexString(tag.getId());
        Log.i(TAG, "NFC tag: " + tagId);
    }
}

另见:

答案 1 :(得分:1)

首先,您的nfc_tech_filter.xml不正确。过滤器

<tech-list>
    <tech>android.nfc.tech.IsoDep</tech>
    <tech>android.nfc.tech.NfcA</tech>
    <tech>android.nfc.tech.NfcB</tech>
    <tech>android.nfc.tech.NfcF</tech>
    <tech>android.nfc.tech.NfcV</tech>
    <tech>android.nfc.tech.Ndef</tech>
    <tech>android.nfc.tech.NdefFormatable</tech>
    <tech>android.nfc.tech.MifareClassic</tech>
    <tech>android.nfc.tech.MifareUltralight</tech>
</tech-list>

表示您要匹配IsoDep NfcA NfcB NfcF ...但是,NfcX标记技术相互排斥(NdefNdefFormatable),所以过滤器不匹配任何标签。你真正想要的是这样的:

<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>

哪个匹配任何标记技术。或者,如果您只想匹配MifareUltralight,则可以使用:

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

使用TAG_DISCOVERED意图过滤器通常不是一个好主意。它仅仅意味着后备以及与第一个Android NFC API的向后兼容性。

当您希望在应用处于前台时接收NFC意图时,通常最好注册foreground dispatch system,而不是依赖应用程序清单中的意图过滤器。这将确保您的活动收到活动,并且即使其他应用也有针对这些活动的意图过滤器,也不会显示活动选择器。