Catch onNewIntent() in flutter plugin class
Solution 1
Ok, I found the way which worked for me perfectly.
There was no need for onNewIntent().
As @chunhunghan mentioned, I implemented NfcAdapter.ReaderCallback
. But to catch the triggering event I use onTagDiscovered(tag: Tag)
.
So it looks like:
class NfcFlutterPlugin(private var activity: Activity?) : MethodCallHandler, NfcAdapter.ReaderCallback, EventChannel.StreamHandler {
private var mNfcAdapter: NfcAdapter? = null
private var mEventSink: EventChannel.EventSink? = null
companion object {
@JvmStatic
fun registerWith(registrar: Registrar) {
var nfcflutterPlugin = NfcFlutterPlugin(registrar.activity())
val channel = MethodChannel(registrar.messenger(), "nfc_flutter")
channel.setMethodCallHandler(nfcflutterPlugin)
val eventChannel = EventChannel(registrar.messenger(), "nfcDataStream")
eventChannel.setStreamHandler(nfcflutterPlugin)
}
}
fun initializeNFCReading():Boolean {
mNfcAdapter = NfcAdapter.getDefaultAdapter(activity)
if(!checkNFCEnable())
return false
if (mNfcAdapter == null)
return false
val bundle = Bundle()
mNfcAdapter?.enableReaderMode(activity, this, NfcAdapter.FLAG_READER_NFC_A, bundle)
return true
}
private fun checkNFCEnable(): Boolean {
return if (mNfcAdapter == null) {
//mTvView.text = getString(R.string.tv_noNfc)
false
} else {
mNfcAdapter!!.isEnabled
}
}
override fun onMethodCall(call: MethodCall, result: Result) {
if (call.method == "getPlatformVersion") {
result.success("Android ${android.os.Build.VERSION.RELEASE}")
return
}
if (call.method == "initializeNFCReading") {
result.success(initializeNFCReading())
return
}
result.notImplemented()
}
override fun onTagDiscovered(tag: Tag) {
val ndef = Ndef.get(tag)
?: // tag is not in NDEF format; skip!
return
try {
ndef.connect()
val message = ndef.ndefMessage ?: return
parserNDEFMessage(message)
} catch (e: IOException) {
} catch (e: FormatException) {
}
}
private fun parserNDEFMessage(message: NdefMessage) {
//parse message
mEventSink?.success(parsedMessage)
}
override fun onListen(p0: Any?, eventSink: EventChannel.EventSink?) {
mEventSink = eventSink
}
override fun onCancel(p0: Any?) {
mEventSink = null
}
}
Solution 2
Implement PluginRegistry.NewIntentListener
for listening intent methods. Check here.
It has onNewIntent
method. you can use it. Like,
class NfcforflutterPlugin(private var activity: Activity?) : MethodCallHandler, EventChannel.StreamHandler, PluginRegistry.NewIntentListener {
....................
....................
override fun onNewIntent(intent:Intent):Boolean {
//handle data with intent
return false;
}
}
drek
I am Android developer. Currently mostly on Java and little on Kotlin. Also I love doing cross platform apps on Flutter.
Updated on December 13, 2022Comments
-
drek over 1 year
Question title might be a bit confusing. I will try to explain more details.
I am writing a flutter plugin to use NFC.
I have example Android Activity that triggers onNewIntent() as it receives NDEF message. At this moment the message payload is ready to be used.
class MainActivity : AppCompatActivity() { private var mNfcAdapter: NfcAdapter? = null private var mPendingIntent: PendingIntent? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) mNfcAdapter = NfcAdapter.getDefaultAdapter(this) mPendingIntent = PendingIntent.getActivity( this, 0, Intent(this, this.javaClass) .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0 ) } override fun onResume() { super.onResume() mNfcAdapter?.enableForegroundDispatch(this, mPendingIntent, null, null) } override fun onPause() { super.onPause() mNfcAdapter?.disableForegroundDispatch(this) } override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) if (NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action) { intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)?.also { rawMessages -> val messages: List<NdefMessage> = rawMessages.map { it as NdefMessage } parseNDEFMessage(messages) } } } private fun parseNDEFMessage(messages: List<NdefMessage>) { //do parsing and display payload }
I need to have same functionality in plugin class.
Here is my plugin class
class NfcforflutterPlugin(private var activity: Activity?) : MethodCallHandler, EventChannel.StreamHandler { private var mNfcAdapter: NfcAdapter? = null private var mPendingIntent: PendingIntent? = null private var mEventSink: EventChannel.EventSink? = null companion object { @JvmStatic fun registerWith(registrar: Registrar) { var nfcforflutterPlugin = NfcforflutterPlugin(registrar.activity()) val channel = MethodChannel(registrar.messenger(), "nfcforflutter") channel.setMethodCallHandler(nfcforflutterPlugin) val eventChannel = EventChannel(registrar.messenger(), "nfcforflutter") eventChannel.setStreamHandler(nfcforflutterPlugin) } } fun getNDEFMessage(): String{ return "CALLED getNDEFMessage" } fun initializeNFCReading():Boolean { mNfcAdapter = NfcAdapter.getDefaultAdapter(activity) if(!checkNFCEnable()) return false val intent = Intent(activity?.applicationContext, activity?.javaClass) intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) val pendingIntent = PendingIntent.getActivity(activity?.applicationContext, 0, intent, 0) mNfcAdapter?.enableForegroundDispatch(activity, pendingIntent, null, null) return true } private fun checkNFCEnable(): Boolean { return if (mNfcAdapter == null) { false } else { mNfcAdapter!!.isEnabled } } override fun onMethodCall(call: MethodCall, result: Result) { if (call.method == "getPlatformVersion") { result.success("Android ${android.os.Build.VERSION.RELEASE}") return } if (call.method == "getNDEFMessage") { result.success(getNDEFMessage()) return } if (call.method == "initializeNFCReading") { result.success(initializeNFCReading()) return } result.notImplemented() } override fun onListen(p0: Any?, eventSink: EventChannel.EventSink?) { mEventSink = eventSink } override fun onCancel(p0: Any?) { }
SInce
NfcforflutterPlugin
is not an Activity, I need a triggering event inNfcforflutterPlugin
class asonNewIntent()
in Android Activity which will be invoked at the message discovering moment, so that I can runmEventSink.success(ndefMessage)
and pass message to Flutter side.Any idea?
-
Abhay Koradiya almost 5 yearswhat is the issue ? you have messages list in activity which you can pass.
-
drek almost 5 years@ Abhay Koradiya: Actually I dont have even Activity. The Activity is an example of how it should work. I only have a
NfcforflutterPlugin
. Ok, I will edit the line On Android side to I have example Actitivy.
-