关于android-beacon-library's scan-period的问题
Questions about android-beacon-library's scan-period
我在使用 android-beacon-library
时遇到有关扫描周期的问题。这是我的问题:
我有三个主要 class:MainActivity
、BaseService
和 BeaconService
。
MainActivity
:只做startForeground
和stopForeground
运算。
BaseService
:做一些参数初始化,BeaconManager
等等。
BeaconService
: 信标操作。
我先描述我的问题。我正在使用前台服务进行扫描操作,backgroundScanPeriod 是 20l。我还有一个带有两个按钮的 MainActivity,startService 和 stopService。当我第一次打开应用程序并单击 startService 时,扫描周期为 10s。
然后我单击“主页”并关闭此应用程序,服务 运行 正常,扫描周期也为 10 秒。但是当我通过点击图片上的通知重新打开 MainActivity
时。
扫描周期将变为1s。这对我来说很快。但是,如果我再次单击“主页”,扫描周期就会变得正常。这意味着,除了第一次打开 MainActivity 之外,每次扫描周期都会变得非常快。
我想知道为什么。下面是我的重要代码:
MainActivity.class
@OnClick(R.id.start_service)
void start_Service() {
if (Utils.isServiceRunning(MainActivity.this, Constants.CLASSNAME)) {
Toast.makeText(this, "service is running, don't start again", Toast.LENGTH_SHORT).show();
} else {
Intent intent = new Intent(MainActivity.this, BeaconService.class);
intent.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
startService(intent);
setInfo();
}
}
@OnClick(R.id.stop_service)
void stop_Service() {
if (Utils.isServiceRunning(MainActivity.this, Constants.CLASSNAME)) {
Intent intent = new Intent(MainActivity.this, BeaconService.class);
intent.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
startService(intent);
setInfo();
} else {
Toast.makeText(this, "service is dead, don't kill again", Toast.LENGTH_SHORT).show();
}
}
BaseService.class
private void setBeaconManager() {
beaconManager.setBackgroundBetweenScanPeriod(20l);
beaconManager.setBackgroundMode(true);
beaconManager.getBeaconParsers().clear();
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(Constants.BEACON_LAYOUT.COMMON_LAYOUT));
}
BeaconService.class
public class BeaconService extends BaseService implements BootstrapNotifier, BeaconConsumer {
private static final int NOTIFICATION = R.string.notify_service_started;
private static final String TAG = "BeaconService";
private int size = -1;
private RegionBootstrap regionBootstrap;
private BackgroundPowerSaver backgroundPowerSaver;
private Beacon beacon;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate");
regionBootstrap = new RegionBootstrap(this, region);
beaconManager.bind(this);
backgroundPowerSaver = new BackgroundPowerSaver(getApplicationContext());
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null && intent.getAction() != null) {
switch (intent.getAction()) {
case Constants.ACTION.STARTFOREGROUND_ACTION:
startForeground(NOTIFICATION, getNotification());
break;
case Constants.ACTION.STOPFOREGROUND_ACTION:
Log.d(TAG, "Received stop foreground request");
stopForeground(true);
stopSelf();
break;
}
}
return START_STICKY;
}
@Override
public void onDestroy() {
beaconManager.unbind(this);
regionBootstrap.disable();
Log.d(TAG, "service onDestroy");
}
/**
* Called when at least one beacon in a Region is visible.
*
* @param region region
*/
@Override
public void didEnterRegion(Region region) {
// TODO: 3/8/16 reload all the resource
Log.d(TAG, "didEnterRegion called");
L.object(region);
try {
beaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
}
/**
* Called when no beacons in a Region are visible.
*
* @param region region
*/
@Override
public void didExitRegion(Region region) {
// TODO: 3/8/16 close all the resource
Log.d(TAG, "didExitRegion called");
try {
beaconManager.stopRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
beaconManager.unbind(this);
regionBootstrap.disable();
L.object(region);
}
/**
* Called with a state value of MonitorNotifier.INSIDE when at least one beacon in a Region is visible
*
* @param region region
*/
@Override
public void didDetermineStateForRegion(int i, Region region) {
Log.d(TAG, "switch from seeing/not seeing beacons");
L.object(region);
}
@Override
public void onBeaconServiceConnect() {
Log.d(TAG, "onBeaconServiceConnect");
if (null == beaconManager.getRangingNotifier()) {
beaconManager.setRangeNotifier(new RangeNotifier() {
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
Log.d(TAG, "beacons.size():" + beacons.size() + "," + this);
if (beacons.size() != 0) {
Iterator<Beacon> iterator = beacons.iterator();
if (beacons.size() != size) {
saveBeacon(iterator);
size = beacons.size();
}
}
}
});
}
}
/**
* Save beacon p-o-j-o to SQLite.
*/
private void saveBeacon(Iterator<Beacon> iterator) {
while (iterator.hasNext()) {
beacon = iterator.next();
L.object(beacon);
entity.setId(null);
entity.setUuid(beacon.getId1().toString());
entity.setMajor(beacon.getId2().toString());
entity.setMinor(beacon.getId3().toString());
entity.setTxpower(beacon.getTxPower());
entity.setTime(Utils.getCurrentTime());
dbHelper.provideNinjaDao().insert(entity);
Log.d(TAG, "sql save success");
}
}
private Notification getNotification() {
CharSequence text = getText(R.string.notify_service_started);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
Notification notification = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ninja_turtle)
.setTicker(text)
.setWhen(System.currentTimeMillis())
.setContentTitle(getText(R.string.info_service))
.setContentText(text)
.setContentIntent(contentIntent)
.build();
return notification;
}
}
希望大家能帮帮我。提前致谢。
几点:
使用 Android 信标库有两组不同的扫描周期设置,前景和背景。当使用代码中的BackgroundPowerSaver
时,Android信标库会自动在前台扫描周期和后台扫描周期之间来回切换。
当使用 BackgroundPowerSaver
时,手动设置 beaconManager.setBackgroundMode(true)
只会在下次应用程序循环到前台之前有效 - BackgroundPowerSaver
将自动更改此设置的值。
扫描周期的单位是毫秒。所以设置 beaconManager.setBackgroundBetweenScanPeriod(20l);
将扫描周期设置为 20 毫秒。这太短了,无法可靠地拾取信标。我建议最小扫描周期为 1100 毫秒。周期越长,检测到信标的概率越高,但使用的电池越多。
如果你想在扫描之间等待10秒,你要设置:beaconManager.setBackgroundBetweenScanPeriod(10000l); // 10000 ms = 10.0 secs
如果您希望在前台和后台应用相同的扫描周期,只需将它们设置为相同即可:
beaconManager.setBackgroundBetweenScanPeriod(10000l);
beaconManager.setForegroundBetweenScanPeriod(10000l);
beaconManager.setBackgroundScanPeriod(1100l);
beaconManager.setForegroundScanPeriod(1100l);
我在使用 android-beacon-library
时遇到有关扫描周期的问题。这是我的问题:
我有三个主要 class:MainActivity
、BaseService
和 BeaconService
。
MainActivity
:只做startForeground
和stopForeground
运算。BaseService
:做一些参数初始化,BeaconManager
等等。BeaconService
: 信标操作。
我先描述我的问题。我正在使用前台服务进行扫描操作,backgroundScanPeriod 是 20l。我还有一个带有两个按钮的 MainActivity,startService 和 stopService。当我第一次打开应用程序并单击 startService 时,扫描周期为 10s。
然后我单击“主页”并关闭此应用程序,服务 运行 正常,扫描周期也为 10 秒。但是当我通过点击图片上的通知重新打开 MainActivity
时。
扫描周期将变为1s。这对我来说很快。但是,如果我再次单击“主页”,扫描周期就会变得正常。这意味着,除了第一次打开 MainActivity 之外,每次扫描周期都会变得非常快。
我想知道为什么。下面是我的重要代码:
MainActivity.class
@OnClick(R.id.start_service)
void start_Service() {
if (Utils.isServiceRunning(MainActivity.this, Constants.CLASSNAME)) {
Toast.makeText(this, "service is running, don't start again", Toast.LENGTH_SHORT).show();
} else {
Intent intent = new Intent(MainActivity.this, BeaconService.class);
intent.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
startService(intent);
setInfo();
}
}
@OnClick(R.id.stop_service)
void stop_Service() {
if (Utils.isServiceRunning(MainActivity.this, Constants.CLASSNAME)) {
Intent intent = new Intent(MainActivity.this, BeaconService.class);
intent.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
startService(intent);
setInfo();
} else {
Toast.makeText(this, "service is dead, don't kill again", Toast.LENGTH_SHORT).show();
}
}
BaseService.class
private void setBeaconManager() {
beaconManager.setBackgroundBetweenScanPeriod(20l);
beaconManager.setBackgroundMode(true);
beaconManager.getBeaconParsers().clear();
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(Constants.BEACON_LAYOUT.COMMON_LAYOUT));
}
BeaconService.class
public class BeaconService extends BaseService implements BootstrapNotifier, BeaconConsumer {
private static final int NOTIFICATION = R.string.notify_service_started;
private static final String TAG = "BeaconService";
private int size = -1;
private RegionBootstrap regionBootstrap;
private BackgroundPowerSaver backgroundPowerSaver;
private Beacon beacon;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate");
regionBootstrap = new RegionBootstrap(this, region);
beaconManager.bind(this);
backgroundPowerSaver = new BackgroundPowerSaver(getApplicationContext());
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null && intent.getAction() != null) {
switch (intent.getAction()) {
case Constants.ACTION.STARTFOREGROUND_ACTION:
startForeground(NOTIFICATION, getNotification());
break;
case Constants.ACTION.STOPFOREGROUND_ACTION:
Log.d(TAG, "Received stop foreground request");
stopForeground(true);
stopSelf();
break;
}
}
return START_STICKY;
}
@Override
public void onDestroy() {
beaconManager.unbind(this);
regionBootstrap.disable();
Log.d(TAG, "service onDestroy");
}
/**
* Called when at least one beacon in a Region is visible.
*
* @param region region
*/
@Override
public void didEnterRegion(Region region) {
// TODO: 3/8/16 reload all the resource
Log.d(TAG, "didEnterRegion called");
L.object(region);
try {
beaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
}
/**
* Called when no beacons in a Region are visible.
*
* @param region region
*/
@Override
public void didExitRegion(Region region) {
// TODO: 3/8/16 close all the resource
Log.d(TAG, "didExitRegion called");
try {
beaconManager.stopRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
beaconManager.unbind(this);
regionBootstrap.disable();
L.object(region);
}
/**
* Called with a state value of MonitorNotifier.INSIDE when at least one beacon in a Region is visible
*
* @param region region
*/
@Override
public void didDetermineStateForRegion(int i, Region region) {
Log.d(TAG, "switch from seeing/not seeing beacons");
L.object(region);
}
@Override
public void onBeaconServiceConnect() {
Log.d(TAG, "onBeaconServiceConnect");
if (null == beaconManager.getRangingNotifier()) {
beaconManager.setRangeNotifier(new RangeNotifier() {
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
Log.d(TAG, "beacons.size():" + beacons.size() + "," + this);
if (beacons.size() != 0) {
Iterator<Beacon> iterator = beacons.iterator();
if (beacons.size() != size) {
saveBeacon(iterator);
size = beacons.size();
}
}
}
});
}
}
/**
* Save beacon p-o-j-o to SQLite.
*/
private void saveBeacon(Iterator<Beacon> iterator) {
while (iterator.hasNext()) {
beacon = iterator.next();
L.object(beacon);
entity.setId(null);
entity.setUuid(beacon.getId1().toString());
entity.setMajor(beacon.getId2().toString());
entity.setMinor(beacon.getId3().toString());
entity.setTxpower(beacon.getTxPower());
entity.setTime(Utils.getCurrentTime());
dbHelper.provideNinjaDao().insert(entity);
Log.d(TAG, "sql save success");
}
}
private Notification getNotification() {
CharSequence text = getText(R.string.notify_service_started);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
Notification notification = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ninja_turtle)
.setTicker(text)
.setWhen(System.currentTimeMillis())
.setContentTitle(getText(R.string.info_service))
.setContentText(text)
.setContentIntent(contentIntent)
.build();
return notification;
}
}
希望大家能帮帮我。提前致谢。
几点:
使用 Android 信标库有两组不同的扫描周期设置,前景和背景。当使用代码中的
BackgroundPowerSaver
时,Android信标库会自动在前台扫描周期和后台扫描周期之间来回切换。当使用
BackgroundPowerSaver
时,手动设置beaconManager.setBackgroundMode(true)
只会在下次应用程序循环到前台之前有效 -BackgroundPowerSaver
将自动更改此设置的值。扫描周期的单位是毫秒。所以设置
beaconManager.setBackgroundBetweenScanPeriod(20l);
将扫描周期设置为 20 毫秒。这太短了,无法可靠地拾取信标。我建议最小扫描周期为 1100 毫秒。周期越长,检测到信标的概率越高,但使用的电池越多。如果你想在扫描之间等待10秒,你要设置:
beaconManager.setBackgroundBetweenScanPeriod(10000l); // 10000 ms = 10.0 secs
如果您希望在前台和后台应用相同的扫描周期,只需将它们设置为相同即可:
beaconManager.setBackgroundBetweenScanPeriod(10000l);
beaconManager.setForegroundBetweenScanPeriod(10000l);
beaconManager.setBackgroundScanPeriod(1100l);
beaconManager.setForegroundScanPeriod(1100l);