Flutter蓝牙信标检测插件beacondart的使用

Flutter蓝牙信标检测插件beacondart的使用

简介

beacondart 是一个实现 Tezos 蓝牙信标协议(TZIP-10)的 Dart 库。该库通过 Flutter 的方法通道(method channels)将 Android 和 iOS 平台上的原生 SDK(如 beacon-android-sdkbeacon-ios-sdk)与 Dart 代码进行连接。

使用范围

该库专注于实现 Tezos 蓝牙信标的 钱包端 功能,允许用户通过蓝牙与 DApp(去中心化应用)进行交互。具体功能包括:

  • 连接到 DApp
    • QR Code 扫描
    • 复制粘贴
    • 深度链接
  • 监听来自 DApp 的消息
    • 权限请求/响应
    • 签名请求/响应
    • 操作请求/响应
    • 广播请求/响应

注意:该库本身不包含生成 QR Code 或深度链接的功能,需要开发者自行集成外部库来完成这些任务。

功能列表

连接到 DApp
// 可以通过 QR Code、复制粘贴或深度链接等方式连接到 DApp
监听消息
// 监听并处理来自 DApp 的各种请求

实现细节

beacondart 提供了一个 Dart 单例类 BeaconWalletClient,用于通过 Flutter 方法通道与 Android 和 iOS 原生 SDK 进行通信。

完整示例代码

以下是一个完整的示例代码,展示如何使用 beacondart 插件进行蓝牙信标检测。

import 'dart:convert';

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

import 'package:beacondart/beacondart.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  [@override](/user/override)
  void initState() {
    super.initState();
    initPlatformState();
  }

  // 初始化 Beacondart 客户端
  BeaconWalletClient bmw = BeaconWalletClient();

  Future<void> initPlatformState() async {
    // 初始化 Beacondart,传入应用名称、公钥和地址
    bool inited = await bmw.init(
      'Ejara',
      '9ae0875d510904b0b15d251d8def1f5f3353e9799841c0ed6d7ac718f04459a0',
      'tz1SkbBZg15BXPRkYCrSzhY6rq4tKGtpUSWv',
    );
    print("======================== Inited ===================================== $inited");
  }

  // 将 Base58 编码字符串解码为普通字符串
  String b58ToString(String b58String) {
    var b = base58CheckDecode(b58String);
    return utf8.decode(b);
  }

  // 将 Base64 编码字符串解码为 JSON 对象
  Map b64Decode(String b64) {
    return jsonDecode(utf8.decode(base64.decode(b64)));
  }

  final TextEditingController _controller = TextEditingController();
  bool isEmpty = false;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('BeaconDart 示例'),
        ),
        body: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 16),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              // 输入框用于输入 Base58 编码的字符串
              TextFormField(
                controller: _controller,
                maxLines: 7,
                decoration: InputDecoration(
                    border: const OutlineInputBorder(),
                    hintText: '请输入 Base58 编码的字符串',
                    errorText: isEmpty ? '请输入内容' : null),
                onChanged: (String value) {
                  if (value.isEmpty) {
                    setState(() {
                      isEmpty = true;
                    });
                  } else {
                    setState(() {
                      isEmpty = false;
                    });
                  }
                },
              ),
              ElevatedButton(
                onPressed: () async {
                  if (_controller.text.isNotEmpty) {
                    debugPrint(_controller.text);

                    // 解码输入的 Base58 字符串
                    String conn = b58ToString(_controller.text);
                    Map<String, String> dApp = Map<String, String>.from(jsonDecode(conn));

                    // 监听来自 DApp 的请求
                    await bmw.onBeaconRequest((response) async {
                      debugPrint('onBeaconRequest = $response');

                      // 根据请求类型发送响应
                      switch (response['type']) {
                        case "TezosPermission":
                          bmw.sendResponse({
                            "id": response["id"],
                            "status": true,
                          }, (args) {});
                          break;
                        case "TezosOperation":
                          bmw.sendResponse({
                            "id": response["id"],
                            "status": true,
                            "transactionHash": "wow",
                          }, (args) {});
                          break;
                        case "TezosSignPayload":
                          bmw.sendResponse({
                            "id": response["id"],
                            "status": true,
                            "signature": "wow",
                          }, (args) {});
                          break;
                        case "TezosBroadcast":
                          bmw.sendResponse({
                            "id": response["id"],
                            "status": true,
                            "transactionHash": "wow",
                          }, (args) {});
                          break;
                        default:
                      }
                    });

                    // 添加对等节点
                    await bmw.addPeer(dApp);

                    // 获取对等节点列表
                    await bmw.getPeers((response) {
                      debugPrint('getPeers = $response');
                    });

                    // 清空输入框
                    setState(() {
                      isEmpty = false;
                      _controller.text = '';
                    });
                  } else {
                    setState(() {
                      isEmpty = true;
                    });
                  }
                },
                child: const Text('连接 DApp'),
              )
            ],
          ),
        ),
      ),
    );
  }
}

