You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 04:09:28