altbeacon 如何使后台服务保持活动状态?

How altbeacon is keeping a background service alive?

我 运行 遇到了与此线程相反的问题:

我有一个使用 altbeacon 的应用程序 (http://altbeacon.org/)

应用初始化alt-beacon实现应用层接口如下(细节省略)

public class MyApp extends Application implements
    BootstrapNotifier,
    BeaconConsumer {
//some code
@Override
public void onCreate() {
    super.onCreate();
    initBeacons();
}
public void initBeacons() {
    mBackgroundPowerSaver = new BackgroundPowerSaver(this);
    org.altbeacon.beacon.BeaconManager altBeaconManager = org.altbeacon.beacon.BeaconManager.getInstanceForApplication(this);
    altBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
    // estimote
    altBeaconManager.setBackgroundScanPeriod(5000);
    altBeaconManager.setBackgroundBetweenScanPeriod(25000);
    mBeaconManager = MyBeaconManager.getInstance(this, altBeaconManager);
    mRegionBootstrap = new RegionBootstrap(this, MyBeaconManager.getRegions());
    altBeaconManager.bind(this);
}
@Override
public void onBeaconServiceConnect() {
    Thread thread = new Thread() {
        public void run() {
        // Try range the beacons
        rangeMyBeacons();
        }
    };
    thread.start();
}
@Override
public void didEnterRegion(Region region) {
    // Some code 
}
@Override
public void didExitRegion(Region region) {
    // Some code
}
@Override
public void didDetermineStateForRegion(int i, Region region) {
    // Some code    
}
public class MyBeaconManager implements
    RangeNotifier {
// some code

但是,如果我终止该应用程序或重新启动 phone,则 alt-beacon 服务会在没有任何特殊广播或应用程序权限的情况下重新启动。换句话说,Alt-beacon 一直在重新启动。请注意,我没有任何前台服务 运行。这是几个小时后应用程序的屏幕截图(我重新启动了 phone),所有应用程序都关闭了。您可以看到 alt-beacon 处于活动状态并正在扫描信标。

但是当我查看 alt-beacon 代码时,它不是前台服务

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    LogManager.i(TAG,
            intent == null ?
                    "starting with null intent"
                    :
                    "starting with intent " + intent.toString()
    );
    return super.onStartCommand(intent, flags, startId);
}

我确实在图书馆内进行了搜索,但没有找到 START_REDELIVER_INTENT 或 START_STICKY。

我的问题是 alt-beacon 如何在应用程序被终止时保持服务活动?

我想了解此功能的原因是我正在编写一个类似的服务,但如果我将它包装到前台服务中,我只能让它作为 alt-beacon 工作。我尝试过的所有其他方法,应用程序关闭后服务都会被终止。

谢谢。

Android 信标库使用 AlarmManager 在后台保持扫描服务 运行。它会在未来定期设置 5 分钟的警报,这会导致操作系统向其发送 BroadcastIntent 如果停止,它将启动扫描服务。当 运行 时,图书馆不断重新安排此警报。

您可以在此处查看执行该操作的代码:

https://github.com/AltBeacon/android-beacon-library/blob/master/src/main/java/org/altbeacon/beacon/service/scanner/CycledLeScanner.java#L339

// In case we go into deep sleep, we will set up a wakeup alarm when in the background to kickoff
// off the scan cycle again
protected void setWakeUpAlarm() {
    // wake up time will be the maximum of 5 minutes, the scan period, the between scan period
    long milliseconds = 1000l * 60 * 5; /* five minutes */
    if (milliseconds < mBetweenScanPeriod) {
        milliseconds = mBetweenScanPeriod;
    }
    if (milliseconds < mScanPeriod) {
        milliseconds = mScanPeriod;
    }

    AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
    alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + milliseconds, getWakeUpOperation());
    LogManager.d(TAG, "Set a wakeup alarm to go off in %s ms: %s", milliseconds, getWakeUpOperation());
}

这种设计保证了如果应用程序由于内存不足而需要终止,扫描将在未来五分钟后重新启动。这允许 phone 时间来完成内存密集型操作,同时仍然允许在合理的时间范围内进行信标检测。