Altbeacon库前台模式在Android上不起作用

时间:2019-07-19 22:22:32

标签: android service beacon altbeacon foreground-service

大家好,我正在使用Altbeacon库来发现我的android应用程序的信标。该服务以前景模式运行,以解决android 8后台服务的局限性。

问题

当我将应用程序置于后台(按“主页”按钮)时,尽管扫描仍然工作了一分钟,但在此间隔之后,连续扫描停止并在5分钟后重新开始

代码

public class BoikomApplication extends MultiDexApplication implements BootstrapNotifier, BeaconConsumer, RangeNotifier { 
...
 public void startListening() {

    final Notification.Builder builder = new Notification.Builder(this);
    builder.setSmallIcon(R.drawable.ic_logo);
    builder.setContentTitle(getString(R.string.foreground_notification_title));
    builder.setContentText(getString(R.string.foreground_notification_text));
    Intent intent = new Intent(this, BeaconActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(
            this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT
    );
    builder.setContentIntent(pendingIntent);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
                "Notification Channel", NotificationManager.IMPORTANCE_DEFAULT);
        channel.setDescription("Listening for beacons");
        NotificationManager notificationManager = (NotificationManager) getSystemService(
                Context.NOTIFICATION_SERVICE);
        if (notificationManager != null) {
            notificationManager.createNotificationChannel(channel);
            builder.setChannelId(channel.getId());
        }
    }
    beaconManager.enableForegroundServiceScanning(builder.build(), 456);
    beaconManager.setBackgroundMode(false);
    beaconManager.setEnableScheduledScanJobs(false);
    beaconManager.setBackgroundBetweenScanPeriod(0);
    beaconManager.setBackgroundScanPeriod(1100);

    backgroundPowerSaver = new BackgroundPowerSaver(this);

    beaconManager.bind(this);
   }
@Override
public void didEnterRegion(Region region) {
    LoggingHelper.i("[Beacon Service] didEnterRegion");
    BeaconServiceHandler.getInstance().onEnterRegion(region, this);
}
@Override
public void didExitRegion(Region region) {
    Log.d("App", "didExitRegion");
}

@Override
public void didDetermineStateForRegion(int state, Region region) {
    LoggingHelper.i("[Beacon Service] didDetermineStateForRegion");
}

@Override
public void onBeaconServiceConnect() {
    beaconManager.addMonitorNotifier(this);
    try {
        for (Region region : regions) {
            beaconManager.startRangingBeaconsInRegion(region);
        }
    } catch (Exception e) {
        LoggingHelper.e("[Beacon Service] Error while connecting to beacon service", e);
    }
    beaconManager.addRangeNotifier(this);
}
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> collection, Region region) {
    LoggingHelper.i("[Beacon Service] didRangeBeaconsInRegion");
    BeaconServiceHandler.getInstance().onEnterRegion(region, this);
}
public void stopListening() {
    beaconManager.unbind(this);
    beaconManager.disableForegroundServiceScanning();
}

