【问题标题】:Tag returns null when trying to write NDEF message to NFC tag - Tag is not detected尝试将 NDEF 消息写入 NFC 标签时,标签返回 null - 未检测到标签
【发布时间】:2015-06-02 14:40:17
【问题描述】:

我正在尝试将 NDEF 消息写入标签。以下是我拥有的代码。我在我的 IDE 中使用调试器运行代码,但在执行该行之后

Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

tag 是null(我假设这意味着没有找到标签)并且我无法编写 NDEF 消息。相反,我得到了 NullPointerException。

public class MainActivity extends Activity {
    private BluetoothAdapter mBluetoothAdapter;
    private NfcAdapter mNfcAdapter;
    static final byte[] TYPE_BT_OOB = "application/vnd.bluetooth.ep.oob".
            getBytes(Charset.forName("US_ASCII"));
    private NdefMessage mNdefMessage;
    String mLocalBluetoothAddress;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
        mNdefMessage = createHandoverRequestMessage();
        Intent intent = getIntent();
        //Intent intent = new Intent();

        String action = intent.getAction();
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);// I am getting only Null in tag here//
        try {
            Ndef ndef = Ndef.get(tag);
            ndef.connect();
            try {
                ndef.writeNdefMessage(mNdefMessage);
            } catch (FormatException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            ndef.close();
        } catch (IOException e) {
            Log.e("TagDispatch", e.toString());
        }
    }

这是我的清单文件:

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

    <uses-sdk  android:minSdkVersion="16" />

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" 
        android:debuggable="true" >

        <activity
            android:name="com.example.nfcdemov5.MainActivity"
            android:label="@string/app_name" >

          <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/vnd.bluetooth.ep.oob" />
            </intent-filter>
        </activity>
    </application>
</manifest>

【问题讨论】:

  • 您的标签上有哪些数据(之前)?您是通过点击标签开始活动还是您的活动已经在前台可见?你用enableForegroundDispatch()吗?如果是,请显示相关代码(来自onResume()、onPause()、onNewIntent())。
  • 感谢迈克尔的回复。标签没有任何数据。我唯一的目标是将 NDEF 写入标签。抱歉 - 我是应用程序开发和 NFC 的新手。
  • 好吧,那你现在到底在做什么?您手动启动应用程序(通过单击启动器图标)?或者当您触摸标签时应用程序是否启动?当您触摸标签时,应用程序会执行任何操作吗?同样,这是您活动的所有代码还是还有更多?
  • 除了上面给出的代码之外,我还有用于准备 NDEF 消息的代码 - createHandoverRequestMessage() 用于与蓝牙设备配对。我无法分享代码,因为它太长了。我尝试通过连接启用 NFC 的手机并将其放在我要编写 NDEF 消息的标签上来执行。它什么也没做。所以我尝试使用调试器ON。在 Tag(tag) 语句之后,一旦进入 try 部分,它就会抛出 nullexception 错误。当我检查标签的值时,它显示为空。
  • intent.getaction() 之后的动作是“android.intent.action.MAIN”。我不确定这是否会帮助你给我建议。

标签: android android-intent tags nfc ndef


【解决方案1】:

NFC 事件通过触摸 NFC 标签触发。因此,当您通过单击启动器图标(或通过从您的开发环境启动它)打开您的应用程序时,ANdroid 不会生成 NFC 事件(即使您的设备已经放置在标签的顶部)。

因此,您需要为您的应用注册 NFC 事件。您可以通过清单或在您的应用程序在前台运行时通过前台调度系统执行此操作。看起来您希望能够写入任何标签,无论当前有什么数据,我建议您坚持使用前台调度系统并且不要在 AndroidManifest.xml 中注册任何 NFC 事件。

您将首先使用onResume() 中的enableForegroundDispatch() 方法注册以接收any 标记的事件:

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

此外,您必须在您的活动离开前台之前再次禁用前台调度(因此,在onPause()):

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

最后,您可以处理来自onNewIntent() 方法的标签。因此,您需要将当前处理标记的代码从onCreate()移动到onNewIntent():

public void onNewIntent(Intent intent) {
    if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        if (tag != null) {
            Ndef ndef = Ndef.get(tag);
            if (ndef != null) {
                try {
                    ndef.connect();
                    ndef.writeNdefMessage(createHandoverRequestMessage());
                } catch (Exception e) {
                    Log.e("TagWriting", e.toString());
                } finally {
                    try {
                        ndef.close();
                    } catch (Exception e) {
                    }
                }   
            }
        }
    }
}

您可以通过在单独的线程上执行实际写入来进一步完善这一点,因为不应在 UI 线程上执行阻塞 IO 操作,因为它们可能会导致您的应用冻结。

【讨论】:

  • 我试过上面的代码。我刚刚将“ACTION_TAG_DISCOVERED”更改为 ACTION_NDEF_DISCOVERED,它正在进入“if”循环。但是在写入标签时会抛出 IO exception=> java.io.IOException.
  • 使用上述代码时,您应该得到 TAG_DISCOVERED 而不是 NDEF_DISCOVERED。如果您的手机与标签失去联系(例如,如果标签没有正确放置在手机上或在写入时被移除)或者如果 NDEF 消息太大而无法放入标签,则可能会发生 IOException。
  • 对不起。最初我尝试使用包含一些内容的标签,因此它不是 TAG_DISCOVERED 并引发 IO 异常。现在我尝试使用新标签,意图是 TAG_DISCOVERED 并且还能够编写 NDEF 消息。感谢 Roland 的帮助。现在我需要检查 Tag 中写入的 NDEF 消息是否有效 :)。非常感谢。
  • @abdullahicyc 请不要劫持其他问题。如果您有新问题,请随时在这里提问:stackoverflow.com/questions/ask(另见stackoverflow.com/help/how-to-ask)
猜你喜欢
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-10
  • 1970-01-01
相关资源
最近更新 更多