11package io.flutter.plugins.nfcmanager
22
33import android.app.Activity
4+ import androidx.lifecycle.*
45import android.content.Intent
56import android.nfc.NfcAdapter
67import android.nfc.Tag
@@ -19,29 +20,33 @@ import android.os.Build
1920import io.flutter.embedding.engine.plugins.FlutterPlugin
2021import io.flutter.embedding.engine.plugins.activity.ActivityAware
2122import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
23+ import io.flutter.embedding.engine.plugins.lifecycle.FlutterLifecycleAdapter
2224import io.flutter.plugin.common.MethodCall
2325import io.flutter.plugin.common.MethodChannel
2426import io.flutter.plugin.common.MethodChannel.MethodCallHandler
2527import io.flutter.plugin.common.MethodChannel.Result
26- import io.flutter.plugin.common.EventChannel;
28+ import io.flutter.plugin.common.EventChannel
2729import io.flutter.plugin.common.EventChannel.EventSink
2830import io.flutter.plugin.common.EventChannel.StreamHandler
2931import java.io.IOException
3032import java.lang.Exception
3133import java.util.*
3234
33- class NfcManagerPlugin : FlutterPlugin , MethodCallHandler , ActivityAware {
35+ class NfcManagerPlugin : FlutterPlugin , MethodCallHandler , ActivityAware , LifecycleObserver {
3436 private lateinit var channel : MethodChannel
3537 private lateinit var activity: Activity
3638 private lateinit var tags: MutableMap <String , Tag >
39+ private lateinit var lifecycle: Lifecycle
3740
3841 private var tagFromIntent: Tag ? = null
3942 private var sinkTagDiscoveredEvents = ArrayList <EventSink >()
4043
41-
4244 private var adapter: NfcAdapter ? = null
4345 private var connectedTech: TagTechnology ? = null
4446
47+ private lateinit var enableActivityReaderMode : () -> Unit
48+ private lateinit var disableActivityReaderMode : () -> Unit
49+
4550 override fun onAttachedToEngine (binding : FlutterPlugin .FlutterPluginBinding ) {
4651 val baseChannelName = " plugins.flutter.io/nfc_manager"
4752
@@ -55,23 +60,36 @@ class NfcManagerPlugin: FlutterPlugin, MethodCallHandler, ActivityAware{
5560
5661 override fun onListen (arguments : Any? , events : EventSink ) {
5762 if (sinkTagDiscoveredEvents.isEmpty()) {
58- if (Build .VERSION .SDK_INT < Build .VERSION_CODES .KITKAT ) {
59- events.error(" unavailable" , " Requires API level 19." , null )
60- } else {
61- val adapter = adapter ? : run {
62- events.error(" unavailable" , " NFC is not available for device." , null )
63- return
63+ enableActivityReaderMode = {
64+ if (Build .VERSION .SDK_INT < Build .VERSION_CODES .KITKAT ) {
65+ events.error(" unavailable" , " Requires API level 19." , null )
66+ } else {
67+ val adapter = adapter
68+
69+ if (adapter != null ) {
70+ var argMaps = arguments as HashMap <String ,Any ?>
71+ adapter.enableReaderMode(activity, NfcAdapter .ReaderCallback {
72+ activity.runOnUiThread { broadcastPreparedTag(it) }
73+ }, getFlags(argMaps[" pollingOptions" ] as List <String >), null )
74+ } else {
75+ events.error(" unavailable" , " NFC is not available for device." , null )
76+ }
6477 }
78+ }
6579
66- var argMaps = arguments as HashMap <String ,Any ?>
67- adapter.enableReaderMode(activity, NfcAdapter .ReaderCallback {
68- activity.runOnUiThread { broadcastPreparedTag(it) }
69- }, getFlags(argMaps[" pollingOptions" ] as List <String >), null )
80+ disableActivityReaderMode = {
81+ if (Build .VERSION .SDK_INT < Build .VERSION_CODES .KITKAT ) {
82+ events.error(" unavailable" , " Requires API level 19." , null )
83+ } else {
84+ adapter?.disableReaderMode(activity)
85+ }
7086 }
87+
88+ enableActivityReaderMode()
7189 }
7290
73- currentEvents = events;
74- sinkTagDiscoveredEvents.add(currentEvents);
91+ currentEvents = events
92+ sinkTagDiscoveredEvents.add(currentEvents)
7593
7694 tagFromIntent?.let {
7795 currentEvents.success(prepareTag(it))
@@ -80,10 +98,10 @@ class NfcManagerPlugin: FlutterPlugin, MethodCallHandler, ActivityAware{
8098 }
8199
82100 override fun onCancel (arguments : Any? ) {
83- sinkTagDiscoveredEvents.remove(currentEvents);
101+ sinkTagDiscoveredEvents.remove(currentEvents)
84102
85103 if (sinkTagDiscoveredEvents.isEmpty()) {
86- adapter?.disableReaderMode(activity )
104+ disableActivityReaderMode( )
87105 }
88106 }
89107 }
@@ -98,12 +116,49 @@ class NfcManagerPlugin: FlutterPlugin, MethodCallHandler, ActivityAware{
98116 }
99117
100118 override fun onAttachedToActivity (binding : ActivityPluginBinding ) {
119+ initBinding(binding)
120+ processIntent(activity.intent)
121+ }
122+
123+ override fun onDetachedFromActivity () {
124+ }
125+
126+ override fun onReattachedToActivityForConfigChanges (binding : ActivityPluginBinding ) {
127+ initBinding(binding)
128+ autoEnableReaderMode()
129+ }
130+
131+ override fun onDetachedFromActivityForConfigChanges () {
132+ // autoDisableReaderMode()
133+ // lifecycle.removeObserver(this)
134+ }
135+
136+ @OnLifecycleEvent(Lifecycle .Event .ON_RESUME )
137+ private fun autoEnableReaderMode () {
138+ // For some device (OnePlus for example),
139+ // the readerMode is not reenabled after paused
140+ if (sinkTagDiscoveredEvents.isNotEmpty()) {
141+ enableActivityReaderMode()
142+ }
143+ }
144+
145+ @OnLifecycleEvent(Lifecycle .Event .ON_PAUSE )
146+ private fun autoDisableReaderMode () {
147+ if (sinkTagDiscoveredEvents.isNotEmpty()) {
148+ disableActivityReaderMode()
149+ }
150+ }
151+
152+ private fun initBinding (binding : ActivityPluginBinding ) {
101153 activity = binding.activity
154+ lifecycle = FlutterLifecycleAdapter .getActivityLifecycle(binding)
155+
156+ lifecycle.addObserver(this )
102157
103158 binding.addOnNewIntentListener(fun (intent : Intent ? ): Boolean {
104- var tagProcessed = false ;
159+ var tagProcessed = false
105160
106- if (intent != null ){
161+ if (intent != null ) {
107162 val tag = processIntent(intent)
108163
109164
@@ -114,21 +169,7 @@ class NfcManagerPlugin: FlutterPlugin, MethodCallHandler, ActivityAware{
114169 }
115170
116171 return tagProcessed
117- })
118-
119- processIntent(activity.intent)
120- }
121-
122- override fun onDetachedFromActivity () {
123- // no op
124- }
125-
126- override fun onReattachedToActivityForConfigChanges (binding : ActivityPluginBinding ) {
127- activity = binding.activity
128- }
129-
130- override fun onDetachedFromActivityForConfigChanges () {
131- // no op
172+ })
132173 }
133174
134175 override fun onMethodCall (call : MethodCall , result : Result ) {
0 commit comments