Android Activity.onCreate is called twice when using foreground NFC dispatching

184 views Asked by At

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:

  1. 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)
    }
}
  1. Install and run this app on Android >= 12 and targetSdk = 33.
  2. Force-stop this app through settings and delete the app.
  3. 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!).
  4. 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.

1

There are 1 answers

2
Andrew On

The answer is to use enableReaderMode instead of the older as less reliable enableForegroundDispatch

enableReaderMode does 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