我试图在用户进入定义的区域以及用户退出该区域时通知用户。这就是我到目前为止所做的。我曾经使用 rangeNotifier 方法 (didBeaconsEnterRange) 来在用户进入某个区域时通知他/她,但随后此方法会每 1 秒调用一次,因此我将通知逻辑移至 monitorNotifier 类 (didEnterRegion) 方法。
我的应用程序类扩展了 BootStrapNotifier,我将 scanPeriod 设置为 2000 秒而不是默认的 1100l 秒,因为我似乎接收退出和进入通知的速度太快了,即使信标在范围内也是如此。早些时候,我什至将超时期限从 10000 毫秒增加到 20000 毫秒,当信标在超时期限内没有发出信号时,它会触发出口。
myapplication 类的代码片段
BeaconManager beaconManager = org.altbeacon.beacon.BeaconManager.getInstanceForApplication(this);
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(LAYOUT_HERE));
beaconManager.setForegroundScanPeriod(2000l);
beaconManager.setBackgroundBetweenScanPeriod(1100l);
//beaconManager.setBackgroundScanPeriod(5000l);
beaconManager.setDebug(true);
Log.d(TAG, "setting up background monitoring for beacons and power saving");
// wake up the app when a beacon is seen
mRegion = new Region("myRangingUniqueId",
null, null, null);
setRegionAgain();
SetRegionAgain 方法
if(SharedPrefs.getString(SharedPrefs.iBEACON_ID, "").trim().length() > 0) {
if(SharedPrefs.getString(SharedPrefs.iBEACON_ID, "").trim().length() > 0 ) {
try {
mRegion = new Region("myRangingUniqueId",
Identifier.parse(SharedPrefs.getString(SharedPrefs.iBEACON_ID, "")),
null, null);
}catch(IllegalArgumentException e) {
e.printStackTrace();
mRegion = new Region("myRangingUniqueId",
null, null, null);
}
}
}
regionBootstrap = new RegionBootstrap(this, mRegion);
// simply constructing this class and holding a reference to it in your custom Application
// class will automatically cause the BeaconLibrary to save battery whenever the application
// is not visible. This reduces bluetooth power usage by about 60%
backgroundPowerSaver = new BackgroundPowerSaver(this);
我有一个执行通知工作的后台服务,因此它实现了 BeaconConsumer 接口。下面的代码片段:
OnStart 方法:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
flagToCheckExit = false;
mHandler = new Handler();
beaconManager.bind(this);
if (beaconManager.isBound(this)) beaconManager.setBackgroundMode(false);
return Service.START_STICKY;
}
onDestroy 方法:
@Override
public void onDestroy() {
super.onDestroy();
try {
beaconManager.stopMonitoringBeaconsInRegion(CommonUtilities.getRegion());
// this region is the one that i use to monitor (singleton types)
} catch (RemoteException e) {
e.printStackTrace();
}
beaconManager.unbind(this);
}
onServiceConnected 方法:
@Override
public void onBeaconServiceConnect() {
beaconManager.setMonitorNotifier(new MonitorNotifier() {
@Override
public void didExitRegion(final Region region) {
LogManager.d(TAG, "didExitRegion %s", region);
if(SharedPrefs.getString(SharedPrefs.USER_ID, "").trim().length() > 0) {
flagToCheckExit = true;
// i use this flag to prevent random entry and exit notifications
mHandler.postDelayed(mRunnable, 20000);
// waiting for 20seconds before firing an exit notification, since an entry notification might get fired immediately after the exit
}
}
@Override
public void didEnterRegion(Region region) {
Log.e(TAG,"region id1 >>> " + ((region.getId1() == null) ? "null" : region.getId1().toUuidString()));
LogManager.d(TAG, "didEnterRegion %s ",region);
if(!flagToCheckExit) {
if(SharedPrefs.getString(SharedPrefs.USER_ID, "").trim().length() > 0) {
if(region.getId1() != null &&
region.getId1().toUuidString().equalsIgnoreCase(SharedPrefs.getString(SharedPrefs.iBEACON_ID, ""))) {
if(!SharedPrefs.getBoolean(SharedPrefs.IS_ENTRY_LOG_CALLED, false)) {
String entryRange = getAppContext().getString(R.string.entered_beacon_region);
CommonUtilities.sendNotification(MonitoringAltBeaconService.this,entryRange,1);
}
}
}
}else {
// invalidate the handler
// stop all operations of the handler
// we do this to prevent an exit getting called since entry has been called immediately.
mHandler.removeCallbacks(mRunnable);
}
}
@Override
public void didDetermineStateForRegion(int state, Region region) {
LogManager.d(TAG, "didDetermineStateForRegion %s ",region);
}
});
startMonitoring();
}
启动监控方法:
private void startMonitoring() {
try {
if(SharedPrefs.getString(SharedPrefs.iBEACON_ID, "").trim().length() > 0 ) {
try {
beaconManager.startMonitoringBeaconsInRegion(CommonUtilities.getRegion());
}catch(IllegalArgumentException e) {
e.printStackTrace();
beaconManager.startMonitoringBeaconsInRegion(CommonUtilities.getRegion());
}
}
} catch (RemoteException e) { }
}
可运行线程:
Runnable mRunnable = new Runnable() {
@Override
public void run() {
SharedPrefs.putBoolean(SharedPrefs.IS_ENTRY_LOG_CALLED, false);
SharedPrefs.putBoolean(SharedPrefs.IS_EXIT_LOG_CALLED, true);
String exitedRange = getAppContext().getString(R.string.exited_beacon_region);
CommonUtilities.sendNotification(MonitoringAltBeaconService.this,exitedRange,2);
LogManager.d(TAG, "exit called");
flagToCheckExit = false;
}
};
这有一个奇怪的行为,即使信标设备在范围内,我也会得到多个进入和退出日志,我得到了退出。我尝试绕过退出通知,但上面的逻辑(补丁)似乎失败了。
日志:
03-19 18:00:25.866: D/MonitoringAltBeaconService(22795): didDetermineStateForRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null
03-19 18:00:25.867: D/MonitoringAltBeaconService(22795): didExitRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null
03-19 18:00:26.470: D/MonitoringAltBeaconService(22795): didDetermineStateForRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null
03-19 18:00:26.477: D/MonitoringAltBeaconService(22795): didEnterRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null
03-19 18:00:48.076: D/MonitoringAltBeaconService(22795): didDetermineStateForRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null
03-19 18:00:48.076: D/MonitoringAltBeaconService(22795): didExitRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null
03-19 18:00:51.275: D/MonitoringAltBeaconService(22795): didDetermineStateForRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null
03-19 18:00:51.282: D/MonitoringAltBeaconService(22795): didEnterRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null
03-19 18:01:10.269: D/MonitoringAltBeaconService(22795): didDetermineStateForRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null
03-19 18:01:10.269: D/MonitoringAltBeaconService(22795): didExitRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null
03-19 18:01:15.876: D/MonitoringAltBeaconService(22795): didDetermineStateForRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null
03-19 18:01:15.883: D/MonitoringAltBeaconService(22795): didEnterRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null
我正在使用 AprilBeacon。我正在开发的应用程序被搁置,因为信标无法正确生成通知。请协助。
编辑:
我在 Motorolla g2 中使用的设备,这种情况发生在 kitkat 和棒棒糖版本中。并且 Wifi 开启,我更喜欢它开启,因为当确定入口退出时,涉及到 web 服务调用。实时,不鼓励用户关闭 wifi :(..
我使用的库是 android-beacon-library ,我恐怕不知道 4 月信标发出信号的频率。
编辑2:
日志 1 可以在这里找到
日志 2 可以在这里找到
编辑 3
关闭wifi时记录 我注意到即使信标在范围内我也确实退出了并且我打开了定位应用程序,它显示没有信标存在(见屏幕截图)。我取出电池并将它们放回去它得到了信标,我的应用程序也是如此。(但在现实生活中,我相信电池不会被篡改)