【问题标题】:Android BLE proximity notificationsAndroid BLE 近距离通知
【发布时间】:2017-12-08 03:39:16
【问题描述】:

我一直致力于开发与 BLE 设备交互的应用程序。一切正常,我可以扫描、连接和使用服务。

我一直在阅读所有文档,但没有看到任何让开发人员可以选择监听 BLE 设备的内容。基本上我想在设备进入 BLE 设备范围时触发广播接收器。

我知道我可以不断地扫描它,但是电池使用量太高了,我希望即使在我的应用程序没有被使用时也能调用它。

是否不支持此功能,或者我错过了讨论此功能的文档部分?

【问题讨论】:

  • 我的印象是您目前必须想出自己的扫描策略(考虑计时器、其他触发器等),但如果您发现任何内置的东西会很有趣。
  • 您是否考虑过使用现有的 SDK 在 android 上使用 BLE?就像 Estimote 或 Radiusnetwork 提供的一样。
  • 您现在在项目中用于 BLE 的库的名称是什么?
  • 我们还没有使用任何库,如果他们只是以更智能的时间进行扫描,我们也不愿意使用它们。 (他们不就是这样做的吗?)想到了android系统提供的一些节能的东西。最好的方案是在 AndroidManifest 中添加 Service UUID,一旦具有此 Service UUID 的设备到达,它就会触发 BroadcastReceiver。如果这种方法不起作用,我们将开发自己的智能定时来触发扫描,因为我们开发了自行车速度和踏频 (CSC) 传感器。我们可以使用 Google Play 服务提供的用户(骑自行车、跑步……)活动。
  • 我从事过使用后台服务的项目,该服务以睡眠间隔监听 ibeacons 活动,睡眠时间是关键。我使用一个有信标监听器的库,我可以提供我的解决方案,但我也可以确定我所说的是你可以使用的东西。你最终可以给我发电子邮件(在我的个人资料中找到我的电子邮件),这样我就能更快地回复

标签: java android bluetooth-lowenergy android-bluetooth


【解决方案1】:

我最近做了一个项目,从我在你的问题中读到的内容与我所做的有些相似。

我知道我可以持续扫描它,但电池使用量太高了,我希望即使在我的应用程序没有被使用时也能调用它。

关于电池问题,一直开蓝牙是很耗电的,但同时不开蓝牙也检测不到BLE。

我做的是两个实验,两个都很有用,但又不同,我不能说哪一个最好,但你需要测试它以符合你的要求。

  1. 让 Thread 以编程方式打开蓝牙并监听 iBeacon 和关闭(有睡眠时间)。它可以通过多种方式完成。

  2. 使用一个名为 Altbeacon 的包,它有很多有用的功能,其中一个功能是使用 example code 自动省电:

    public class MyApplication extends Application implements BootstrapNotifier {
        private BackgroundPowerSaver backgroundPowerSaver;
    
        public void onCreate() {
            super.onCreate();
            // Simply constructing this class and holding a reference to it
            // in your custom Application class
            // enables auto battery saving of about 60%
            backgroundPowerSaver = new BackgroundPowerSaver(this);
        }
    }
    

我们需要一个广播事件,它会在具有特定 Service-UUID 的 BLE 设备到达时唤醒我们的应用程序。也许现在有比 2 年前更好的 BLE API 可用。最节能最精准的方法获得奖励。

你的另一部分,叫做在特定距离触发动作。 我仍然使用 Altbeacon 来检查信标范围和触发动作。 sample code 类似于

@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
    for (Beacon beacon : beacons) {
        if (beacon.getDistance() < 5.0) {
            Log.d(TAG, "I see a beacon that is less than 5 meters away.");
            // Perform distance-specific action here
        }
    }
}

也就是说,你还可以获取特定 UUID 的距离我构建了一个基于 Altbeacon 的方法,如下所示(查看 for 循环和 if 语句内部):

private void startRangeNotifier() {
    Log.i(TAG, "Starting range notifier...");
    beaconManager.setRangeNotifier(new BeaconRangeListener() {
        @Override
        public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {

            if (beacons.size() > 0) {
                for (Beacon beacon : beacons) {
                    Log.d(TAG, "uuid's: " + beacon);
                    Log.d(TAG, "uuid id1: " + beacon.getId1());
                    if (beacon.getId1().toString()
                            .equals("b9407f30-f5f8-466e-aff9-25556b57fe6d")) {
                        Log.d(TAG, "uuid id1 distance: " + beacon.getDistance());
                    }
                }

            }
        }
    });

    try {
        beaconManager.startRangingBeaconsInRegion(
                new Region(BEACON_MONITORING_ID, null, null, null));
    } catch (RemoteException e) {
        e.printStackTrace();
    }
}

我的日志输出:

