OnyxBeacon 的 AltBeacon 不稳定,反复循环通过 didEnterRegion 和 didExitRegion
Posted
技术标签:
【中文标题】OnyxBeacon 的 AltBeacon 不稳定,反复循环通过 didEnterRegion 和 didExitRegion【英文标题】:AltBeacon unstable for OnyxBeacons, cycling through didEnterRegion and didExitRegion repeatedly 【发布时间】:2015-12-11 08:06:57 【问题描述】:我正在使用 AltBeacon 库构建应用程序以支持 Onyx Beacons (Beacon One) 和 Gimbal Beacons (Series 21)
我的测试设备是配备 android 4.4.4 KitKat 和 Onyx Beacon 的 Nexus 7 2013。信标就在我的设备旁边不到一米的地方,我没有移动它。检测到信标并转到didEnterRegion
,然后在大约一分钟后转到didExitRegion
,然后循环重复。
我们还在使用不同 (Onyx) 信标的不同设备(三星手机)上对此进行了测试。问题仍然存在。请注意,这只发生在 Onyx Beacons (Beacon One) 上。 Gimbal Beacons (Series 21) 仅在范围内触发一次。
我是否使用了正确的 Beacon Parser 字符串?我是否正确执行此操作?我真的没有想法,我想支持这两个信标。
基础应用程序
public class BaseApplication extends Application
@Override
public void onCreate()
super.onCreate();
startService(new Intent(this, BeaconMonitoringService.class));
BeaconMonitoringService
public class BeaconMonitoringService extends Service implements BeaconConsumer
private Context context;
private BeaconService service;
private BeaconManager beaconManager;
private NotificationCompat.Builder notifBuilder;
@Override
public void onCreate()
super.onCreate();
context = getBaseContext();
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.setBackgroundMode(true);
beaconManager.setBackgroundScanPeriod(1100l);
beaconManager.setBackgroundBetweenScanPeriod(15000l);
String[] beaconParsers = new String[] "m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24", "m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25", "m:2-3=0203,i:14-19l,d:10-13,p:9-9" ;
for(String beacon : beaconParsers)
Log.i("BeaconService","layout: "+beacon);
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(beacon));
beaconManager.bind(this);
@Override
public void onBeaconServiceConnect()
beaconManager.setMonitorNotifier(new MonitorNotifier()
private String log;
@Override
public void didEnterRegion(Region region)
Beacon beacon = service.getBeacon(region.getId1().toString(), region.getId2().toString(), region.getId3().toString());
log = "I just saw a beacon for the first time! "+region.getId1()+" "+region.getId2()+" "+region.getId3();
Log.i("BeaconService", log);
sendNotification(beacon);
@Override
public void didExitRegion(Region region)
Beacon beacon = service.getBeacon(region.getId1().toString(), region.getId2().toString(), region.getId3().toString());
log = "I no longer see a beacon";
Log.i("BeaconService", log);
@Override
public void didDetermineStateForRegion(int state, Region region)
);
List<BackendRegion> regionList = Util.getRegionList();
for(BackendRegion region : regionList)
ArrayList<Beacon> beaconList = region.getBeacons();
for(Beacon beacon : beaconList)
try
String beaconString = region.getUuid().toLowerCase() + " " + beacon.getMajor() + " " + beacon.getMinor();
service.addBeacon(beacon);
beaconManager.startMonitoringBeaconsInRegion(new Region(beacon.getIdentifier(), Identifier.parse(region.getUuid()),Identifier.parse(beacon.getMajor()),Identifier.parse(beacon.getMinor())));
catch (RemoteException e)
@Override
public IBinder onBind(Intent intent)
return null;
@Override
public void onDestroy()
beaconManager.unbind(this);
super.onDestroy();
private void sendNotification(Beacon beacon, InteractiveImage interactiveImage)
this.notifBuilder = new NotificationCompat.Builder(this)
.setAutoCancel(true)
.setContentTitle("Sample Beacon")
.setContentText("A beacon was detected")
.setSmallIcon(R.drawable.ic_launcher);
Intent notifyIntent = new Intent(this, NotificationActivity.class);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notifyIntent, 0);
notifBuilder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(Integer.parseInt(beacon.getId()), notifBuilder.build());
日志
12-11 15:45:24.103 I/BeaconService: I just saw a beacon for the first time! 20cae8a0-a9cf-11e3-a5e2-0800200c9a66 7 44512
12-11 15:45:24.784 D/BluetoothAdapter: stopLeScan()
12-11 15:45:39.698 D/BluetoothAdapter: startLeScan(): null
12-11 15:45:39.709 D/BluetoothAdapter: onClientRegistered() - status=0 clientIf=5
12-11 15:45:40.830 D/BluetoothAdapter: stopLeScan()
12-11 15:45:55.794 D/BluetoothAdapter: startLeScan(): null
12-11 15:45:55.804 D/BluetoothAdapter: onClientRegistered() - status=0 clientIf=5
12-11 15:45:56.985 D/BluetoothAdapter: stopLeScan()
12-11 15:46:11.920 D/BluetoothAdapter: startLeScan(): null
12-11 15:46:11.950 D/BluetoothAdapter: onClientRegistered() - status=0 clientIf=5
12-11 15:46:13.091 D/BluetoothAdapter: stopLeScan()
12-11 15:46:27.996 D/BluetoothAdapter: startLeScan(): null
12-11 15:46:28.016 D/BluetoothAdapter: onClientRegistered() - status=0 clientIf=5
12-11 15:46:29.147 D/BluetoothAdapter: stopLeScan()
12-11 15:46:29.227 I/BeaconService: I no longer see a beacon
12-11 15:46:44.121 D/BluetoothAdapter: startLeScan(): null
12-11 15:46:44.141 D/BluetoothAdapter: onClientRegistered() - status=0 clientIf=5
12-11 15:46:44.402 I/BeaconService: I just saw a beacon for the first time! 20cae8a0-a9cf-11e3-a5e2-0800200c9a66 7 44512
12-11 15:46:45.282 D/BluetoothAdapter: stopLeScan()
12-11 15:47:00.197 D/BluetoothAdapter: startLeScan(): null
12-11 15:47:00.197 D/BluetoothAdapter: onClientRegistered() - status=0 clientIf=5
12-11 15:47:01.328 D/BluetoothAdapter: stopLeScan()
12-11 15:47:16.343 D/BluetoothAdapter: startLeScan(): null
12-11 15:47:16.363 D/BluetoothAdapter: onClientRegistered() - status=0 clientIf=5
12-11 15:47:17.514 D/BluetoothAdapter: stopLeScan()
12-11 15:47:32.418 D/BluetoothAdapter: startLeScan(): null
12-11 15:47:32.428 D/BluetoothAdapter: onClientRegistered() - status=0 clientIf=5
12-11 15:47:33.540 D/BluetoothAdapter: stopLeScan()
12-11 15:47:48.494 D/BluetoothAdapter: startLeScan(): null
12-11 15:47:48.504 D/BluetoothAdapter: onClientRegistered() - status=0 clientIf=5
12-11 15:47:49.635 D/BluetoothAdapter: stopLeScan()
12-11 15:48:04.620 D/BluetoothAdapter: startLeScan(): null
12-11 15:48:04.630 D/BluetoothAdapter: onClientRegistered() - status=0 clientIf=5
12-11 15:48:05.771 D/BluetoothAdapter: stopLeScan()
12-11 15:48:20.706 D/BluetoothAdapter: startLeScan(): null
12-11 15:48:20.706 D/BluetoothAdapter: onClientRegistered() - status=0 clientIf=5
12-11 15:48:21.827 D/BluetoothAdapter: stopLeScan()
12-11 15:48:36.821 D/BluetoothAdapter: startLeScan(): null
12-11 15:48:36.831 D/BluetoothAdapter: onClientRegistered() - status=0 clientIf=5
12-11 15:48:37.962 D/BluetoothAdapter: stopLeScan()
12-11 15:48:52.917 D/BluetoothAdapter: startLeScan(): null
12-11 15:48:52.927 D/BluetoothAdapter: onClientRegistered() - status=0 clientIf=5
12-11 15:48:54.058 D/BluetoothAdapter: stopLeScan()
12-11 15:49:09.003 D/BluetoothAdapter: startLeScan(): null
12-11 15:49:09.003 D/BluetoothAdapter: onClientRegistered() - status=0 clientIf=5
12-11 15:49:10.154 D/BluetoothAdapter: stopLeScan()
12-11 15:49:10.214 I/BeaconService: I no longer see a beacon
【问题讨论】:
【参考方案1】:一些提示:
检查 Onyx Beacon One 的广告速率。 为获得最佳效果,信标应以标准 10Hz 进行广告。一些制造商放慢这种广告速度以节省电池寿命。如果您有一个以 1Hz 或更低频率进行广告的信标,则信标扫描仪可能会开始定期错过它。 (由于蓝牙无线电噪声,无法检测到 100% 的数据包。)
如果您发现广告频率为 1 Hz 或更低,请尽可能提高广告频率,问题应该会消失。
如果您无法提高信标的广告速率,您可以减慢Android Beacon Library的扫描速度,使其有更多时间收集信标数据包。默认情况下,它使用 1.1 秒的扫描周期。您可以使用如下所示的一行代码将其减慢到 5 秒。对于不经常做广告的信标,这将更可靠地工作,但也会使您对区域进入/退出的响应时间变慢。 beaconManager.setForegroundScanPeriod(5000l);
【讨论】:
我也应该更改setBackgroundScanPeriod
吗?
默认的后台扫描周期已经更长,但您可以将其增加到 60000l 以更加确定您会检测到信标。
尽管我想接受这个作为答案,但我尝试降低扫描速度,但问题仍然存在
你知道beacon的广告费率吗?您将扫描速度降低到什么程度?
信标频率为 1000 毫秒,相当于 1Hz 我使用了beaconManager.setForegroundScanPeriod(50001);
5000l
上的最后一个数字真的是 L 吗?我用的是 1。以上是关于OnyxBeacon 的 AltBeacon 不稳定,反复循环通过 didEnterRegion 和 didExitRegion的主要内容,如果未能解决你的问题,请参考以下文章
AltBeacon:didExitRegion 和 didEnterRegion 交替
使用 AltBeacon 库以 CoreBluetooth 格式做广告