使用 AltBeacon:从应用程序设置开始和停止扫描
Using AltBeacon: start and stop scanning from app settings
我正在将 AltBeacon API 集成到现有应用程序中。当用户进入或离开 "bluetooth zone".
时,应用程序应在 后台 中启动操作
此功能应该是可选的,用户应该从设置开始和停止扫描。
我尝试了 bind/unbind BeaconConsumer,但我看到,在后台 BluetoothLeScanner 一直在扫描!如何阻止 BluetoothLeScanner 扫描?这是正确的方法吗?
代码如下:
@Override
public void onCreate() {
super.onCreate();
LogManager.setVerboseLoggingEnabled(true);
log.debug("onCreate");
mAllBeaconsRegion = new Region(ALLBEACONS, null, null, null);
mBeaconManager = BeaconManager.getInstanceForApplication(this);
mBackgroundPowerSaver = new BackgroundPowerSaver(this);
mBeaconManager.setBackgroundBetweenScanPeriod(60000L);
mBeaconManager.setBackgroundScanPeriod(2100L);
// wake up the app when a beacon is seen
mRegionBootstrap = new RegionBootstrap(this, mAllBeaconsRegion);
mBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
dsGlobal = new DbGlobalsHelper(getApplicationContext());
boolean isBeaconScan = Utils.isBoolean(dsGlobal.getCursorGlobalsByKey(Constants.DB_KEY_BEACON_SCAN));
if(isBeaconScan){
mBeaconManager.bind(this);
}else{
mBeaconManager.unbind(this);
}
}
// Set Regions to monitor at boot/startup
private void setRegionsAtBoot(){
Log.i(TAG, "setRegionsAtBoot");
log.info("setRegionsAtBoot");
SimpleBeaconStore beaconStore = new SimpleBeaconStore(this);
List<SimpleBeacon> beacons = beaconStore.getBeacons();
for (Iterator<SimpleBeacon> iterator = beacons.iterator(); iterator.hasNext();) {
SimpleBeacon simpleBeacon = iterator.next();
List<Identifier> listB = new ArrayList<Identifier>();
StringTokenizer st = new StringTokenizer(simpleBeacon.getBeaconUuid(), "#");
while (st.hasMoreTokens()) {
listB.add(new Identifier(Identifier.parse(st.nextToken())));
}
try {
Log.i(TAG, "setRegionsAtBoot " + simpleBeacon.getId());
log.info("setRegionsAtBoot " + simpleBeacon.getId());
Region region = new Region(simpleBeacon.getId(), listB);
mBeaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
// Start actions
if (region.getUniqueId().equals(ALLBEACONS)){
return;
}
if (beacons.size() > 0) {
for (Beacon beacon: beacons) {
Log.d(TAG, "Beacon "+beacon.toString()+" is about "+beacon.getDistance()+" meters away, with Rssi: "+beacon.getRssi());
log.debug("Beacon " + beacon.toString() + " is about " + beacon.getDistance() + " meters away, with Rssi: " + beacon.getRssi());
datasource = new DbZoneHelper(getApplicationContext());
ZoneEntity ze = datasource.getCursorZoneByName(region.getUniqueId());
if (beacon.getDistance() < ze.getRadius() && !ze.isStatus()) {
//
Log.i(TAG, "Beacon " + beacon.toString() + " Just became less than " + ze.getRadius() + " meters away.");
log.info("*** Beacon " + beacon.toString() + " Just became less than " + ze.getRadius() + " meters away. ***");
String transitionType = getTransitionString(1);
NotificationUtil.sendNotification(getApplicationContext(), transitionType, region.getUniqueId());
worker = new Worker(getApplicationContext());
worker.handleTransition(1, region.getUniqueId(), Constants.BEACON);
}
if (beacon.getDistance() > (ze.getRadius() * EXITMULTIPLICATOR) && ze.isStatus()) {
//
Log.i(TAG, "Beacon "+ beacon.toString()+" Just became over " + ze.getRadius() * EXITMULTIPLICATOR + " meters away.");
log.info("*** Beacon " + beacon.toString() + " Just became over " + ze.getRadius() * EXITMULTIPLICATOR + " meters away. ***");
String transitionType = getTransitionString(2);
NotificationUtil.sendNotification(getApplicationContext(), transitionType, region.getUniqueId());
worker = new Worker(getApplicationContext());
//
worker.handleTransition(2, region.getUniqueId(), Constants.BEACON);
}
}
}
}
@Override
public void didDetermineStateForRegion(int arg0, Region arg1) {
}
@Override
public void didEnterRegion(Region region) {
}
@Override
public void didExitRegion(Region region) {
if (region.getUniqueId().equals(ALLBEACONS)){
return;
}
datasource = new DbZoneHelper(getApplicationContext());
ZoneEntity ze = datasource.getCursorZoneByName(region.getUniqueId());
if (ze.isStatus()) {
//
Log.i(TAG, "Beacon " + region.getUniqueId() + " Just exited region.");
log.info("Beacon " + region.getUniqueId() + " Just exited region.");
String transitionType = getTransitionString(2);
NotificationUtil.sendNotification(getApplicationContext(), transitionType, region.getUniqueId());
worker = new Worker(getApplicationContext());
worker.handleTransition(2, region.getUniqueId(), Constants.BEACON);
}
}
@Override
public void onBeaconServiceConnect() {
Log.d(TAG, "onBeaconServiceConnect.");
log.debug("onBeaconServiceConnect");
setRegionsAtBoot();
mBeaconManager.setRangeNotifier(this);
}
public void bind(){
mBeaconManager.bind(this);
}
public void unbind(){
mBeaconManager.unbind(this);
}
我也在从我的设置中调用 bind/unbind。
显示的代码使用 RegionBootstrap
class 在后台持续扫描信标。 class 本质上是为了永不停止扫描信标而设计的。 RegionBootstrap
在构建时绑定到扫描服务,实际上永远不会取消绑定。显示的代码手动绑定和解除绑定因此无效。
如果您想在不同时间开始和停止扫描,请不要使用 RegionBootstrap
class,而是让您的 Application
或 Activity
工具BeaconConsumer
和 bind/unbind 如此处的监控示例代码所述:http://altbeacon.github.io/android-beacon-library/samples.html
编辑:RegionBootstrap 中添加了新方法,使动态区域监控更容易。您现在可以使用:regionBootstrap.disable()
完全停止扫描,或 regionBootstrap.removeRegion(region)
停止寻找单个区域。
我正在将 AltBeacon API 集成到现有应用程序中。当用户进入或离开 "bluetooth zone".
时,应用程序应在 后台 中启动操作此功能应该是可选的,用户应该从设置开始和停止扫描。
我尝试了 bind/unbind BeaconConsumer,但我看到,在后台 BluetoothLeScanner 一直在扫描!如何阻止 BluetoothLeScanner 扫描?这是正确的方法吗?
代码如下:
@Override
public void onCreate() {
super.onCreate();
LogManager.setVerboseLoggingEnabled(true);
log.debug("onCreate");
mAllBeaconsRegion = new Region(ALLBEACONS, null, null, null);
mBeaconManager = BeaconManager.getInstanceForApplication(this);
mBackgroundPowerSaver = new BackgroundPowerSaver(this);
mBeaconManager.setBackgroundBetweenScanPeriod(60000L);
mBeaconManager.setBackgroundScanPeriod(2100L);
// wake up the app when a beacon is seen
mRegionBootstrap = new RegionBootstrap(this, mAllBeaconsRegion);
mBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
dsGlobal = new DbGlobalsHelper(getApplicationContext());
boolean isBeaconScan = Utils.isBoolean(dsGlobal.getCursorGlobalsByKey(Constants.DB_KEY_BEACON_SCAN));
if(isBeaconScan){
mBeaconManager.bind(this);
}else{
mBeaconManager.unbind(this);
}
}
// Set Regions to monitor at boot/startup
private void setRegionsAtBoot(){
Log.i(TAG, "setRegionsAtBoot");
log.info("setRegionsAtBoot");
SimpleBeaconStore beaconStore = new SimpleBeaconStore(this);
List<SimpleBeacon> beacons = beaconStore.getBeacons();
for (Iterator<SimpleBeacon> iterator = beacons.iterator(); iterator.hasNext();) {
SimpleBeacon simpleBeacon = iterator.next();
List<Identifier> listB = new ArrayList<Identifier>();
StringTokenizer st = new StringTokenizer(simpleBeacon.getBeaconUuid(), "#");
while (st.hasMoreTokens()) {
listB.add(new Identifier(Identifier.parse(st.nextToken())));
}
try {
Log.i(TAG, "setRegionsAtBoot " + simpleBeacon.getId());
log.info("setRegionsAtBoot " + simpleBeacon.getId());
Region region = new Region(simpleBeacon.getId(), listB);
mBeaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
// Start actions
if (region.getUniqueId().equals(ALLBEACONS)){
return;
}
if (beacons.size() > 0) {
for (Beacon beacon: beacons) {
Log.d(TAG, "Beacon "+beacon.toString()+" is about "+beacon.getDistance()+" meters away, with Rssi: "+beacon.getRssi());
log.debug("Beacon " + beacon.toString() + " is about " + beacon.getDistance() + " meters away, with Rssi: " + beacon.getRssi());
datasource = new DbZoneHelper(getApplicationContext());
ZoneEntity ze = datasource.getCursorZoneByName(region.getUniqueId());
if (beacon.getDistance() < ze.getRadius() && !ze.isStatus()) {
//
Log.i(TAG, "Beacon " + beacon.toString() + " Just became less than " + ze.getRadius() + " meters away.");
log.info("*** Beacon " + beacon.toString() + " Just became less than " + ze.getRadius() + " meters away. ***");
String transitionType = getTransitionString(1);
NotificationUtil.sendNotification(getApplicationContext(), transitionType, region.getUniqueId());
worker = new Worker(getApplicationContext());
worker.handleTransition(1, region.getUniqueId(), Constants.BEACON);
}
if (beacon.getDistance() > (ze.getRadius() * EXITMULTIPLICATOR) && ze.isStatus()) {
//
Log.i(TAG, "Beacon "+ beacon.toString()+" Just became over " + ze.getRadius() * EXITMULTIPLICATOR + " meters away.");
log.info("*** Beacon " + beacon.toString() + " Just became over " + ze.getRadius() * EXITMULTIPLICATOR + " meters away. ***");
String transitionType = getTransitionString(2);
NotificationUtil.sendNotification(getApplicationContext(), transitionType, region.getUniqueId());
worker = new Worker(getApplicationContext());
//
worker.handleTransition(2, region.getUniqueId(), Constants.BEACON);
}
}
}
}
@Override
public void didDetermineStateForRegion(int arg0, Region arg1) {
}
@Override
public void didEnterRegion(Region region) {
}
@Override
public void didExitRegion(Region region) {
if (region.getUniqueId().equals(ALLBEACONS)){
return;
}
datasource = new DbZoneHelper(getApplicationContext());
ZoneEntity ze = datasource.getCursorZoneByName(region.getUniqueId());
if (ze.isStatus()) {
//
Log.i(TAG, "Beacon " + region.getUniqueId() + " Just exited region.");
log.info("Beacon " + region.getUniqueId() + " Just exited region.");
String transitionType = getTransitionString(2);
NotificationUtil.sendNotification(getApplicationContext(), transitionType, region.getUniqueId());
worker = new Worker(getApplicationContext());
worker.handleTransition(2, region.getUniqueId(), Constants.BEACON);
}
}
@Override
public void onBeaconServiceConnect() {
Log.d(TAG, "onBeaconServiceConnect.");
log.debug("onBeaconServiceConnect");
setRegionsAtBoot();
mBeaconManager.setRangeNotifier(this);
}
public void bind(){
mBeaconManager.bind(this);
}
public void unbind(){
mBeaconManager.unbind(this);
}
我也在从我的设置中调用 bind/unbind。
显示的代码使用 RegionBootstrap
class 在后台持续扫描信标。 class 本质上是为了永不停止扫描信标而设计的。 RegionBootstrap
在构建时绑定到扫描服务,实际上永远不会取消绑定。显示的代码手动绑定和解除绑定因此无效。
如果您想在不同时间开始和停止扫描,请不要使用 RegionBootstrap
class,而是让您的 Application
或 Activity
工具BeaconConsumer
和 bind/unbind 如此处的监控示例代码所述:http://altbeacon.github.io/android-beacon-library/samples.html
编辑:RegionBootstrap 中添加了新方法,使动态区域监控更容易。您现在可以使用:regionBootstrap.disable()
完全停止扫描,或 regionBootstrap.removeRegion(region)
停止寻找单个区域。