我有一个持续存在的问题,我的应用程序在 NFC 标签扫描后向接收 Activity 传送多个 Intent 。
我的应用程序本质上是扫描一个 NFC 标签,上面有一些数据并将其发送到服务器。 一般来说它工作正常。我知道 NFC 在几厘米的阈值内工作,也许我的问题是用户错误,例如用户在标签周围挥动手机,标签可以在几毫秒内扫描两次。
我在 Application 对象中放置了一个计时器。当用户扫描标签时,我启动计时器并将标志设置为 false,在处理 NFC Intent 的 Activity 中检查此标志,如果标志为 false,则丢弃 Intent 。这(应该)在 10 秒内停止对标签的多次扫描。
我的应用用于家庭护理工作,因此用户将在客户家中扫描标签。当他们第一次扫描标签时,它会使用数据和时间戳将他们登录到该客户端。标签的第二次扫描会将它们注销。
一般来说它是有效的,但有时护理人员会在第一个客户处登录和注销,然后在第二个客户处或有时几小时后,护理人员会在前一个客户处重新登录。
我认为正在发生的事情是护理人员误扫描了触发 NFC 适配器两次的标签。第一个 Intent 立即交付,然后第二个 Intent 在几分钟/几小时后交付。
事情是如何流动的。 扫描标签 -> Intent 传递给 Activity -> 启动 AppObj 计时器。 将数据写入 sqlite DB -> 启动 IntentService 将事务发送到服务器(10 秒后取消)。
谁能看到一个我遗漏的问题,它可以解释为什么在几个小时后交付了一个重复的 Intent?
谁能提出阻止这种情况发生的解决方案?
在 Activity 中处理 Intent 的方式是否存在问题?例如错误的 Activity 生命周期方法中的错误代码?
有没有办法取消/拦截第二次误扫描的第二个 Intent ?
基本上,我想要的是 nfcAdapter 可以在一秒钟内被触发 10 次,但只有第一次扫描被传送到 Activity 。我怎样才能做到这一点?
我会发布一些代码。
[编辑2]
Toast.makeText(this, "about to test flags", Toast.LENGTH_LONG).show();
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
Toast.makeText(this, "intent is from history", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(this, "intent is not from history", Toast.LENGTH_LONG).show();
}
.
[编辑3]
<activity
android:name=".NfcscannerActivity"
android:screenOrientation="portrait"
>
<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="com.carefreegroup.rr3.QRCODE_ACTION" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<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>
<activity
android:name=".EntryActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:launchMode="singleTask" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="com.carefreegroup.rr3.INVALID_CARER_TAG_SCANNED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
. [编辑4]
Tag tagTest = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Ndef ndefTag = Ndef.get(tagTest);
try {
Log.e(TAG, "about to test io operations on Ndef Tag");
ndefTag.connect(); // this should already perform an IO operation and should therefore fail if there is no tag
NdefMessage ndefMsg = ndefTag.getNdefMessage(); // this reads the current NDEF message from the tag and consequently causes an IO operation
Log.e(TAG, "tested io operations on Ndef Tag, must be a real Tag!!!!!******!!!!!!");
} catch (Exception e) {
// there is no tag or communication with tag dropped
Log.e(TAG, "tested io operations on Ndef Tag, No Tag there, must be a re-delivery of the old Tag via an intent!!!!!******!!!!!!!!!!!!!!!!!!!!!!");
onResume();
} finally {
try {
ndefTag.close();
} catch (Exception e) {
}
}
最佳答案
根据您的描述,我假设受影响的用户通过按主页键“关闭”(实际上是隐藏)应用程序。稍后他们会从历史记录(长按主页键)中打开应用程序(或者更确切地说是那个 Activity )。
假设您在 onCreate()
中处理与 NFC 相关的 Intent 仅,您通常不会遇到您在从历史记录开始 Activity 时描述的问题如果您的 Activity 仍然存在于后台,则不会调用 onCreate()
方法。 但是 如果您的 Activity 同时被销毁(例如,应用程序被手动杀死,应用程序被系统杀死以释放资源等),从历史记录中重新启动应用程序将导致您的 onCreate()
方法再次运行。当 Android 重建 Activity 堆栈并重新发送原始 Intent (即最初启动您的 Activity 的 Intent )时,从历史记录中打开应用程序时,您的 Activity 将收到它收到的 NFC Intent 它最初是开始的。
您可以通过检查您收到的 Intent 是否设置了 FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
来解决这个问题。如果您的 Activity 是从历史开始的,那么只有是这种情况。
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) {
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()) ||
NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) {
...
}
}
不是解决您最初的问题,而是作为最后的手段,请记住,在收到 Intent 后,IO 操作可以访问 NFC 标签。因此,为了检查您在 Intent 中收到的标签是否实际存在,您可以执行这样的 IO 操作。
例如,如果您的标签是 NDEF 标签:
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Ndef ndefTag = Ndef.get(tag);
try {
ndefTag.connect(); // this should already perform an IO operation and should therefore fail if there is no tag
NdefMessage ndefMsg = ndefTag.getNdefMessage(); // this reads the current NDEF message from the tag and consequently causes an IO operation
} catch (Exception e) {
// there is no tag or communication with tag dropped
} finally {
try {
ndefTag.close();
} catch (Exception e) {
}
}
对于非 NDEF 标签,您需要知道如何使用低级命令访问标签。但至少连接测试适用于任何标签。
关于android - 多个扫描/Intent 传递给接收 Activity ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23362675/