Flutter NFC信息读取插件nfc_info的使用

Flutter NFC信息读取插件nfc_info的使用

这个包是为了让Flutter应用程序能够在应用从后台切换到前台时获取NFC标签传递的数据。

请注意,这是该包的第一个版本,在某些方面我并不确定,特别是在iOS平台上。


完整示例代码

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

import 'package:flutter/services.dart';
import 'package:nfc_info/nfc_info.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  String _platformVersion = '未知';
  String? _initialNfc = "";
  String _latestNfc = "";
  StreamSubscription? _sub;

  [@override](/user/override)
  void initState() {
    super.initState();
    WidgetsBinding.instance!.addObserver(this);
    initPlatformState();
    getInitialNfcInfo();
    listenToNfcStream();
  }

  [@override](/user/override)
  void dispose() {
    WidgetsBinding.instance!.removeObserver(this);
    _sub?.cancel();
    super.dispose();
  }

  [@override](/user/override)
  void didChangeAppLifecycleState(AppLifecycleState state) {
    switch (state) {
      case AppLifecycleState.resumed:
        print("app resumed");
        // getNfcInfo();
        break;
      default:
        break;
    }
  }

  // 平台消息是异步的,所以我们通过异步方法进行初始化。
  Future<void> initPlatformState() async {
    String platformVersion;
    // 平台消息可能会失败,所以我们使用try/catch来捕获PlatformException。
    try {
      platformVersion = await NfcInfo.platformVersion;
    } on PlatformException {
      platformVersion = '获取平台版本失败。';
    }

    // 如果小部件在异步平台消息执行期间从树中移除,我们希望丢弃回复而不是调用setState来更新我们的非存在的外观。
    if (!mounted) return;

    setState(() {
      _platformVersion = platformVersion;
    });
  }

  Future<void> getInitialNfcInfo() async {
    String? nfc = "";
    try {
      nfc = await (NfcInfo.getInitialText() as FutureOr<String>);
    } on PlatformException {
      print("getInitialNfcInfo: 错误 getInitialText()");
    }
    print('getInitialNfcInfo: $nfc');
    if (!mounted) return;
    setState(() {
      _initialNfc = nfc;
    });
    // ��icoffee://www.icoffee.app/shops/123
    if (nfc != null && nfc.isNotEmpty) {
      /// TODO 如果我们得到了nfc,需要清除
      /// 这样当应用程序从前台切换到后台时,应用程序将不会再次处理相同的旧NFC数据。
      // await NfcInfo.reset();
    }
  }

  void listenToNfcStream() {
    _sub = NfcInfo.getTextsStream().listen((String nfc) {
      if (!mounted) return;
      print("nfc from stream: $nfc");
      setState(() {
        _latestNfc = nfc;
      });
    }, onError: (Object err) {
      if (!mounted) return;
      print(err.toString());
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('NFC信息'),
        ),
        body: Column(
          children: [
            Text('运行于: $_platformVersion\n'),
            Text('收到的nfc: $_initialNfc'),
            Text('nfc流: $_latestNfc'),
          ],
        ),
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.nfc),
          onPressed: getInitialNfcInfo,
        ),
      ),
    );
  }
}

说明

  1. 导入必要的库

    import 'package:flutter/material.dart';
    import 'dart:async';
    
    import 'package:flutter/services.dart';
    import 'package:nfc_info/nfc_info.dart';
    
  2. 初始化状态

    void initState() {
      super.initState();
      WidgetsBinding.instance!.addObserver(this);
      initPlatformState();
      getInitialNfcInfo();
      listenToNfcStream();
    }
    
  3. 获取平台版本

    Future<void> initPlatformState() async {
      String platformVersion;
      try {
        platformVersion = await NfcInfo.platformVersion;
      } on PlatformException {
        platformVersion = '获取平台版本失败。';
      }
      if (!mounted) return;
      setState(() {
        _platformVersion = platformVersion;
      });
    }
    
  4. 获取初始NFC信息

    Future<void> getInitialNfcInfo() async {
      String? nfc = "";
      try {
        nfc = await (NfcInfo.getInitialText() as FutureOr<String>);
      } on PlatformException {
        print("getInitialNfcInfo: 错误 getInitialText()");
      }
      print('getInitialNfcInfo: $nfc');
      if (!mounted) return;
      setState(() {
        _initialNfc = nfc;
      });
    }
    
  5. 监听NFC流

    void listenToNfcStream() {
      _sub = NfcInfo.getTextsStream().listen((String nfc) {
        if (!mounted) return;
        print("nfc from stream: $nfc");
        setState(() {
          _latestNfc = nfc;
        });
      }, onError: (Object err) {
        if (!mounted) return;
        print(err.toString());
      });
    }
    
  6. 构建UI

    [@override](/user/override)
    Widget build(BuildContext context) {
      return MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: const Text('NFC信息'),
          ),
          body: Column(
            children: [
              Text('运行于: $_platformVersion\n'),
              Text('收到的nfc: $_initialNfc'),
              Text('nfc流: $_latestNfc'),
            ],
          ),
          floatingActionButton: FloatingActionButton(
            child: Icon(Icons.nfc),
            onPressed: getInitialNfcInfo,
          ),
        ),
      );
    }
    

