Multiple scans / intentions sent to receive activity

I have a persistent problem when my application delivers multiple intentions in a return action after checking the NFC tag.

My application essentially scans the NFC tag, which has some data and sends it to the server. All in all, it works great. I understand that NFC works within a few cms, and maybe my problem is related to a user error, for example, a user waves his phone around a tag that can scan it twice in milliseconds.

I put a timer in the Application object. When the user scans the tag, I start the timer and set the flag to false, this flag is checked in the Activity, which processes the NFC intent, and the intent is deleted if the flag is false. This (should) stop several tag scans within 10 seconds.

My application is used to work with HomeCare, so the user scans the tag in the customers house. When they scan a tag the first time they log on to this client with data and a timestamp. A second tag scan will log out.

In general, it works, but sometimes the guardian will log in and log out on the first client, and then on the second client, and sometimes after a few hours, the guardian will be credited back to the previous client.

What, in my opinion, is happening is taking care of the wrong tag scan, which runs the NFC applet twice. The first intention is delivered immediately, and the second in a few minutes.

How are things. scan tag -> intent delivered to Activity -> start AppObj timer. write data to sqlite DB → run IntentService to send the transaction to the server (canceled after 10 seconds).

Can someone see the problem that I missed, can explain why the Intent duplicate comes in a few hours?

Can anyone suggest a solution that would stop this?

Is there a problem with how intent is handled in this activity? for example, the wrong code in the wrong activity lifecycle method?

Is there a way to cancel / intercept the second intention from the second incorrect scan?

Basically, I want nfcAdapter to be run 10 times in one second, but only the first scan gets delivered to the action. How can I achieve this?

I will send the code.

[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) { } } 
+6
source share
2 answers

From what you described, I would suggest that your affected users “close” (actually hide) the application by pressing the home key. Later they open the application (or rather, activity) from the story (long press key).

Assuming that you only handle NFC-related actions in onCreate() , you usually did not encounter the problem that you described when starting your activity from history, since the onCreate() method was not called if your activity still existed on the background. But , if your activity was destroyed in the meantime (for example, the application was killed manually, the application was killed by the system to free resources, etc.), restarting the application from the history will result in your onCreate() , which will be launched again. When Android restores the activity stack and resends the original intentions (that is, the intent that originally started your activity) again when opening applications from the story, you will receive the NFC intent that it received when it was originally launched.

You can solve this problem by checking if your intent is FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY . This will only take place if your activity has been launched from history.

 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())) { ... } } 

Not resolving your original problem, but as a last resort, remember that NFC tags can be obtained through I / O after receiving the intent. Therefore, to check whether the tag you received in the intent is valid, you can perform such an I / O operation.

If, for example, your tag is an NDEF tag:

 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) { } } 

For tags other than NDEF, you will need to know how to access the tag using low level commands. But at least the connection test will work for any tag.

+5
source

Multiple scans / intentions sent to receive activity

Already the answer is accepted, but the best parameters

add the following flag during the start of activity (by default, the action starts in default mode, that is, it starts a new instance of activity) FLAG_ACTIVITY_CLEAR_TOP

0
source

All Articles