androidflutterkotlindartnfc

Starting Flutter App/Bringing it to foregroundn via NFC NDEF AAR Record, can not access additional information in same Read


I am trying to launch my app and read some data from the NFC Chip at the same time, passing the data to Flutter so I can handle it in the App.

Here is what I have done:

Modified MainActivity.kt

class MainActivity: FlutterActivity() {
    private val CHANNEL = "com.test.test/nfc"
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "onNFCDiscovered") {
                result.success("Method handled successfully")
            } else {
                result.notImplemented()
            }
        }
    }
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        handleIntent(intent)
    }

    private fun handleIntent(intent: Intent) {
        if (NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action) {
            val rawMessages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)
            if (rawMessages != null) {
                val messages = rawMessages.map { it as NdefMessage }
                val record = messages.first().records.first()
                val payload = String(record.payload)
                MethodChannel(flutterEngine!!.dartExecutor.binaryMessenger, CHANNEL).invokeMethod("onNFCDiscovered", payload)
        }
    }
}

added permissions and this intent filter to AndroidManifest.xml:

<intent-filter>
     <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
     <category android:name="android.intent.category.DEFAULT"/>
     <data android:mimeType="application/com.test.test"/>
</intent-filter>

set up a method channel listener in flutter controller:

class LoggingController extends GetxController {
  static const platform = MethodChannel('com.test.test/nfc');

  LoggingController() {
    platform.setMethodCallHandler((call) async {
      if (call.method == "onNFCDiscovered") {
        log("NFC Tag Data: ${call.arguments}");
      }
    });
  }
}

So far, the App launches but none of my attempts to read the additional data stored on the chip at and pass it to Flutter at the same time have been successful.


Solution

  • The problem I believe that onNewIntent is only called

    when the activity is re-launched

    So if you are starting your App using the Manifest intent filters then the Intent with the Ndef message in it is passed to onCreate, onNewIntent is never called because the is no Activity to re-launch yet.

    As you have nicely put the Intent handling is a separate method then in onCreate method add

    // get the Intent the App was started with
    val mIntent = getIntent()
    handleIntent(mIntent)
    

    This is similar to what I do in my App that starts and reads the Tag in one go.