繁体   English   中英

Android BLE邻近通知

[英]Android BLE proximity notifications

我一直在开发一个与BLE设备交互的应用程序。 一切都很好,我可以扫描,连接和使用服务。

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

我知道我可以继续扫描这个,但电池使用率太高了,我希望即使我的应用程序没有被使用也可以调用它。

是不支持此功能还是我错过了讨论此内容的部分文档?

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

我知道我可以继续扫描这个,但电池使用率太高了,我希望即使我的应用程序没有被使用也可以调用它。

关于电池问题,一直使用蓝牙是耗电的,但同时你无法在没有蓝牙的情况下检测到BLE。

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

  1. 让线程运行打开蓝牙并以编程方式监听iBeacon并关闭(使用休眠时间)。 它可以通过多种方式完成。

  2. 使用名为Altbeacon的软件包,有许多有用的功能,其中一个功能是使用示例代码自动节省电池:

     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来检查信标范围和触发动作。 示例代码就像

@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项目总体上需要耐心。 正如另一个答案所提到的,也可以将此处的解决方案与Geofences和ActivityRecognition结合起来。

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

链接参考:

Android上的BLE扫描非常耗电,而且它绝对不是您想要在后台执行的操作。 如果您正在处理具有固定蓝牙设备(àlabebeons)的后台应用程序,您知道其位置,则可以使用Geofences在您认为距离设备大致接近时打开和关闭扫描。 如果你不小心地理围栏也可以耗尽电池。

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

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

您可能知道如何按服务UUID过滤扫描结果,所以我不会进入。 关于醒来:如果你的应用正在扫描,它的清晰度就是清醒。 它可能是也可能不是前景,但它是清醒的。

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

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


关于扫描:
扫描是电池密集型的。 甚至文档也这么说。

虽然强度是相对的。 与完全不扫描相比,这是非常密集的,但它不够密集,以至于它将无可救药地耗尽电池。 毕竟它被称为低能量

另一个答案建议监控Geofences,只有当您知道自己处于BLE设备范围内时才会进行扫描。 虽然这会降低ble扫描的电池消耗,但它需要为GPS提供电池电量,否则无法监控Geofences(好吧,它可以,使用蜂窝/ wifi数据,但它不会接近如准确)。


根据您的扫描时间如何关键的是(例如,如果附近有设备, 必须要知道它的时候了 ?或者是好的,如果它的延迟几秒钟?)可以实现暂停其间扫描。

假设您扫描5秒钟,暂停5秒钟,再次扫描5秒钟。 这样你几乎可以一直扫描,但只消耗大约一半的电池电量。 可以调整这些间隔以符合您的情况。 也许你可以通过扫描3秒钟并暂停10秒钟。(请注意, 设备广播之间的最长时间为10.24秒 )。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM