Reputation: 111
I'm new to both android and NFC, and trying to make a simple little Flutter relay app which takes json data embedded on an NFC tag and executes the action described. ie:
My issue is that I can do #2, or #3, but not with the same NFC scan. If I scan with the app closed, it opens my app, but doesn't hit my NFC listening function in the MyApp.build
. If the app is already foreground it will hit it, but that limits the value.
NFC Tag (via NFC Tools)
DATA
{"action" : "Do the thing and you will have the power."}
FORMAT
Media (0x02)
Defined by RFC 2046
TYPE
application/json
AndroidManifest.xml
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/json" />
</intent-filter>
MainActivity.kt
package com.example.package
import io.flutter.embedding.android.FlutterActivity
import android.content.Intent;
import android.os.Bundle;
class MainActivity: FlutterActivity() {
}
main.dart (using nfc_in_flutter)
import 'package:flutter/material.dart';
import 'package:nfc_in_flutter/nfc_in_flutter.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
var stream = NFC.readNDEF();
stream.listen((NDEFMessage message) {
for (var record in message.records) {
print("Payload: ${record.payload}"); // This works when foregrounded
}
});
return MaterialApp(
title: 'Material App',
home: Scaffold(
appBar: AppBar(
title: Text('Material App Bar'),
),
body: Text("Foo"),
),
);
}
}
Upvotes: 2
Views: 3685
Reputation: 10162
I know the reason for your problem but not the solution for your problem in Flutter (I know the solution in Java), but hopefully this answer will point you in the right direction.
When your App is in running in the foreground there are two ways the System NFC App sends you data about the NFC Tag it has detected.
The new enableReaderMode
better API use a Callback onTagDiscovered
to handle the data.
The old enableForgroundDispatch
API pauses and resumes your App to send it an Intent
that contains data about the NFC Tag and this is handled by the onNewIntent
method.
The nfc_in_flutter
package handles both of these methods for you BUT it does not handle when your App is started by the System NFC App.
When your App is not running and the System NFC App see an NFC Tag it reads the Tag to identify the Type and data content and generates an Intent
(Much like the Intent format used for the enableForgroundDispatch
API, it then looks at the Manifest
to see which App handles this type of Intent
as shares it with the App.
The difference is that onNewIntent
method is only called on App Restart
not on App Start
.
Normally in Java in your onCreate
method you would call getIntent()
to get the Intent your Activity was started with and then call directly the method that processes the NFC Intents (so you could use the code in onCreate
like onNewIntent(getIntent());
to process the incoming shared data)
So when you App is started by the reading of an NFC Tag the mechanism more like one Android Activity sharing data with another Android Activity than it is actually to do with NFC reading.
Thus in flutter getting data from the NFC Tag that was read when your App was not running is more about receiving "sharing" Intents and this post might help you https://muetsch.io/how-to-receive-sharing-intents-in-flutter.html
Upvotes: 2