在 flutter 插件中捕获 onNewIntent() class
Catch onNewIntent() in flutter plugin class
问题标题可能有点混乱。我会尝试解释更多细节。
我正在写一个 flutter 插件来使用 NFC。
我有一个示例 Android Activity 在收到 NDEF 消息时触发 onNewIntent()。此时消息负载已准备好使用。
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
}
我需要在插件中具有相同的功能 class。
这是我的插件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?) {
}
由于 NfcforflutterPlugin
不是 Activity,我需要 NfcforflutterPlugin
class 中的触发事件,因为 onNewIntent()
中 Android Activity 将在消息发现时刻调用,这样我就可以 运行 mEventSink.success(ndefMessage)
并将消息传递给 Flutter 端。
有什么想法吗?
实施 PluginRegistry.NewIntentListener
用于收听意图方法。检查 here.
它有onNewIntent
方法。你可以使用它。喜欢,
class NfcforflutterPlugin(private var activity: Activity?) : MethodCallHandler, EventChannel.StreamHandler, PluginRegistry.NewIntentListener {
....................
....................
override fun onNewIntent(intent:Intent):Boolean {
//handle data with intent
return false;
}
}
建议大家参考或fork https://github.com/akeblom/flutter-nfc-reader
这个 repo 修复了 pub.dev https://pub.dev/packages/flutter_nfc_reader
中 flutter-nfc-reader 的一些问题
并且我用真机测试过,效果很好。
代码片段
class FlutterNfcReaderPlugin(val registrar: Registrar) : MethodCallHandler, EventChannel.StreamHandler, NfcAdapter.ReaderCallback {
...
init {
nfcManager = activity.getSystemService(Context.NFC_SERVICE) as? NfcManager
nfcAdapter = nfcManager?.defaultAdapter
}
第 112 行的事件通道处理
// EventChannel.StreamHandler methods
override fun onListen(arguments: Any?, eventSink: EventChannel.EventSink?) {
this.eventSink = eventSink
}
好的,我找到了最适合我的方法。
不需要 onNewIntent()。
正如@chunhunghan提到的,我实现了NfcAdapter.ReaderCallback
。但是为了捕获触发事件,我使用 onTagDiscovered(tag: Tag)
。
看起来像:
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
}
}
问题标题可能有点混乱。我会尝试解释更多细节。
我正在写一个 flutter 插件来使用 NFC。
我有一个示例 Android Activity 在收到 NDEF 消息时触发 onNewIntent()。此时消息负载已准备好使用。
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
}
我需要在插件中具有相同的功能 class。
这是我的插件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?) {
}
由于 NfcforflutterPlugin
不是 Activity,我需要 NfcforflutterPlugin
class 中的触发事件,因为 onNewIntent()
中 Android Activity 将在消息发现时刻调用,这样我就可以 运行 mEventSink.success(ndefMessage)
并将消息传递给 Flutter 端。
有什么想法吗?
实施 PluginRegistry.NewIntentListener
用于收听意图方法。检查 here.
它有onNewIntent
方法。你可以使用它。喜欢,
class NfcforflutterPlugin(private var activity: Activity?) : MethodCallHandler, EventChannel.StreamHandler, PluginRegistry.NewIntentListener {
....................
....................
override fun onNewIntent(intent:Intent):Boolean {
//handle data with intent
return false;
}
}
建议大家参考或fork https://github.com/akeblom/flutter-nfc-reader
这个 repo 修复了 pub.dev https://pub.dev/packages/flutter_nfc_reader
中 flutter-nfc-reader 的一些问题
并且我用真机测试过,效果很好。
代码片段
class FlutterNfcReaderPlugin(val registrar: Registrar) : MethodCallHandler, EventChannel.StreamHandler, NfcAdapter.ReaderCallback {
...
init {
nfcManager = activity.getSystemService(Context.NFC_SERVICE) as? NfcManager
nfcAdapter = nfcManager?.defaultAdapter
}
第 112 行的事件通道处理
// EventChannel.StreamHandler methods
override fun onListen(arguments: Any?, eventSink: EventChannel.EventSink?) {
this.eventSink = eventSink
}
好的,我找到了最适合我的方法。
不需要 onNewIntent()。
正如@chunhunghan提到的,我实现了NfcAdapter.ReaderCallback
。但是为了捕获触发事件,我使用 onTagDiscovered(tag: Tag)
。
看起来像:
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
}
}