更多关于Flutter蓝牙信标检测插件beacondart的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter蓝牙信标检测插件beacondart的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


beacondart 是一个用于在 Flutter 应用中检测蓝牙信标的插件。它基于 Android 和 iOS 平台的蓝牙信标检测功能,并提供了统一的 Dart API 供开发者使用。以下是如何使用 beacondart 插件的基本步骤:

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 beacondart 依赖:

dependencies:
  flutter:
    sdk: flutter
  beacondart: ^0.2.0

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

2. 配置权限

为了使用蓝牙功能,你需要在应用中请求相应的权限。

Android

AndroidManifest.xml 文件中添加以下权限:

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

iOS

Info.plist 文件中添加以下权限:

<key>NSLocationAlwaysUsageDescription</key>
<string>We need access to your location to detect beacons.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>We need access to your location to detect beacons.</string>
<key>NSBluetoothAlwaysUsageDescription</key>
<string>We need access to your Bluetooth to detect beacons.</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>We need access to your Bluetooth to detect beacons.</string>

3. 初始化 beacondart

在你的 Dart 代码中,首先导入 beacondart 包,然后初始化 BeaconScanner

import 'package:beacondart/beacondart.dart';

void initBeaconScanner() async {
  BeaconScanner beaconScanner = BeaconScanner();
  await beaconScanner.initialize();
}

4. 扫描信标

你可以使用 beaconScanner.startScan() 方法来开始扫描信标。扫描到的信标会通过 beaconScanner.beaconsStream 流发出。

void startScanning() {
  beaconScanner.beaconsStream.listen((List<Beacon> beacons) {
    for (var beacon in beacons) {
      print('Beacon detected: ${beacon.uuid}, Major: ${beacon.major}, Minor: ${beacon.minor}, Distance: ${beacon.distance}');
    }
  });

  beaconScanner.startScan();
}

5. 停止扫描

当你不再需要扫描信标时,可以调用 beaconScanner.stopScan() 来停止扫描。

void stopScanning() {
  beaconScanner.stopScan();
}

6. 处理信标数据

Beacon 类包含了信标的 UUID、Major、Minor 和距离等信息。你可以根据这些信息来处理信标数据。

class Beacon {
  String uuid;
  int major;
  int minor;
  double distance;
}

7. 示例代码

以下是一个完整的示例代码,展示了如何使用 beacondart 插件进行信标检测:

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

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: BeaconScannerScreen(),
    );
  }
}

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

class _BeaconScannerScreenState extends State<BeaconScannerScreen> {
  BeaconScanner beaconScanner = BeaconScanner();
  List<Beacon> beacons = [];

  [@override](/user/override)
  void initState() {
    super.initState();
    initBeaconScanner();
  }

  void initBeaconScanner() async {
    await beaconScanner.initialize();
    beaconScanner.beaconsStream.listen((List<Beacon> detectedBeacons) {
      setState(() {
        beacons = detectedBeacons;
      });
    });
    beaconScanner.startScan();
  }

  [@override](/user/override)
  void dispose() {
    beaconScanner.stopScan();
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Beacon Scanner'),
      ),
      body: ListView.builder(
        itemCount: beacons.length,
        itemBuilder: (context, index) {
          Beacon beacon = beacons[index];
          return ListTile(
            title: Text('UUID: ${beacon.uuid}'),
            subtitle: Text('Major: ${beacon.major}, Minor: ${beacon.minor}, Distance: ${beacon.distance}'),
          );
        },
      ),
    );
  }
}
回到顶部