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

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

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

是否不支持此功能,或者我是否缺少讨论此问题的文档部分?

最佳答案

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



关于电池问题,一直开着蓝牙很耗电,但与此同时,如果没有开着蓝牙,你就无法检测到 BLE。

我所做的是两个实验,它们都很有用但又不同,我不能说哪个最好,但是您需要对其进行测试以使其符合您的要求。

  • 运行 Thread,以编程方式打开蓝牙并收听 iBeacon 和关闭(有 sleep 时间)。它可以通过多种方式完成。
  • 使用一个名为 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);
        }
    }
    



  • 你的另一部分,它被称为在特定距离触发 Action 。
    我仍然使用 Altbeacon 来检查信标范围和触发 Action 。 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 结合起来。



    链接引用:
  • https://altbeacon.github.io/android-beacon-library/distance-triggering.html
  • https://altbeacon.github.io/android-beacon-library/samples.html
  • https://altbeacon.github.io/android-beacon-library/eddystone-how-to.html
  • https://github.com/AltBeacon/android-beacon-library-reference
  • 10-08 02:47