问题描述
我正在开发一个应用程序,该应用程序可以检测附近的信标,以便用户记录特定的运动。我正在使用AltBeacon库来这样做。当我打开蓝牙后,它可以完美工作。
public void didRangeBeaconsInRegion(Collection<Beacon> beacons,Region region)
{
Logr.d(TAG,"didRangeBeaconsInRegion size:" + beacons.size());
for (Beacon b : beacons)
{
try
{
String json = (new Gson()).toJson(beaconIdList);
Logr.d(TAG,json,"");
if (b.getId1() == null)
{
continue;
}
if (b.getId2() == null)
{
continue;
}
if (b.getId3() == null)
{
continue;
}
String id1 = b.getId1().toString();
String id2 = b.getId2().toString();
String id3 = b.getId3().toString();
String finalId = id1 + ":" + id2 + ":" + id3;
Integer index = beaconIdList.indexOf(finalId);
if (index >= 0)
{
// index = -1 means that no match
Logr.d(TAG,"beacon matched: " + finalId,"");
}
else
{
Logr.d(TAG,"beacon unmatched: " + finalId + ":" + b.getdistance(),"");
}
}
catch(Exception ex)
{
}
}
}
}
在某些情况下,用户可能会关闭蓝牙。在这种情况下,我仍然想记录运动。参照此SO answer,可以在iOS上借助定位服务来完成此操作。
Android是否有可能?
任何建议都会有很大帮助。
解决方法
这个问题应该很容易回答。如果关闭了蓝牙无线电的电源,则它根本无法检测到外部蓝牙无线电信号,包括信标。该规则受物理学定律支配。
使答案变得更加复杂的是, Android和iOS玩的游戏都具有“蓝牙关闭”设置的真正含义。关闭并不是真的意味着关闭。为了使事情变得更复杂,此行为的方式因操作系统版本和平台而异。
通常,iOS和Android的较新版本具有两种不同的蓝牙设置:(1)通过从屏幕顶部向下滑动获得的快速面板设置,以及(2)通过转到“设置”获得的完整设置应用程序并深入研究蓝牙。
iOS 11 +
Beacon Detection
Setting iBeacon Others* Bluetooth Connections
----------------- ------ -------- ---------------------
Bluetooth On YES YES YES
Quick Setting Off YES NO NO
Full Setting Off NO NO NO
注意:*其他信标类型包括AltBeacon,Eddystone等。
装有Android 9+的像素/三星设备
Setting Beacon Detection Bluetooth Connections
----------------- ---------------- ---------------------
Bluetooth On YES YES
Quick Setting Off* YES NO
Full Setting Off NO NO
注意:* Android 9+版还具有“位置-> WiFi和蓝牙扫描”下的进一步设置:“即使关闭了蓝牙,也允许应用和服务随时扫描附近的设备。例如改善基于位置的功能和服务。”默认情况下启用此功能,但是如果将其关闭,则会使“快速设置”的行为类似于“完整设置”。
上表适用于Samsung和Pixel设备。不幸的是,Android零散的世界意味着任何OEM都可以自定义此行为。 如果您发现廉价的Android手机或旧版OS的行为有所不同,请不要感到惊讶。
最后应该指出的是,在Android和iOS上,信标检测都需要:
- 在设置中打开了位置
- 用户已将位置权限授予该应用