Flutter Android应用通过NDEF Intent启动时的图标异常与实例重复问题
解决NFC启动Flutter Android应用的实例重复与图标异常问题
针对你遇到的两个问题,可通过以下步骤解决:
1. 避免重复创建应用实例
在AndroidManifest.xml的主Activity标签中添加launchMode="singleTask",系统会自动复用已存在的Activity实例,不会新建应用进程:
<activity android:name=".MainActivity" android:launchMode="singleTask" <!-- 添加这一行 --> android:exported="true" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize"> <!-- 原有MAIN/LAUNCHER过滤器 --> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> <!-- NDEF过滤器 --> <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> <data android:scheme="https" android:host="developer.android.com" android:pathPrefix="/test"/> </intent-filter> </activity>
2. 修复NFC启动时的图标异常
在NDEF对应的intent-filter标签中添加android:icon属性,指定应用自身的图标资源,替换系统默认的NFC图标:
<intent-filter android:icon="@mipmap/ic_launcher"> <!-- 添加图标指定 --> <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> <data android:scheme="https" android:host="developer.android.com" android:pathPrefix="/test"/> </intent-filter>
注:如果你的应用图标存放在drawable目录,替换为@drawable/你的图标文件名即可。
3. 处理复用实例时的NFC数据传递
因为使用singleTask模式,新的NFC Intent会通过onNewIntent方法传递,需要自定义Flutter Activity并将数据转发给Flutter端:
自定义MainActivity(Kotlin)
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel class MainActivity : FlutterActivity() { private val CHANNEL = "nfc_intent" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) sendIntentDataToFlutter(flutterEngine) } override fun onNewIntent(intent: android.content.Intent) { super.onNewIntent(intent) setIntent(intent) flutterEngine?.let { sendIntentDataToFlutter(it) } } private fun sendIntentDataToFlutter(flutterEngine: FlutterEngine) { val uri = intent.dataString MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL) .invokeMethod("handleNfcIntent", uri) } }
Flutter端接收数据
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() => runApp(const MyApp()); class MyApp extends StatefulWidget { const MyApp({super.key}); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { static const platform = MethodChannel('nfc_intent'); String? nfcUri; @override void initState() { super.initState(); platform.setMethodCallHandler((call) async { if (call.method == 'handleNfcIntent') { setState(() => nfcUri = call.arguments as String?); } }); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('NFC Demo')), body: Center(child: Text(nfcUri ?? '等待NFC标签触发')), ), ); } }
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

