我一直存在一个问题,即我的应用在NFC标签扫描后向接收活动提供多种意图。
我的应用基本上会扫描一个NFC标签,该标签上有一些数据并将其发送到服务器。 一般来说它工作正常。我知道NFC工作在几个cms的阈值范围内,也许我的问题是用户错误,例如用户在标签周围挥动手机,可以在毫秒内扫描两次。
我在Application对象中放了一个计时器。当用户扫描标签时,我启动计时器并将标志设置为false,在处理NFC意图的Activity中检查此标志,如果标志为false则删除意图。这(应该)在10秒内停止对标签的多次扫描。
我的应用程序用于HomeCare工作,因此用户将扫描客户端中的标签。当他们第一次在该客户端上使用数据和时间戳记录它们时扫描标签。标签的第二次扫描会将其记录下来。
一般情况下它可以工作,但有时护理人员会在第一个客户端登录和注销,然后在第二个客户端登录或退出,或者有时几个小时后,护理人员将在之前的客户端登录。
我认为正在发生的事情是护理人员错误地扫描了两次触发NFC adpter的标签。第一个意图是立即发送,然后第二个意图是几分钟/小时后发送。
事情如何发展。 扫描标签 - >意图传递给活动 - >启动AppObj计时器。 将数据写入sqlite DB - >启动IntentService将事务发送到服务器(10秒后取消)。
任何人都可以看到我错过的问题可以解释为什么几小时后会传递重复的意图吗?
有人能提出一个可以阻止这种情况发生的解决方案吗?
在活动中如何处理意图是否存在问题?例如错误的Activity生命周期方法中的错误代码?
有没有办法从第二次误扫描中取消/拦截第二个意图?
基本上,我想要的是nfcAdapter可以在一秒内触发10次,但只有第一次扫描被传递给活动。我怎样才能做到这一点?
我会发布一些代码。
[EDIT2]
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();
}
[EDIT3]
<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>
。 [edit4]
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) {
}
}
答案 0 :(得分:5)
根据您的描述,我会假设受影响的用户通过按主页键“关闭”(实际上隐藏)应用程序。之后他们将从历史记录中打开应用程序(或者更确切地说是活动)(长按主页键)。
假设您只处理onCreate()
中与NFC相关的意图 ,您通常不会遇到您在历史记录中作为{{1}启动活动时所描述的问题如果您的活动仍然存在于后台,则不会调用方法。 但如果你的活动同时遭到破坏(例如app被手动杀死,app被系统杀死以释放资源等),从历史记录中重新启动应用程序将导致你的{{ 1}}方法再次运行。当Android重建活动堆栈并在从历史记录打开应用时再次发送原始意图(即最初启动您的活动的意图)时,您的活动将收到它在收到时的NFC意图它最初开始了。
您可以通过检查您收到的意图是否设置了onCreate()
来解决此问题。如果您的活动是从历史记录开始的话,那么仅
onCreate()
不解决您的初始问题,但作为最后的手段,请记住,在收到意图后,IO操作可以访问NFC标签。因此,为了检查您在意图中收到的标签是否确实存在,您可以执行这样的IO操作。
例如,如果您的标记是NDEF标记:
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
对于非NDEF标记,您需要知道如何使用低级命令访问标记。但至少连接测试适用于任何标签。
答案 1 :(得分:0)
传递给接收活动的多个扫描/意图
已经接受了答案,但更好的选择是
在启动活动时添加以下标志(默认情况下,活动以默认模式启动,即启动新的活动实例) FLAG_ACTIVITY_CLEAR_TOP