日志

  2019-07-20 01:13:35.409 13181-13181/package D/CycledLeScanner: Waiting to stop scan cycle for another 89 milliseconds
    2019-07-20 01:13:35.417 13181-13181/package D/CycledLeScanner: Set a wakeup alarm to go off in 300000 ms: PendingIntent{69e638a: android.os.BinderProxy@a809dfb}
    2019-07-20 01:13:35.506 13181-13181/package D/CycledLeScanner: Done with scan cycle
    2019-07-20 01:13:35.509 13181-13181/package D/ScanHelper: Calling ranging callback
    2019-07-20 01:13:35.509 13181-13181/package D/Callback: attempting callback via local broadcast intent: org.altbeacon.beacon.range_notification
    2019-07-20 01:13:35.514 13181-13181/package D/CycledLeScanner: Not stopping scan because this is Android N and we keep scanning for a minimum of 6 seconds at a time. We will stop in 424 millisconds.
    2019-07-20 01:13:35.514 13181-13181/package D/CycledLeScanner: starting a new scan cycle
    2019-07-20 01:13:35.514 13181-13181/package D/CycledLeScanner: We are already scanning and have been for 904944386 millis
    2019-07-20 01:13:35.514 13181-13181/package D/CycledLeScanner: Waiting to stop scan cycle for another 1100 milliseconds
    2019-07-20 01:13:35.522 13181-13181/package D/CycledLeScanner: Set a wakeup alarm to go off in 300000 ms: PendingIntent{69e638a: android.os.BinderProxy@a809dfb}
    2019-07-20 01:13:35.522 13181-13181/package D/CycledLeScanner: Scan started
    2019-07-20 01:13:35.522 13181-13181/package D/IntentHandler: got ranging data
    2019-07-20 01:13:35.522 13181-13181/package I/Boikom: Thread: main
            ├ package.core.util.LoggingHelper.i(LoggingHelper.java:84)
            └ package.BoikomApplication.didRangeBeaconsInRegion(Application.java:133)
        [Beacon Service] didRangeBeaconsInRegion
    2019-07-20 01:13:35.523 13181-13181/package W/Boikom: Thread: main
            ├ package.core.util.LoggingHelper.w(LoggingHelper.java:217)
            └ package.core.service.BeaconServiceHandler.onEnterRegion(BeaconServiceHandler.java:89)
        [BeaconServiceHandler] The specified beacon has already show recently. Abort
    2019-07-20 01:19:25.142 13181-13181/package D/CycledLeScanner: Done with scan cycle
    2019-07-20 01:19:25.149 13181-13181/package D/ScanHelper: Calling ranging callback
    2019-07-20 01:19:25.155 13181-13181/package D/Callback: attempting callback via local broadcast intent: org.altbeacon.beacon.range_notification
    2019-07-20 01:19:25.159 13181-13181/package D/CycledLeScanner: stopping bluetooth le scan
    2019-07-20 01:19:25.159 13181-13181/package D/CycledLeScannerForLollipop: Stopping scan
    2019-07-20 01:19:25.162 13181-13181/package D/CycledLeScanner: starting a new scan cycle
    2019-07-20 01:19:25.162 13181-13333/package D/CycledLeScannerForLollipop: Stopping LE scan on scan handler
    2019-07-20 01:19:25.164 13181-13333/package D/BluetoothAdapter: isLeEnabled(): ON
    2019-07-20 01:19:25.164 13181-13181/package D/CycledLeScanner: starting a new bluetooth le scan
    2019-07-20 01:19:25.164 13181-13333/package D/BluetoothLeScanner: could not find callback wrapper
    2019-07-20 01:19:25.168 13181-13181/package D/CycledLeScanner: Waiting to stop scan cycle for another 1100 milliseconds
    2019-07-20 01:19:25.170 13181-13181/package D/CycledLeScanner: Set a wakeup alarm to go off in 300000 ms: PendingIntent{69e638a: android.os.BinderProxy@a809dfb}
    2019-07-20 01:19:25.171 13181-13181/package D/CycledLeScanner: Scan started
    2019-07-20 01:19:25.172 13181-13181/package D/StartupBroadcastReceiver: onReceive called in startup broadcast receiver
    2019-07-20 01:19:25.173 13181-13181/package D/StartupBroadcastReceiver: got wake up intent
    2019-07-20 01:19:25.175 13181-13181/package D/IntentHandler: got ranging data

1 个答案:

答案 0 :(得分:0)

华为的EMUI操作系统是Android的一个分支,其中包含未记录的标准Android行为更改:

  • 应用程序可能不会使用JobScheduler无限期在后台运行,从而导致该库的默认Android 8+后台扫描机制终止。
  • 使用华为不会透露的秘密算法,有时会在屏幕关闭时阻止蓝牙扫描。

最重要的是:仅在华为设备上不可靠进行后台信标扫描。

图书馆开发团队曾试图对华为的秘密算法进行独立的逆向工程,但迄今为止尚未找到可接受的解决方案。看这里:  https://github.com/AltBeacon/android-beacon-library/issues/554

在上面的工作中,已知此系统级别的logcat行与阻止扫描相关联:

E/Bth: G.GattService:App 'my_package_name' is scanning too frequently on screen off

以上工作适用于EMUI 5.0-8.0,而上述问题适用于具有EMUI 8.1的P20。该行为听起来与上述库问题中所述的行为略有不同,因此秘密扫描阻止算法可能已在EMUI 8和8.1之间进行了修改。在捕获系统级日志以帮助表征此行为并将其添加到上述问题方面的任何帮助将不胜感激。