一次触摸从标签读取 NDEF 消息两次(不移动 phone)
Read NDEF message from tag two times with one single touch (without moving phone)
我通过读取来自 NFC 标签的 NDEF 消息成功地获得了一切。在我读完之后,我移动 phone 它可以再次读取标签。
我正在使用 onNewIntent 和 foregroundDispatch 来处理消息。
问题是:
我想读取同一个 NFC 标签两次(出于安全原因)而不移动 phone(无需再次触摸标签)。所以为了一次触摸,我想读两遍。
我尝试查看生命周期,但似乎如果您不移动 phone,它不会再次发出新的 Intent。
private NfcAdapter nfc = null;
private boolean inReadMode = false;
private boolean isNFC_support = false;
private PendingIntent mPendingIntent;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ignore the unrelevent part of layout
isNFC_support = true;
nfc = NfcAdapter.getDefaultAdapter(this);
if(nfc == null) {
Toast.makeText(this, "Not support NFC device.", Toast.LENGTH_LONG).show();
isNFC_support = false;
}
if(!nfc.isEnabled()) {
Toast.makeText(this, "Please go the setting and enable NFC first.", Toast.LENGTH_LONG).show();
isNFC_support = false;
}
if (isNFC_support == true) {
mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
}
}
@Override
protected void onNewIntent(Intent intent) {
Log.i("NFC", "---- onNewIntent called ---- ");
if (this.inReadMode && NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
Log.i("NFC", "---- onNewIntent called ---- AND read nfc success!");
try {
readFromTag(intent);
} catch (Exception e) {
Log.e("NFC", "nfc cmac validate: ", e);
}
}
}
@Override
public void onResume() {
super.onResume();
Log.i("NFC", "---- onResume called ---- ");
nfc.enableForegroundDispatch(this, mPendingIntent, null, null);
}
@Override
public void onPause() {
Log.i("NFC", "---- onPause called ---- ");
if (nfc != null) {
nfc.disableForegroundDispatch(this);
}
if (isFinishing()) {
cleanupReadingFromTag();
}
super.onPause();
}
private void readFromTag(Intent intent) throws RuntimeException, NoSuchAlgorithmException, IOException {
Parcelable[] msgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
// code I handle the message as I get. Not important for read twice I think?
}
那么我怎样才能再次读取标签呢?
NFC 意图仅在 检测到 NFC 标签时调度。如果标签包含 NDEF 消息,该消息会自动处理并在 intent extra (NfcAdapter.EXTRA_NDEF_MESSAGES
) 中与您的应用共享。
如果您想在稍后阶段再次读取标签(并设法保持 NFC 标签持续连接),您将需要直接与标签通信。您可以通过标记句柄对象来完成此操作。此对象 (class Tag
) 也会在检测到标签时传递给您的应用(作为 NFC 意图的附加意图):
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
连接标签后,您可以随时使用该对象启动与标签的通信。例如。要重新阅读标签上的当前 NDEF 消息,您可以使用:
Ndef ndef = Ndef.get(tag);
if (ndef != null) {
try {
ndef.connect();
NdefMessage msg = ndef.getNdefMessage();
// do something with the NDEF message
} catch (IOException e) {
} finally {
try {
ndef.close();
} catch (Exception e) {}
}
}
我通过读取来自 NFC 标签的 NDEF 消息成功地获得了一切。在我读完之后,我移动 phone 它可以再次读取标签。
我正在使用 onNewIntent 和 foregroundDispatch 来处理消息。
问题是: 我想读取同一个 NFC 标签两次(出于安全原因)而不移动 phone(无需再次触摸标签)。所以为了一次触摸,我想读两遍。
我尝试查看生命周期,但似乎如果您不移动 phone,它不会再次发出新的 Intent。
private NfcAdapter nfc = null;
private boolean inReadMode = false;
private boolean isNFC_support = false;
private PendingIntent mPendingIntent;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ignore the unrelevent part of layout
isNFC_support = true;
nfc = NfcAdapter.getDefaultAdapter(this);
if(nfc == null) {
Toast.makeText(this, "Not support NFC device.", Toast.LENGTH_LONG).show();
isNFC_support = false;
}
if(!nfc.isEnabled()) {
Toast.makeText(this, "Please go the setting and enable NFC first.", Toast.LENGTH_LONG).show();
isNFC_support = false;
}
if (isNFC_support == true) {
mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
}
}
@Override
protected void onNewIntent(Intent intent) {
Log.i("NFC", "---- onNewIntent called ---- ");
if (this.inReadMode && NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
Log.i("NFC", "---- onNewIntent called ---- AND read nfc success!");
try {
readFromTag(intent);
} catch (Exception e) {
Log.e("NFC", "nfc cmac validate: ", e);
}
}
}
@Override
public void onResume() {
super.onResume();
Log.i("NFC", "---- onResume called ---- ");
nfc.enableForegroundDispatch(this, mPendingIntent, null, null);
}
@Override
public void onPause() {
Log.i("NFC", "---- onPause called ---- ");
if (nfc != null) {
nfc.disableForegroundDispatch(this);
}
if (isFinishing()) {
cleanupReadingFromTag();
}
super.onPause();
}
private void readFromTag(Intent intent) throws RuntimeException, NoSuchAlgorithmException, IOException {
Parcelable[] msgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
// code I handle the message as I get. Not important for read twice I think?
}
那么我怎样才能再次读取标签呢?
NFC 意图仅在 检测到 NFC 标签时调度。如果标签包含 NDEF 消息,该消息会自动处理并在 intent extra (NfcAdapter.EXTRA_NDEF_MESSAGES
) 中与您的应用共享。
如果您想在稍后阶段再次读取标签(并设法保持 NFC 标签持续连接),您将需要直接与标签通信。您可以通过标记句柄对象来完成此操作。此对象 (class Tag
) 也会在检测到标签时传递给您的应用(作为 NFC 意图的附加意图):
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
连接标签后,您可以随时使用该对象启动与标签的通信。例如。要重新阅读标签上的当前 NDEF 消息,您可以使用:
Ndef ndef = Ndef.get(tag);
if (ndef != null) {
try {
ndef.connect();
NdefMessage msg = ndef.getNdefMessage();
// do something with the NDEF message
} catch (IOException e) {
} finally {
try {
ndef.close();
} catch (Exception e) {}
}
}