首页 文章

在后台模式下开始扫描需要几分钟(使用AltBeacons)

提问于
浏览
0

我正在尝试通过仅分配第一个ID然后获取检测到的信标的完整UUID来监视背景和前景模式上的信标 .

使用didEnterRegion方法,该区域的第二个ID为null,所以我做的是当我进入一个区域以检测哪个是第二个ID时开始测距信标 .

public class BeaconListener extends Application implements BootstrapNotifier {
private static final String TAG = "BEACON TEST";
private RegionBootstrap regionBootstrap;
private MonitoringActivity monitoringActivity = null;
private Region mRegion;
private BeaconManager beaconManager;
private String UUID;
public void onCreate() {
    super.onCreate();
    beaconManager = BeaconManager.getInstanceForApplication(this);
    beaconManager.getBeaconParsers().add(new BeaconParser().
            setBeaconLayout("s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19"));
    beaconManager.setBackgroundScanPeriod(1100);
    beaconManager.setBackgroundBetweenScanPeriod(0);
    beaconManager.setAndroidLScanningDisabled(true);

    beaconManager.setBackgroundMode(true);

    mRegion = new Region("Beacon", Identifier.parse("0xffffffffffffffffffff"), null, null);

    regionBootstrap = new RegionBootstrap(this, mRegion);

}

@Override
public void didEnterRegion(Region arg0) {
    // In this example, this class sends a notification to the user whenever a Beacon
    // matching a Region (defined above) are first seen.

    try {
        beaconManager.startRangingBeaconsInRegion(mRegion);
        beaconManager.setRangeNotifier(new RangeNotifier() {
            @Override
            public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region arg0) {
                try {
                    for (Beacon beacon : beacons) {
                          beaconManager.stopRangingBeaconsInRegion(mRegion);
                          sendNotification();
                    }
                } catch (Exception e) {
                    Log.i(TAG, e.getMessage());
                }
            }
        });

        beaconManager.startRangingBeaconsInRegion(mRegion);
        beaconManager.setBackgroundScanPeriod(1100);
        beaconManager.setBackgroundBetweenScanPeriod(0);
        beaconManager.setAndroidLScanningDisabled(true);
    } catch (RemoteException e) {    }
}

这工作正常,我可以获得检测到的信标的完整UUID但是,当我杀死应用程序或我将其置于后台模式时,重启监控服务需要几分钟(大约5分钟) . 有没有办法在转到后台或杀死应用程序后立即重启服务?当我将设备连接到充电器时,它会重新启动服务并快速找到信标 .

PS:当我谈到第一个ID和第二个ID时,我认为UUID = ID1 ID2

2 回答

  • 0

    您是正确的,在用户使用Android Beacon Library杀死应用程序后,最多需要五分钟才能重新开始扫描 . 无法配置此间隔,但如果适合您的用例,可以在代码中进行更改 .

    了解当您使用任务切换器终止应用程序时,操作系统将停止与应用程序关联的所有进程,包括库用于扫描信标的后台服务 . 该库使用两种不同的技术重新启动此扫描服务:

    • 通过监听电源连接/断开事件 .

    • 使用AlarmManager重新启动,如果自上次激活以来已经过了五分钟 .

    第二种方法既可用于应用程序被任务切换器杀死的情况,也可用于操作系统因内存不足而导致的情况 . 在后一种情况下,立即重新启动是不合适的,因为前台应用程序可能需要驱逐其他应用程序以使用所有系统内存一段时间 . 平移和缩放时,Google Map 应用通常会导致此问题 .

    选择五分钟间隔仅仅是因为期望低内存条件清除是合理的时间间隔 .

    虽然五分钟默认值在库中是不可配置的,但由于它是开源的,因此如果您愿意,可以编译修改后的版本以将其设置为更短的间隔 . 要更改的代码是here . 但是,要明白,这可能会对需要大量内存的前景应用产生负面影响 .

  • 0

    完全没有延迟来检测前景,背景,杀戮状态中的信标 .

    仅在 Application 类中编写代码, no need background service 用于监视信标 .

    我这样做了:

    /**
     * Created by Hiren Patel on 3/25/2017.
     */
    public class MyApplication extends Application implements BootstrapNotifier {
    
        private BeaconManager iBeaconManager;
        private RegionBootstrap regionBootstrap;
    
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            stopBeaconMonitoring();
            startBeaconMonitoring();
    
        }
    
        public void stopBeaconMonitoring() {
            Log.i("Application", "stopBeaconMonitoring");
            if (iBeaconManager != null) {
                iBeaconManager.removeAllMonitorNotifiers();
                iBeaconManager.removeAllRangeNotifiers();
                iBeaconManager = null;
            }
        }
    
        private void startBeaconMonitoring() {
    
            iBeaconManager = BeaconManager.getInstanceForApplication(this);
            iBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:0-3=4c000215,i:4-19,i:20-21,i:22-23,p:24-24"));
            iBeaconManager.setBackgroundBetweenScanPeriod(5000l);
            iBeaconManager.setBackgroundScanPeriod(1000l);
            iBeaconManager.setDebug(true);
    
            //Start the Services that will keep checking for beacons in the background, even if the application is closed (swiped away from the app-switcher).
            Intent startServiceIntent = new Intent(this.getApplicationContext(), BeaconService.class);
            this.getApplicationContext().startService(startServiceIntent);
            startServiceIntent = new Intent(this.getApplicationContext(), BeaconIntentProcessor.class);
            this.getApplicationContext().startService(startServiceIntent);
    
            List<BeaconEntity> beaconEntityList = YourBeaconListHere;
            if (beaconEntityList != null) {
                for (BeaconEntity beaconEntity : beaconEntityList) {
                    Region region = new Region(beaconEntity.Name, Identifier.parse(beaconEntity.UUID), Identifier.parse(String.valueOf(beaconEntity.Major)), Identifier.parse(String.valueOf(beaconEntity.Minor)));
                    regionBootstrap = new RegionBootstrap(this, region);
                    Log.i("Beacons List", beaconEntity.Name + "-" + beaconEntity.UUID + "-" + String.valueOf(beaconEntity.Major) + "-" + String.valueOf(beaconEntity.Minor));
                }
            }else{
                Log.i("Beacons List", "null");
            }
        }
    
        @Override
        public void didEnterRegion(Region region) {
            // You entered in Region(beacon range)
            Log.i("Application", "didEnterRegion called");
        }
    
        @Override
        public void didExitRegion(Region region) {
            // You exited from Region(beacon range)
            Log.i("Application", "didExitRegion called");
        }
    
        @Override
        public void didDetermineStateForRegion(int i, Region region) {
            // Region state changed, just ignore it
            Log.i("Application", "didDetermineStateForRegion called");
        }
    }
    

    Enjoy beaconing .

相关问题