如何通过 NFC 打开应用程序并在同一操作中传递嵌入数据?

How can I open an app via NFC and pass embedded data in the same action?

我是 android 和 NFC 的新手,正在尝试制作一个简单的小型 Flutter 中继应用程序,该应用程序采用 json 嵌入 NFC 标签的数据并执行所描述的操作。即:

  1. 在这张 NFC 贴纸上轻触我的 phone
  2. 打开我的 flutter 应用程序
  3. 自动将json数据传递给可以读取和执行指令的函数。

我的问题是我可以执行#2 或#3,但不能使用相同的 NFC 扫描。如果我在关闭应用程序的情况下进行扫描,它会打开我的应用程序,但不会在 MyApp.build 中触发我的 NFC 监听功能。如果该应用程序已经在前台运行,它将命中它,但这会限制该值。

NFC 标签(通过 NFC Tools

DATA
{"action" : "Do the thing and you will have the power."}
FORMAT
Media (0x02)
Defined by RFC 2046
TYPE
application/json

AndroidManifest.xml

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="application/json" />
</intent-filter>

MainActivity.kt

package com.example.package

import io.flutter.embedding.android.FlutterActivity

import android.content.Intent;
import android.os.Bundle;

class MainActivity: FlutterActivity() {
}

main.dart(使用nfc_in_flutter

import 'package:flutter/material.dart';
import 'package:nfc_in_flutter/nfc_in_flutter.dart';


void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var stream = NFC.readNDEF();

    stream.listen((NDEFMessage message) {
      for (var record in message.records) {
        print("Payload: ${record.payload}"); // This works when foregrounded
      }
    });

    return MaterialApp(
      title: 'Material App',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Material App Bar'),
        ),
        body: Text("Foo"),
      ),
    );
  }
}

我知道你的问题的原因,但不知道你在 Flutter 中的解决方案(我知道 Java 中的解决方案),但希望这个答案能为你指明正确的方向。

当您的应用程序在前台 运行 时,系统 NFC 应用程序可以通过两种方式向您发送有关它检测到的 NFC 标签的数据。

新的enableReaderMode更好API使用回调onTagDiscovered来处理数据。

旧的 enableForgroundDispatch API 暂停并恢复您的应用程序以向其发送包含有关 NFC 标签数据的 Intent,这是由 onNewIntent 方法处理的.

nfc_in_flutter 包会为您处理这两种方法,但当您的应用程序由系统 NFC 应用程序启动时,它不会处理。

当您的应用不是 运行 并且系统 NFC 应用看到 NFC 标签时,它会读取标签以识别类型和数据内容并生成 Intent(很像使用的 Intent 格式对于 enableForgroundDispatch API,它会查看 Manifest 以查看哪个应用处理此类 Intent 并与应用共享。
不同之处在于 onNewIntent 方法仅在 App Restart 上调用,而不在 App Start.

上调用

通常在 Java 中,在您的 onCreate 方法中,您会调用 getIntent() 来获取您的 Activity 开始时使用的 Intent,然后直接调用处理该方法的方法NFC Intents(因此您可以使用 onCreate 中的代码,例如 onNewIntent(getIntent()); 来处理传入的共享数据)

因此,当您的 App 通过读取 NFC 标签启动时,该机制更像是一个 Android Activity 与另一个 Android Activity 共享数据而不是它实际上与NFC阅读有关。

因此,当您的应用程序未 运行 时,从读取的 NFC 标签中获取数据更多地是关于接收“共享”意图,这 post 可能会对您有所帮助 https://muetsch.io/how-to-receive-sharing-intents-in-flutter.html