信标

Flutter插件 用于处理信标。
支持 Android API 16+ 和 iOS 8+。

功能

  • 自动权限管理
  • 测距
  • 监控(包括后台)

支持的信标规格

  • iBeacon (iOS & Android)
  • Altbeacon (Android)

安装

添加到 pubspec.yaml

dependencies:
  beacons: ^0.3.0

注意: 该插件是用 Swift 编写的,用于 iOS。
在集成 Swift 插件到使用 Objective-C 模板的 Flutter 项目中存在一个已知问题。请遵循 Flutter#16049 的说明来解决该问题(Cocoapods 1.5+ 是强制要求的)。

Android 特定设置

创建一个 FlutterApplication 的子类

class App : FlutterApplication() {

    override fun onCreate() {
        super.onCreate()

        // Beacons setup for Android
        BeaconsPlugin.init(this, object : BeaconsPlugin.BackgroundMonitoringCallback {
            override fun onBackgroundMonitoringEvent(event: BackgroundMonitoringEvent): Boolean {
                val intent = Intent(this@App, MainActivity::class.java)
                startActivity(intent)
                return true
            }
        })
    }
}

并在 android/app/src/main/AndroidManifest.xml 中注册它

<manifest ...>
  ...
  <application
    android:name=".App"
    android:label="beacons_example"
    android:icon="@mipmap/ic_launcher">
    ...
  </application>
</manifest>

BeaconsPlugin.BackgroundMonitoringCallback 是响应后台监控事件所必需的。当应用程序在后台运行时检测到监控事件时,将执行该回调。在上面的代码片段中,它将启动 Flutter 应用程序。它还将允许在 Flutter 端接收回调。有关更多详细信息,请参阅后台监控部分。

有关权限,请参阅下文。

iOS 特定设置

无。与普遍看法相反,您无需启用任何后台模式。

有关权限,请参阅下文。

Permission

为了使用与信标相关的特性,应用程序需要请求位置权限。这是一个分两步的过程:

  1. 在配置文件中声明应用程序所需的权限
  2. 在应用程序运行时请求用户授权(插件可以自动处理此问题)

对于 iOS

iOS 中有两种可用权限:使用中始终
后者是后台监控所必需的。

有关每种权限可执行的操作的更多详细信息,请参阅:
https://developer.apple.com/documentation/corelocation/choosing_the_authorization_level_for_location_services

权限必须在 ios/Runner/Info.plist 中声明

<dict>
  <!-- When in use -->
  <key>NSLocationWhenInUseUsageDescription</key>
  <string>Reason why app needs location</string>

  <!-- Always -->
  <!-- for iOS 11 + -->
  <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
  <string>Reason why app needs location</string>
  <!-- for iOS 9/10 -->
  <key>NSLocationAlwaysUsageDescription</key>
  <string>Reason why app needs location</string>
  ...
</dict>

对于 Android

Android 中有两种可用权限:coarsefine
对于与信标相关的特性,这两种权限之间没有区别。

权限必须在 android/app/src/main/AndroidManifest.xml 中声明

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  <!-- or -->
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>

操作指南

测距和监控 API 被设计为响应式流。

  • 第一次订阅流将开始测距/监控;
  • 最后一次取消订阅(当没有更多订阅时)流将停止测距/监控操作。

测距信标

