尝试将 NDEF 消息写入 NFC 标签时标签 returns 为空 - 未检测到标签
Tag returns null when trying to write NDEF message to NFC tag - Tag is not detected
我正在尝试将 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>
NFC 事件通过触摸 NFC 标签触发。因此,当您通过单击启动器图标(或从您的开发环境启动它)打开您的应用程序时,ANdroid 不会生成 NFC 事件(即使您的设备已经放在标签上) .
因此,您需要做的是为您的应用程序注册 NFC 事件。您可以通过清单或当您的应用程序在前台 运行 时通过前台调度系统执行此操作。由于您似乎希望能够写入任何标签,而不管标签上当前有什么数据,我建议您坚持使用前台调度系统并且不要在 [=35= 中注册任何 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);
}
此外,在 activity 离开前台之前,您必须再次禁用前台调度(因此,在 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) {
}
}
}
}
}
}
您可以通过在单独的线程上执行实际写入来进一步完善这一点,因为阻塞 IO 操作不应在 UI 线程上执行,因为它们可能会导致您的应用程序冻结。
我正在尝试将 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>
NFC 事件通过触摸 NFC 标签触发。因此,当您通过单击启动器图标(或从您的开发环境启动它)打开您的应用程序时,ANdroid 不会生成 NFC 事件(即使您的设备已经放在标签上) .
因此,您需要做的是为您的应用程序注册 NFC 事件。您可以通过清单或当您的应用程序在前台 运行 时通过前台调度系统执行此操作。由于您似乎希望能够写入任何标签,而不管标签上当前有什么数据,我建议您坚持使用前台调度系统并且不要在 [=35= 中注册任何 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);
}
此外,在 activity 离开前台之前,您必须再次禁用前台调度(因此,在 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) {
}
}
}
}
}
}
您可以通过在单独的线程上执行实际写入来进一步完善这一点,因为阻塞 IO 操作不应在 UI 线程上执行,因为它们可能会导致您的应用程序冻结。