Android BLE近距离通知

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

我一直在阅读所有的文档,我没有看到任何让开发者select收听BLE设备的选项。 基本上我想在设备进入BLE设备的范围时触发广播接收机。

我知道我可以不断地扫描这个,但电池使用太高,我希望这个被调用,即使当我的应用程序不被使用。

这个function是不支持的还是我错过了讨论这个文档的一部分?

Solutions Collecting From Web of "Android BLE近距离通知"

我最近做了一个项目,从我读到的问题来看,它和我所做的有些相似。

我知道我可以不断地扫描这个,但电池使用方式太高,我希望这个被调用即使当我的应用程序不被使用。

对于电池问题,一直有蓝牙功耗,但同时你无法检测到带蓝牙的BLE。

我所做的是两个实验,两者都是有用的,但不同,我不能说哪一个是最好的,但你需要testing它,以便它符合你的要求。

  1. 在线程运行后,打开蓝牙并收听iBeacon,然后以编程方式closures(睡眠时间)。 这可以通过很多方式来完成。

  2. 使用名为Altbeacon的软件包具有许多有用的function,其中一个function是自动电池保存,并带有示例代码 :

    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的距离,我build立一个基于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项目一般需要耐心。 如提到的其他答案,也可以将这里的解决scheme与Geofences和ActivityRecognition结合起来。

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

链接参考:

Android上的BLE扫描是相当耗电的,绝对不是你想要在后台一直做的事情。 如果您正在使用固定蓝牙设备(àla ibeacons)处理后台应用程序,并且您知道该设备的位置,则可以使用Geofences打开和closures扫描。 如果你不小心,geofencing也可以消耗电池。

如果你不知道你的蓝牙设备的位置,我猜你也可以玩ActivityRecognition技巧,也就是说,只有当用户正在行走时才定期扫描,如果用户静止/跑步/骑自行车/在车内停止。 再次,活动的认可的东西也需要电池,所以你将不得不谨慎。

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

您可能知道如何通过服务UUID过滤扫描结果,所以我不会进入。 关于醒来:如果你的应用程序正在扫描,它是清醒的定义。 它可能或可能不在前台,但它是清醒的。

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

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


关于扫描:
确实扫描是电池密集型的。 即使是文件也这么说。

强度是相对的。 这是相当密集的,而不是根本没有扫描,但它不够密集,将无可救药地耗尽你的电池。 毕竟它叫做低能量

另外一个答案build议监测地理栅栏,只有当你知道你在BLE设备范围内时才进行扫描。 虽然这样做会降低可疑扫描的电池消耗,但它需要为GPS提供电池电量,否则无法监视地理栅栏(可以用蜂窝/ wifi数据进行监视,但不会太近如同准确)。


根据您的扫描时间的关键时间(例如,如果附近有设备,您是否立即知道它或者是否延迟了几秒?),您可以在扫描之间实施暂停。

假设您扫描5秒钟,暂停5秒钟,再扫描5秒钟。 这样你几乎可以一直扫描,但只消耗大约一半的电池电量。 这些间隔可以调整以适应您的情况。 也许你可以扫描3秒,然后暂停10(注意, 设备广播之间的最大时间是10.24秒 )。

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

如果你有一个特定的BLE外围设备你要检测,然后找出其广告期。 如果你有不同的设备,find最长的广告时段。 扫描时间超过设备的广告时间,所以您至less得到一条广告信息。 定期以适合您使用情况的频率重复此扫描。 例如,您的外围设备每秒都会广告一次。 您想要在接近5秒内检测到设备。 然后扫描1秒(或更多)。 closures扫描4秒。 这样可以节省电池。