D/Main activity:: uuid's: id1: b9407f30-f5f8-466e-aff9-25556b57fe6d id2: 31807 id3: 59251
D/Main activity:: uuid id1: b9407f30-f5f8-466e-aff9-25556b57fe6d
D/Main activity:: uuid id1 distance: 0.2108658568686884

在我的回答中,我想介绍我使用的概念,Beacons 项目通常需要耐心。正如另一个答案所提到的,也可以将此处的解决方案与地理围栏和 ActivityRecognition 结合起来。

注意:由于蓝牙信标的性质,距离是接近而不是绝对的,有时甚至蓝牙信标是 1 米,它可能显示 2 米或 0.5 米,所以请记住这一点

链接参考:

【讨论】:

  • 感谢您指向活跃的开发库“altbeacon”,它最适合目前开始使用 BLE 的开发人员。对于我们的用例,我认为将此库的使用与 ActivityRecognition 结合起来并没有多大好处。不过,我们可能会看看他们如何进行智能扫描。
  • 没问题,欢迎您,希望您在项目中取得进展
【解决方案2】:

Android 上的 BLE 扫描非常耗电,而且绝对不是您想一直在后台执行的操作。如果您正在使用您知道其位置的固定蓝牙设备(à la ibeacons)处理后台应用程序,您可以使用Geofences 在您认为自己接近设备时打开和关闭扫描。如果您不小心,地理围栏也会耗尽电池电量。

如果你不知道你的蓝牙设备的位置,我猜你也可以用ActivityRecognition 玩技巧,即只在用户走路时定期扫描,如果用户静止/跑步/骑自行车/在停止它车辆。同样,活动识别的东西也需要电池,所以你必须谨慎。

【讨论】:

  • 我们认为 ActivityRecognition 的电池消耗更少,并且可以使用 Manifest 中的 BroadcastReceiver 接收其广播事件。目标是让应用程序终止并在用户活动事件中唤醒它。
  • 电池消耗肯定更少。不过,请确保您仍然对电池消耗进行基准测试。
  • 是否必须唤醒并请求它,或者用户的活动是否使用清单中注册的接收器唤醒我的应用程序?
  • 赏金,因为该解决方案最符合我们的要求,并且由于明确声明,使用 ActivityRecognition 可以减少电池消耗。
【解决方案3】:

我们需要一个广播事件,它会在具有特定 Service-UUID 的 BLE 设备到达时唤醒我们的应用程序。

您可能知道如何按服务 UUID 过滤扫描结果,所以我不会深入讨论。关于唤醒:如果您的应用程序正在扫描,则根据定义它是唤醒的。它可能在前台,也可能不在前台,但它是醒着的。

也许现在有比 2 年前更好的 BLE API 可用。

从 SDK 版本 21 开始,有一个新的 API 可用于 BLE 扫描。据我所知,唯一的区别是您访问 API 的方式和底层功能(关于功耗等)没有改变。


关于扫描:
确实,扫描是耗电的。连docs都这么说。

强度是相对的。与根本不扫描相比,它是密集的,但它不够密集,以至于它会无可救药地耗尽你的电池。毕竟叫低能。

另一个答案建议监控地理围栏,并且仅在您知道自己处于 BLE 设备范围内时才进行扫描。虽然这会降低 ble 扫描 的电池消耗,但 GPS 需要电池电量,否则它无法监控地理围栏(嗯,它可以使用蜂窝/wifi 数据,但是那么它就不会那么准确了)。


取决于您扫描的时间紧迫性(例如,如果附近有设备,必须您立即知道它?或者如果它延迟了几次也没关系秒?)您可以在扫描之间实现暂停。

假设您扫描 5 秒,暂停 5 秒,再次扫描 5 秒。这样您将几乎一直在扫描,但只消耗大约一半的电池电量。可以调整这些间隔以匹配您的情况。也许您可以扫描 3 秒并暂停 10 秒。(注意 the maximum time between a device's broadcasts is 10.24 seconds)。

我有一个有大约 50 名用户的应用程序,它在后台 24/7 以这样的暂停(扫描 3 秒,暂停 3 秒,重复)进行扫描,并且没有收到任何关于电池过度使用的投诉。

【讨论】:

  • 感谢您明确表示在功耗方面没有太大改善!太糟糕了,我不能分享赏金......
  • @OneWorld 没关系。很高兴分享我花了很长时间才收集到的信息
【解决方案4】:

如果您想要检测特定的 BLE 外围设备,请确定其广告周期。如果您有不同的设备,请找出最长的广告周期。扫描时间长于设备的广告周期,因此您至少会收到一条广告消息。以适合您的用例的频率定期重复此扫描。例如。您的外围设备每秒广告一次。当涉及到接近时,您希望在 5 秒内检测到设备。然后扫描 1 秒(或更多)。关闭扫描4s。这样可以节省电池。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-31
    • 2023-03-26
    • 1970-01-01
    • 2015-01-20
    • 1970-01-01
    • 2011-12-16
    相关资源
    最近更新 更多