更多关于Flutter NFC信息读取插件nfc_info的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter NFC信息读取插件nfc_info的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用nfc_info插件来读取NFC信息的代码示例。这个插件允许你访问设备的NFC功能,读取NFC标签的信息。

首先,确保你已经在pubspec.yaml文件中添加了nfc_info依赖:

dependencies:
  flutter:
    sdk: flutter
  nfc_info: ^latest_version  # 请替换为实际的最新版本号

然后,运行flutter pub get来安装依赖。

接下来,你需要配置Android和iOS项目以支持NFC。

Android配置

android/app/src/main/AndroidManifest.xml中添加NFC权限:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yourapp">

    <uses-permission android:name="android.permission.NFC" />

    <application
        ... >
        <uses-library android:name="android.nfc" />
        <activity
            ... >
            <intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="text/plain" />
            </intent-filter>
            <meta-data
                android:name="android.nfc.action.TECH_LIST"
                android:resource="@xml/nfc_tech_filter" />
        </activity>
    </application>

</manifest>

android/app/src/main/res/xml/目录下创建一个名为nfc_tech_filter.xml的文件,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.NfcA</tech>
        <tech>android.nfc.tech.NfcB</tech>
        <tech>android.nfc.tech.NfcF</tech>
        <tech>android.nfc.tech.NfcV</tech>
        <tech>android.nfc.tech.IsoDep</tech>
        <tech>android.nfc.tech.MifareClassic</tech>
        <tech>android.nfc.tech.MifareUltralight</tech>
        <tech>android.nfc.tech.Ndef</tech>
        <tech>android.nfc.tech.NdefFormatable</tech>
    </tech-list>
</resources>

iOS配置

对于iOS,你需要确保在Info.plist中添加NFC权限描述。打开ios/Runner/Info.plist并添加以下键和值:

<key>NSNFCReaderUsageDescription</key>
<string>This app needs access to NFC to read tags.</string>

Flutter代码实现

接下来,在你的Dart代码中实现NFC读取功能。以下是一个简单的示例:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('NFC Reader'),
        ),
        body: NfcReaderScreen(),
      ),
    );
  }
}

class NfcReaderScreen extends StatefulWidget {
  @override
  _NfcReaderScreenState createState() => _NfcReaderScreenState();
}

class _NfcReaderScreenState extends State<NfcReaderScreen> {
  NfcInfo? _nfcInfo;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          ElevatedButton(
            onPressed: _startNfcSession,
            child: Text('Start NFC Session'),
          ),
          if (_nfcInfo != null)
            Text(
              'NFC Data: ${_nfcInfo!.ndefMessage.first.payloadAsString}',
              style: TextStyle(fontSize: 20),
            ),
        ],
      ),
    );
  }

  Future<void> _startNfcSession() async {
    NfcInfo nfcInfo = NfcInfo();

    nfcInfo.startSession().then((session) async {
      if (session == NfcSession.started) {
        NfcTag? tag = await nfcInfo.scanTag();
        if (tag != null) {
          setState(() {
            _nfcInfo = nfcInfo;
          });
        }
      }
      nfcInfo.endSession();
    }).catchError((error) {
      print('NFC Error: $error');
    });
  }
}

这个示例中,我们创建了一个简单的Flutter应用,其中包含一个按钮来启动NFC会话。当NFC标签被扫描时,将显示标签的数据。

请注意,实际开发中可能需要根据具体需求对代码进行调整,并处理更多的错误情况。此外,由于NFC功能的限制,测试时请确保在支持NFC的设备上进行。

回到顶部