My Activity.onCreate() method is called twice when I use foreground NFC dispatching and re-install my app after force-stop. Detailed steps to reproduce this bug:
- Create the following Activity:
package com.example.sample
class MainActivity : AppCompatActivity() {
private val nfcTechList: Array<Array<String>> = arrayOf(arrayOf(IsoDep::class.java.name))
private val nfcIntentFilters: Array<IntentFilter> = arrayOf(IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED, "*/*"))
private lateinit var nfcAdapter: NfcAdapter
private lateinit var pendingIntent: PendingIntent
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d("SAMPLE_TAG", "onCreate")
setContentView(R.layout.activity_main)
nfcAdapter = NfcAdapter.getDefaultAdapter(applicationContext)
val nfcIntent = Intent(this, javaClass).apply {
addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
}
pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
PendingIntent.getActivity(this, 0, nfcIntent, PendingIntent.FLAG_MUTABLE)
} else {
PendingIntent.getActivity(this, 0, nfcIntent, 0)
}
}
override fun onResume() {
super.onResume()
Log.d("SAMPLE_TAG", "onResume")
nfcAdapter.enableForegroundDispatch(this, pendingIntent, nfcIntentFilters, nfcTechList)
}
override fun onPause() {
super.onPause()
Log.d("SAMPLE_TAG", "onPause")
nfcAdapter.disableForegroundDispatch(this)
}
}
- Install and run this app on Android >= 12 and targetSdk = 33.
- Force-stop this app through settings and delete the app.
- Install and run the app again through this command:
adb install app-debug.apk && adb shell am start -n "com.example.sample/com.example.sample.MainActivity"or run the app with Android Studio. (Note: if you run these 2 adb commands separately one after the other - the bug won't reproduce!). - In logcat you'll see that
onCreate()method was called twice:
14:20:55.419 22851 22851 D SAMPLE_TAG: onCreate
14:20:55.542 22851 22851 D SAMPLE_TAG: onResume
14:20:55.575 22851 22851 D SAMPLE_TAG: onPause
14:20:55.612 22851 22851 D SAMPLE_TAG: onCreate
14:20:55.640 22851 22851 D SAMPLE_TAG: onResume
I expect that Activity.onCreate() method will be called only once regardless of the way you run the app. I used the example of foreground NFC dispatching from official documentation, see https://developer.android.com/guide/topics/connectivity/nfc/advanced-nfc#foreground-dispatch
The actual result is that onCreate() & the following onResume() methods are called twice although it doesn't correspond with the Activity's lifecycle.
The answer is to use
enableReaderModeinstead of the older as less reliableenableForegroundDispatchenableReaderModedoes not have to pause and resume your app and does not have interactions with your startup mode (which might be your problem), it also gives you more control and it helps you correctly not do NFC operations on the main UI thread as it automatically starts a new thread and is much more reliable especially for write operations.An example of using enableReaderMode