为什么 altbeacon 库只检测少量信标
Why altbeacon library only detect small number of beacons
我正在开发一个 android 应用程序并每 1 秒检测一次信标,我使用 altbeacon 库来实现该服务,我使用 200 个放在一边的信标测试了这个应用程序,但我的应用程序似乎只检测到40-80个beacon,没有近200个beacon,我想可能是beacon的广告间隔问题,所以我把所有beacon的间隔都调整为300ms,最后还是得到类似的结果(小于80),有谁知道吗它出了什么问题?
这里附上我的主要代码:
我首先使用布局初始化 beacommanager 并绑定服务:
private void initManager(){
beaconManager = BeaconManager.getInstanceForApplication(getActivity().getApplicationContext());
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:0-3=4c000215,i:4-19,i:20-21,i:22-23,p:24-24"));
beaconManager.setForegroundScanPeriod(1000);
beaconManager.setForegroundBetweenScanPeriod(0);
beaconManager.bind(this);
try {
if (beaconManager.isAnyConsumerBound()) {
beaconManager.updateScanPeriods();
}
} catch (RemoteException e) {
Log.e("RECO", "update scan periods error", e);
}
}
然后我从 onBeaconServiceConnect
获取结果并将其发送到主线程(我创建了一个 beacon 以启动 ranigng)
@Override
public void onBeaconServiceConnect() {
Log.d(TAG, "onBeaconServiceConnect called");
beaconManager.addRangeNotifier(new RangeNotifier() {
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
Log.i("RECORangingActivity", "didRangeBeaconsInRegion() region: " + region.getUniqueId() + ", number of beacons ranged: " + beacons.size());
// send bacon to main_activity to update UI
ArrayList<Beacon> scanedBeacon = new ArrayList<Beacon>(beacons);
// rank beacon by RSSI
Collections.sort(scanedBeacon, new Comparator<Beacon>() {
public int compare(Beacon one, Beacon other) {
return Integer.compare(other.getRssi(), one.getRssi());
}
});
Intent intent = new Intent(action);
intent.putParcelableArrayListExtra("RecoBeacon", scanedBeacon);
getActivity().sendBroadcast(intent);
}
});
}
最后,我创建了 startranging 和 stopranging 函数来控制它,并将 startranging 放入 onclicklistener 内的线程中;
private void startRanging(){
Log.d(TAG, "start Ranging beacons");
try {
beaconRegion = new Region("MyBeacons", Identifier.parse(RECO_UUID), null, null);
beaconManager.startMonitoringBeaconsInRegion(beaconRegion);
beaconManager.startRangingBeaconsInRegion(beaconRegion);
} catch (RemoteException e) {
e.printStackTrace();
}
}
private void stopRanging(){
Log.d(TAG, "stop Ranging beacons");
try {
beaconManager.stopMonitoringBeaconsInRegion(beaconRegion);
beaconManager.stopRangingBeaconsInRegion(beaconRegion);
} catch (RemoteException e) {
e.printStackTrace();
}
}
startBT.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startBT.setText("Running");
startBT.setEnabled(false);
Thread t1 = new Thread(){
@Override
public void run() {
startRanging();
}
};
t1.start();
}
})
检测结果如下:
08-21 06:33:51.373 10408-11779/com.example.haoch.groupsI/RECORangingActivity: didRangeBeaconsInRegion() region: MyBeacons, number of beacons ranged: 60
08-21 06:33:52.394 10408-11780/com.example.haoch.groupse I/RECORangingActivity: didRangeBeaconsInRegion() region: MyBeacons, number of beacons ranged: 49
08-21 06:33:53.416 10408-11781/com.example.haoch.groupse I/RECORangingActivity: didRangeBeaconsInRegion() region: MyBeacons, number of beacons ranged: 43
08-21 06:33:54.475 10408-11782/com.example.haoch.groupse I/RECORangingActivity: didRangeBeaconsInRegion() region: MyBeacons, number of beacons ranged: 58
08-21 06:33:55.515 10408-11783/com.example.haoch.groupse I/RECORangingActivity: didRangeBeaconsInRegion() region: MyBeacons, number of beacons ranged: 64
08-21 06:33:56.541 10408-11784/com.example.haoch.groupse I/RECORangingActivity: didRangeBeaconsInRegion() region: MyBeacons, number of beacons ranged: 64
08-21 06:33:57.566 10408-11785/com.example.haoch.groupse I/RECORangingActivity: didRangeBeaconsInRegion() region: MyBeacons, number of beacons ranged: 46
08-21 06:33:58.599 10408-11786/com.example.haoch.groupse I/RECORangingActivity: didRangeBeaconsInRegion() region: MyBeacons, number of beacons ranged: 68
08-21 06:33:59.637 10408-11788/com.example.haoch.groupse I/RECORangingActivity: didRangeBeaconsInRegion() region: MyBeacons, number of beacons ranged: 68
08-21 06:34:00.665 10408-11789/com.example.haoch.groupse I/RECORangingActivity: didRangeBeaconsInRegion() region: MyBeacons, number of beacons ranged: 72
显然,这是错误的检测结果,它应该检测到将近 200 个信标,但我只得到了很少的信标。
坏消息是 库可能不是限制你的地方。这是 phone 上的蓝牙堆栈。您可以同时成功扫描的信标数量主要取决于两个因素:
- 正在使用的 Android 设备型号的蓝牙堆栈(硬件、固件和操作系统软件)。
- 设备的CPU功率。
第一个因素几乎总是限制因素。第二个因素仅在信标回调中正在进行大量处理(或在库中打开调试日志记录)时才会发挥作用。
我对许多三星设备型号进行了 运行 测试,因为这些是市场上最常见的型号。 Galaxy S5 (Android 6) 的性能优于 S8 (Android 7) 或 S9 (Android 8)。我已经看到它在 5 分钟内检测到大约 350 个独特的信标传输,但并不是所有这些都在同一个测距周期内被检测到——通常少于 100 个。每个测距周期检测到一组不同的信标,但超过他们都这样做的时间。
一种设备型号与另一种设备型号之间存在很大差异,价格不是预测因素。 S8 和 S9 在单个周期内检测到的信标数量不到 S5 的一半。 Nexus 5X (Android 6) 简直糟透了,检测到的信标数量仅为 S5 的 10% 华为 P9 (Android 7) 的性能与三星 Galaxy S8 和 S9 相似。
要确认 phone 模型是关键因素,请尝试 运行 同时在几个不同的 phone 上使用完全相同的应用程序并计算有多少个信标你检测。您可能会发现设备型号之间存在很大差异。
我正在开发一个 android 应用程序并每 1 秒检测一次信标,我使用 altbeacon 库来实现该服务,我使用 200 个放在一边的信标测试了这个应用程序,但我的应用程序似乎只检测到40-80个beacon,没有近200个beacon,我想可能是beacon的广告间隔问题,所以我把所有beacon的间隔都调整为300ms,最后还是得到类似的结果(小于80),有谁知道吗它出了什么问题?
这里附上我的主要代码:
我首先使用布局初始化 beacommanager 并绑定服务:
private void initManager(){
beaconManager = BeaconManager.getInstanceForApplication(getActivity().getApplicationContext());
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:0-3=4c000215,i:4-19,i:20-21,i:22-23,p:24-24"));
beaconManager.setForegroundScanPeriod(1000);
beaconManager.setForegroundBetweenScanPeriod(0);
beaconManager.bind(this);
try {
if (beaconManager.isAnyConsumerBound()) {
beaconManager.updateScanPeriods();
}
} catch (RemoteException e) {
Log.e("RECO", "update scan periods error", e);
}
}
然后我从 onBeaconServiceConnect
获取结果并将其发送到主线程(我创建了一个 beacon 以启动 ranigng)
@Override
public void onBeaconServiceConnect() {
Log.d(TAG, "onBeaconServiceConnect called");
beaconManager.addRangeNotifier(new RangeNotifier() {
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
Log.i("RECORangingActivity", "didRangeBeaconsInRegion() region: " + region.getUniqueId() + ", number of beacons ranged: " + beacons.size());
// send bacon to main_activity to update UI
ArrayList<Beacon> scanedBeacon = new ArrayList<Beacon>(beacons);
// rank beacon by RSSI
Collections.sort(scanedBeacon, new Comparator<Beacon>() {
public int compare(Beacon one, Beacon other) {
return Integer.compare(other.getRssi(), one.getRssi());
}
});
Intent intent = new Intent(action);
intent.putParcelableArrayListExtra("RecoBeacon", scanedBeacon);
getActivity().sendBroadcast(intent);
}
});
}
最后,我创建了 startranging 和 stopranging 函数来控制它,并将 startranging 放入 onclicklistener 内的线程中;
private void startRanging(){
Log.d(TAG, "start Ranging beacons");
try {
beaconRegion = new Region("MyBeacons", Identifier.parse(RECO_UUID), null, null);
beaconManager.startMonitoringBeaconsInRegion(beaconRegion);
beaconManager.startRangingBeaconsInRegion(beaconRegion);
} catch (RemoteException e) {
e.printStackTrace();
}
}
private void stopRanging(){
Log.d(TAG, "stop Ranging beacons");
try {
beaconManager.stopMonitoringBeaconsInRegion(beaconRegion);
beaconManager.stopRangingBeaconsInRegion(beaconRegion);
} catch (RemoteException e) {
e.printStackTrace();
}
}
startBT.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startBT.setText("Running");
startBT.setEnabled(false);
Thread t1 = new Thread(){
@Override
public void run() {
startRanging();
}
};
t1.start();
}
})
检测结果如下:
08-21 06:33:51.373 10408-11779/com.example.haoch.groupsI/RECORangingActivity: didRangeBeaconsInRegion() region: MyBeacons, number of beacons ranged: 60
08-21 06:33:52.394 10408-11780/com.example.haoch.groupse I/RECORangingActivity: didRangeBeaconsInRegion() region: MyBeacons, number of beacons ranged: 49
08-21 06:33:53.416 10408-11781/com.example.haoch.groupse I/RECORangingActivity: didRangeBeaconsInRegion() region: MyBeacons, number of beacons ranged: 43
08-21 06:33:54.475 10408-11782/com.example.haoch.groupse I/RECORangingActivity: didRangeBeaconsInRegion() region: MyBeacons, number of beacons ranged: 58
08-21 06:33:55.515 10408-11783/com.example.haoch.groupse I/RECORangingActivity: didRangeBeaconsInRegion() region: MyBeacons, number of beacons ranged: 64
08-21 06:33:56.541 10408-11784/com.example.haoch.groupse I/RECORangingActivity: didRangeBeaconsInRegion() region: MyBeacons, number of beacons ranged: 64
08-21 06:33:57.566 10408-11785/com.example.haoch.groupse I/RECORangingActivity: didRangeBeaconsInRegion() region: MyBeacons, number of beacons ranged: 46
08-21 06:33:58.599 10408-11786/com.example.haoch.groupse I/RECORangingActivity: didRangeBeaconsInRegion() region: MyBeacons, number of beacons ranged: 68
08-21 06:33:59.637 10408-11788/com.example.haoch.groupse I/RECORangingActivity: didRangeBeaconsInRegion() region: MyBeacons, number of beacons ranged: 68
08-21 06:34:00.665 10408-11789/com.example.haoch.groupse I/RECORangingActivity: didRangeBeaconsInRegion() region: MyBeacons, number of beacons ranged: 72
显然,这是错误的检测结果,它应该检测到将近 200 个信标,但我只得到了很少的信标。
坏消息是 库可能不是限制你的地方。这是 phone 上的蓝牙堆栈。您可以同时成功扫描的信标数量主要取决于两个因素:
- 正在使用的 Android 设备型号的蓝牙堆栈(硬件、固件和操作系统软件)。
- 设备的CPU功率。 第一个因素几乎总是限制因素。第二个因素仅在信标回调中正在进行大量处理(或在库中打开调试日志记录)时才会发挥作用。
我对许多三星设备型号进行了 运行 测试,因为这些是市场上最常见的型号。 Galaxy S5 (Android 6) 的性能优于 S8 (Android 7) 或 S9 (Android 8)。我已经看到它在 5 分钟内检测到大约 350 个独特的信标传输,但并不是所有这些都在同一个测距周期内被检测到——通常少于 100 个。每个测距周期检测到一组不同的信标,但超过他们都这样做的时间。
一种设备型号与另一种设备型号之间存在很大差异,价格不是预测因素。 S8 和 S9 在单个周期内检测到的信标数量不到 S5 的一半。 Nexus 5X (Android 6) 简直糟透了,检测到的信标数量仅为 S5 的 10% 华为 P9 (Android 7) 的性能与三星 Galaxy S8 和 S9 相似。
要确认 phone 模型是关键因素,请尝试 运行 同时在几个不同的 phone 上使用完全相同的应用程序并计算有多少个信标你检测。您可能会发现设备型号之间存在很大差异。