Beacons.ranging(
  region: new BeaconRegionIBeacon(
    identifier: 'test',
    proximityUUID: '7da11b71-6f6a-4b6d-81c0-8abd031e6113',
  ),
  inBackground: false, // continue the ranging operation in background or not, see below
).listen((result) {
  // result contains a list of beacons
  // list can be empty if no matching beacons were found in range
}

后台测距

当关闭时,测距将在应用程序进入后台时自动暂停,并在应用程序返回前台时恢复。否则,它将积极地在后台继续运行,直到应用程序被操作系统终止。

操作系统不支持在应用程序已终止时测距信标。对于此类用法,请参阅后台监控。

监控信标

Beacons.monitoring(
  region: new BeaconRegionIBeacon(
    identifier: 'test',
    proximityUUID: '7da11b71-6f6a-4b6d-81c0-8abd031e6113',
  ),
  inBackground: false, // continue the monitoring operation in background or not, see below
).listen((result) {
  // result contains the new monitoring state:
  // - enter
  // - exit
}

后台监控

当关闭时,监控将在应用程序进入后台时自动暂停,并在应用程序返回前台时恢复。否则,它将积极地在后台继续运行,直到应用程序被操作系统终止。

一旦应用程序被终止,监控将继续。
如果发生监控事件,操作系统将会在后台启动应用程序几秒钟(用户不会看到任何内容)。操作系统会为您提供执行一些快速操作的机会,例如显示本地通知。

为了监听后台监控事件,您可以订阅一个特殊的流。这个流是被动的:它不会启动监控操作。您仍然需要使用 Beacons.monitoring(inBackground: true) 来启动它。

由于操作系统只会为后台应用程序运行几秒钟,然后将其终止,因此设置监听器的最佳位置是在应用程序启动时。

class MyApp extends StatefulWidget {
  MyApp() {
    Beacons.backgroundMonitoringEvents().listen((event) {
      final BackgroundMonitoringEventType type = event.type // didEnterRegion, didExitRegion or didDetermineState
      final BeaconRegion region = event.region // The monitored region associated to the event
      final MonitoringState state = event.state // useful for type = didDetermineState

      // do something quick here to react to the background monitoring event, like showing a notification
    });
  }

  @override
  _MyAppState createState() => new _MyAppState();
}

要测试后台监控以及您应该期望的结果,请阅读:
https://developer.radiusnetworks.com/2013/11/13/ibeacon-monitoring-in-the-background-and-foreground.html

除了使用 Beacons.monitoring() 流订阅来启动/停止监控外,您还可以使用以下命令式 API:

// Result will be successful if monitoring has started, or contain the reason why it has not (permission denied, etc)
final BeaconsResult result = await Beacons.startMonitoring(
  region: BeaconRegionIBeacon(
    identifier: 'test',
    proximityUUID: 'uuid',
  ),
  inBackground: true,
);

await Beacons.stopMonitoring(
  region: BeaconRegionIBeacon(
    identifier: 'test',
    proximityUUID: 'uuid',
  ),
);

请注意,这些函数只能启动/停止监控。
要接收相关的监控事件,请监听 Beacons.backgroundMonitoringEvents() 流。

信标类型

对于需要或返回区域或信标的每个 API,您都可以使用不同类型的信标规格。

无论信标规格如何,每个区域都需要一个唯一的标识符,底层引擎使用该标识符来唯一地标识和管理测距/监控请求。

通用

Beacons.ranging(region: BeaconRegion(
    identifier: 'test',
    ids: ['id1', 'id2', 'id3'],
  ),
).listen((result) {
  final Beacon beacon = result.beacons.first;
});

iBeacon

Beacons.ranging(region: BeaconRegionIBeacon(
    identifier: 'test',
    proximityUUID: 'some-uuid',
    major:0,
    minor: 0,
  ),
).listen((result) {
  final BeaconIBeacon beacon = BeaconIBeacon.from(result.beacons.first);
});

底层

每种技术都有其独特性。
该插件尽最大努力进行抽象并公开通用逻辑,但对于高级用法,您可能仍然需要熟悉原生技术。

信标插件的开发由 Pointz 赞助,该公司是一家奖励人们在当地实体店消费的公司。Pointz 总部位于阿拉巴马州伯明翰。

作者

信标插件由 Loup 开发,这是一家位于蒙特利尔和巴黎的移动开发工作室。
您可以通过 [email protected] 联系我们。

GitHub

https://github.com/loup-v/beacons