Android OnePlus6 无法使用 AltBeacon 库检测到 iBeacon
Android OnePlus6 can't detect iBeacon using AltBeacon library
我在 Android 应用程序中使用 AltBeacon 库检测 iBeacons
。我的代码适用于以下设备:
- 小米 9 (Android 10.0)
- 摩托罗拉 Moto G4 (Android 6.0.1)
- 华为P Smart (Android 8.0)
- 三星 Galaxy S8 (Android 9.0)
但是,相同的代码不适用于 OnePlus 6(Android 10、OxygenOS 10.3.2)。它没有在我的应用程序中检测到任何信标。我尝试使用其他有效的应用程序 (Locate) 检测信标。 AltBeacon 库的创建者告诉我 Locate 使用 AltBeacon 库,因此可以检测到信标。这意味着我的代码设置错误。你能帮我看看我的设置有什么问题吗?
我检查了(例如) 答案,尽管它没有解决我的问题。我为 BeaconManager 打开了调试功能,但没有发现任何有趣的东西(这个问题底部的一个例子)。
在ViewModel
我调用了MyStateManager
。它包含一个列表 regionsInRange
,其中包含范围内的信标。我遗漏了一些代码,因为我认为它是无关紧要的。如果大家觉得我漏掉的太多,我再补上。
public class MyStateManager implements BootstrapNotifier {
private static final MyStateManager instance = new MyStateManager();
private final MyBeaconHelper myBeaconHelper;
// ViewModel accessess this List to retrieve the beacons that are found.
public final List<Region> regionsInRange = new ArrayList<>();
private PresenceRegistrationStateManager() {
presenceRegistrationBeaconHelper = new PresenceRegistrationBeaconHelper(this);
updateScanningRegions();
}
@Override
public Context getApplicationContext() {
return MyApplication.getAppContext();
}
@Override
public void didEnterRegion(Region region) {
//Empty method
}
@Override
public void didExitRegion(Region region) {
//Empty method
}
@Override
public void didDetermineStateForRegion(int status, Region region) {
if (status == OUTSIDE) {
regionsInRange.remove(region);
} else {
if (!regionsInRange.contains(region)) {
regionsInRange.add(region);
}
}
updateState();
}
public static MyStateManager getInstance() {
return instance;
}
public void updateState() {
// Own implementation here
}
private void updateScanningRegions() {
// add all the regions here
}
}
此外,这是MyBeaconHelper
:
public class MyBeaconHelper implements BeaconConsumer, Serializable {
private transient final RegionBootstrap regionBootstrap;
private List<Region> scanRegions = new ArrayList<>();
public MyBeaconHelper(BootstrapNotifier bootstrapNotifier) {
BeaconManager beaconManager = BeaconManager.getInstanceForApplication(getApplicationContext());
beaconManager.getBeaconParsers().clear();
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
LogManager.setVerboseLoggingEnabled(true);
beaconManager.bind(this);
regionBootstrap = new RegionBootstrap(bootstrapNotifier, new ArrayList<>());
}
@Override
public void onBeaconServiceConnect() {
//Empty method
}
@Override
public Context getApplicationContext() {
return MyApplication.getAppContext();
}
@Override
public void unbindService(ServiceConnection serviceConnection) {
getApplicationContext().unbindService(serviceConnection);
}
@Override
public boolean bindService(Intent intent, ServiceConnection serviceConnection, int i) {
return getApplicationContext().bindService(intent, serviceConnection, i);
}
public void updateScanRegions(List<Region> newRegions) {
for (Region oldRegion : this.scanRegions) {
if (!newRegions.contains(oldRegion)) {
regionBootstrap.removeRegion(oldRegion);
}
}
for (Region newRegion : newRegions) {
if (!this.scanRegions.contains(newRegion)) {
regionBootstrap.addRegion(newRegion);
}
}
this.scanRegions = newRegions;
}
}
当我为 BeaconManager
打开调试时,它向我显示了很多次:
2020-03-31 11:57:30.181 25259-25259/com.my.app D/CycledLeScanner: starting a new scan cycle
2020-03-31 11:57:30.181 25259-25259/com.my.app D/CycledLeScanner: We are already scanning and have been for 1134 millis
2020-03-31 11:57:30.181 25259-25259/com.my.app D/CycledLeScanner: Waiting to stop scan cycle for another 1100 milliseconds
2020-03-31 11:57:30.181 25259-25259/com.my.app D/CycledLeScanner: Scan started
2020-03-31 11:57:31.213 25259-25259/com.my.app D/CycledLeScanner: Waiting to stop scan cycle for another 69 milliseconds
2020-03-31 11:57:31.323 25259-25259/com.my.app D/CycledLeScanner: Done with scan cycle
它一遍又一遍地打印这些行...
显示的日志消息(这些是针对 OnePlus 的,是吗?)表明 BLE 扫描已启动。您是否看到任何日志行显示检测到的数据包的十六进制字节?如果 BLE 扫描确实在运行,您应该。您可能想比较其他设备输出的日志。
您确定您的应用在 OnePlus 上获得了适当的位置权限吗?您可以在“设置”->“应用”->“您的应用”->“权限”中查看。还要确认蓝牙已打开并且全局 phone 设置的位置已打开(但如果定位在同一台设备上工作,这应该不是问题。)
不清楚这是否相关,但是beaconManager.bind()
和RegionBootstrap
同时使用是没有必要的,可能会引起冲突。代码似乎没有使用绑定方法回调的 BeaconConsumer
接口。我建议您删除绑定调用,使用 BeaconConsumer
并删除所有该接口的回调方法以确保安全。
我在 Android 应用程序中使用 AltBeacon 库检测 iBeacons
。我的代码适用于以下设备:
- 小米 9 (Android 10.0)
- 摩托罗拉 Moto G4 (Android 6.0.1)
- 华为P Smart (Android 8.0)
- 三星 Galaxy S8 (Android 9.0)
但是,相同的代码不适用于 OnePlus 6(Android 10、OxygenOS 10.3.2)。它没有在我的应用程序中检测到任何信标。我尝试使用其他有效的应用程序 (Locate) 检测信标。 AltBeacon 库的创建者告诉我 Locate 使用 AltBeacon 库,因此可以检测到信标。这意味着我的代码设置错误。你能帮我看看我的设置有什么问题吗?
我检查了(例如)
在ViewModel
我调用了MyStateManager
。它包含一个列表 regionsInRange
,其中包含范围内的信标。我遗漏了一些代码,因为我认为它是无关紧要的。如果大家觉得我漏掉的太多,我再补上。
public class MyStateManager implements BootstrapNotifier {
private static final MyStateManager instance = new MyStateManager();
private final MyBeaconHelper myBeaconHelper;
// ViewModel accessess this List to retrieve the beacons that are found.
public final List<Region> regionsInRange = new ArrayList<>();
private PresenceRegistrationStateManager() {
presenceRegistrationBeaconHelper = new PresenceRegistrationBeaconHelper(this);
updateScanningRegions();
}
@Override
public Context getApplicationContext() {
return MyApplication.getAppContext();
}
@Override
public void didEnterRegion(Region region) {
//Empty method
}
@Override
public void didExitRegion(Region region) {
//Empty method
}
@Override
public void didDetermineStateForRegion(int status, Region region) {
if (status == OUTSIDE) {
regionsInRange.remove(region);
} else {
if (!regionsInRange.contains(region)) {
regionsInRange.add(region);
}
}
updateState();
}
public static MyStateManager getInstance() {
return instance;
}
public void updateState() {
// Own implementation here
}
private void updateScanningRegions() {
// add all the regions here
}
}
此外,这是MyBeaconHelper
:
public class MyBeaconHelper implements BeaconConsumer, Serializable {
private transient final RegionBootstrap regionBootstrap;
private List<Region> scanRegions = new ArrayList<>();
public MyBeaconHelper(BootstrapNotifier bootstrapNotifier) {
BeaconManager beaconManager = BeaconManager.getInstanceForApplication(getApplicationContext());
beaconManager.getBeaconParsers().clear();
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
LogManager.setVerboseLoggingEnabled(true);
beaconManager.bind(this);
regionBootstrap = new RegionBootstrap(bootstrapNotifier, new ArrayList<>());
}
@Override
public void onBeaconServiceConnect() {
//Empty method
}
@Override
public Context getApplicationContext() {
return MyApplication.getAppContext();
}
@Override
public void unbindService(ServiceConnection serviceConnection) {
getApplicationContext().unbindService(serviceConnection);
}
@Override
public boolean bindService(Intent intent, ServiceConnection serviceConnection, int i) {
return getApplicationContext().bindService(intent, serviceConnection, i);
}
public void updateScanRegions(List<Region> newRegions) {
for (Region oldRegion : this.scanRegions) {
if (!newRegions.contains(oldRegion)) {
regionBootstrap.removeRegion(oldRegion);
}
}
for (Region newRegion : newRegions) {
if (!this.scanRegions.contains(newRegion)) {
regionBootstrap.addRegion(newRegion);
}
}
this.scanRegions = newRegions;
}
}
当我为 BeaconManager
打开调试时,它向我显示了很多次:
2020-03-31 11:57:30.181 25259-25259/com.my.app D/CycledLeScanner: starting a new scan cycle
2020-03-31 11:57:30.181 25259-25259/com.my.app D/CycledLeScanner: We are already scanning and have been for 1134 millis
2020-03-31 11:57:30.181 25259-25259/com.my.app D/CycledLeScanner: Waiting to stop scan cycle for another 1100 milliseconds
2020-03-31 11:57:30.181 25259-25259/com.my.app D/CycledLeScanner: Scan started
2020-03-31 11:57:31.213 25259-25259/com.my.app D/CycledLeScanner: Waiting to stop scan cycle for another 69 milliseconds
2020-03-31 11:57:31.323 25259-25259/com.my.app D/CycledLeScanner: Done with scan cycle
它一遍又一遍地打印这些行...
显示的日志消息(这些是针对 OnePlus 的,是吗?)表明 BLE 扫描已启动。您是否看到任何日志行显示检测到的数据包的十六进制字节?如果 BLE 扫描确实在运行,您应该。您可能想比较其他设备输出的日志。
您确定您的应用在 OnePlus 上获得了适当的位置权限吗?您可以在“设置”->“应用”->“您的应用”->“权限”中查看。还要确认蓝牙已打开并且全局 phone 设置的位置已打开(但如果定位在同一台设备上工作,这应该不是问题。)
不清楚这是否相关,但是beaconManager.bind()
和RegionBootstrap
同时使用是没有必要的,可能会引起冲突。代码似乎没有使用绑定方法回调的 BeaconConsumer
接口。我建议您删除绑定调用,使用 BeaconConsumer
并删除所有该接口的回调方法以确保安全。