应用关闭后,Android Beacon停止扫描(在最近的应用列表中将其关闭)

时间:2018-10-30 03:37:41

标签: android ibeacon android-bluetooth beacon altbeacon

我正在使用Android Beacon Library扫描ibeacon。在这些代码中,它将使用BootstrapNotifier界面在后台扫描ibeacon。一旦检测到iBeacon,RangeNotifier界面即会启动,并在textview中显示信标信息。当我关闭此应用程序时(通过在最近的应用程序列表中将其关闭),后台扫描停止了。正确地说,它不应基于示例here停止扫描。以下是代码。赞赏是否有人可以提供帮助。预先感谢。

package com.example.budakgigibesi.ibeacon_scan;

import android.app.Activity;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import org.altbeacon.beacon.Beacon;
import org.altbeacon.beacon.BeaconConsumer;
import org.altbeacon.beacon.BeaconManager;
import org.altbeacon.beacon.BeaconParser;
import org.altbeacon.beacon.RangeNotifier;
import org.altbeacon.beacon.Region;
import org.altbeacon.beacon.powersave.BackgroundPowerSaver;
import org.altbeacon.beacon.startup.BootstrapNotifier;
import org.altbeacon.beacon.startup.RegionBootstrap;

import java.util.Collection;

public class MainActivity extends AppCompatActivity implements BootstrapNotifier, BeaconConsumer, RangeNotifier {

    private BeaconManager beaconManager;
    private RegionBootstrap regionBootstrap;
    private BackgroundPowerSaver backgroundPowerSaver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);     

        //enable beacon features///////////////////////////////////////////////////////////////////////

        beaconManager = BeaconManager.getInstanceForApplication(this);
        beaconManager.getBeaconParsers().clear();
        beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
        beaconManager.setEnableScheduledScanJobs(false);    // disable JobScheduler-based scans (used on Android 8+)
        beaconManager.setBackgroundBetweenScanPeriod(0);    // set the time between each scan to be 1 hour (3600 seconds)
        beaconManager.setBackgroundScanPeriod(1100);    // set the duration of the scan to be 1.1 seconds

        Region region = new Region("backgroundRegion", null, null, null);
        regionBootstrap = new RegionBootstrap(this, region);    // wake up the app when a beacon is seen

        backgroundPowerSaver = new BackgroundPowerSaver(this);  //This reduces bluetooth power usage by about 60%

        beaconManager.bind(this);   //for beacon RangeNotifier
        //////////////////////////////////////////////////////////////////////////////////////////////
    }

    //altbeacon bootstrapnotifier///////////////////////////////////////////////////////////////////////
    @Override
    public void didEnterRegion(Region region) {
        TextView mTextView = (TextView) findViewById(R.id.id_tv);
        mTextView.setText( "found a beacon");

        // 
        try {
            beaconManager.startRangingBeaconsInRegion(region);  //Tells the BeaconService to start looking for beacons that match the passed Region object, and providing updates on the estimated mDistance every seconds while beacons in the Region are visible.
        }
        catch (RemoteException e) {
            if (BuildConfig.DEBUG) Log.d("RangeNotifier", "Can't start ranging");
        }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////

    //altbeacon BeaconConsumer///////////////////////////////////////////////////////////////////////
    @Override
    public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
        if (beacons.size() > 0) {
            Log.i("beaconconsumer", "didRangeBeaconsInRegion called with beacon count:  "+beacons.size());
            for (Beacon b : beacons) {
                Log.i("beaconconsumer", "The first beacon " + b.toString() + " is about " + b.getDistance() + " meters away.");
                TextView mTextView = (TextView) findViewById(R.id.id_tv);
                mTextView.setText( "The first beacon " + b.toString() + " is about " + b.getDistance() + " meters away.");
            }
        }catch (RemoteException e) {   }
    }

    @Override
    public void onBeaconServiceConnect() {
        beaconManager.addRangeNotifier(this);
    }

    @Override 
    protected void onPause() {
        super.onPause();
        if (beaconManager.isBound(this)) beaconManager.setBackgroundMode(true);
    }

    @Override 
    protected void onResume() {
        super.onResume();
        if (beaconManager.isBound(this)) beaconManager.setBackgroundMode(false);
    }




}

并在logcat中发现了一些错误

10-30 13:24:40.263 14712-30801/? D/BtGatt.btif: btif_gattc_upstreams_evt: Event 4096
10-30 13:24:40.263 14712-30801/? D/BtGatt.GattService: onScanResult() - address=7C:64:56:83:5E:71, rssi=-86
10-30 13:24:40.323 7928-7945/com.example.budakgigibesi.ibeacon_scan D/BluetoothAdapter: stopLeScan()
10-30 13:24:40.323 14712-14847/? D/BtGatt.GattService: stopScan() - queue=1
10-30 13:24:40.333 14712-14847/? D/BtGatt.GattService: stopScan() - queue empty; stopping scan
10-30 13:24:40.333 14712-14847/? D/BtGatt.btif: btif_gattc_scan
10-30 13:24:40.333 14712-30801/? D/BtGatt.btif: btgattc_handle_event: Event 1003
10-30 13:24:40.343 14712-14723/? D/BtGatt.GattService: unregisterClient() - clientIf=5
10-30 13:24:40.343 14712-14723/? D/BtGatt.btif: btif_gattc_unregister_app
10-30 13:24:40.353 14712-30801/? D/BtGatt.btif: btgattc_handle_event: Event 1001
10-30 13:24:40.353 14712-30801/? D/BtGatt.btif: btif_gattc_upstreams_evt: Event 1
10-30 13:24:40.363 7928-7945/com.example.budakgigibesi.ibeacon_scan D/BluetoothAdapter: startLeScan(): null
10-30 13:24:40.363 14712-14724/? D/BtGatt.GattService: registerClient() - UUID=6f27a4f0-4631-405a-8651-07c58b62f50d
10-30 13:24:40.373 14712-14724/? D/BtGatt.btif: btif_gattc_register_app
10-30 13:24:40.373 14712-30801/? D/BtGatt.btif: btgattc_handle_event: Event 1000
10-30 13:24:40.373 14712-30801/? D/BtGatt.btif: btif_gattc_upstreams_evt: Event 0
10-30 13:24:40.373 14712-30801/? D/BtGatt.GattService: onClientRegistered() - UUID=6f27a4f0-4631-405a-8651-07c58b62f50d, clientIf=5
10-30 13:24:40.373 7928-7998/com.example.budakgigibesi.ibeacon_scan D/BluetoothAdapter: onClientRegistered() - status=0 clientIf=5
10-30 13:24:40.383 14712-30801/? D/BtGatt.GattService: startScan() - queue=0
10-30 13:24:40.383 14712-30801/? D/BtGatt.GattService: startScan() - adding client=5
10-30 13:24:40.383 14712-30801/? D/BtGatt.btif: btif_gattc_scan
10-30 13:24:40.383 14712-30801/? D/BtGatt.btif: btgattc_handle_event: Event 1002
10-30 13:24:40.463 932-14195/? I/ActivityManager: Killing 7928:com.example.budakgigibesi.ibeacon_scan/u0a315 (adj 16): remove task
10-30 13:24:40.673 14712-16859/? D/BtGatt.GattService: Binder is dead - unregistering client (5)!
10-30 13:24:40.673 14712-16859/? D/BtGatt.GattService: stopScan() - queue=1
10-30 13:24:40.673 14712-16859/? D/BtGatt.GattService: stopScan() - queue empty; stopping scan
10-30 13:24:40.673 14712-16859/? D/BtGatt.btif: btif_gattc_scan
10-30 13:24:40.673 14712-30801/? D/BtGatt.btif: btgattc_handle_event: Event 1003
10-30 13:24:40.673 932-1593/? W/ActivityManager: Scheduling restart of crashed service com.example.budakgigibesi.ibeacon_scan/org.altbeacon.beacon.service.BeaconService in 1000ms
10-30 13:24:40.683 14712-16859/? D/BtGatt.GattService: unregisterClient() - clientIf=5
10-30 13:24:40.683 14712-16859/? D/BtGatt.btif: btif_gattc_unregister_app
10-30 13:24:40.683 14712-30801/? D/BtGatt.btif: btgattc_handle_event: Event 1001
10-30 13:24:40.683 14712-30801/? D/BtGatt.btif: btif_gattc_upstreams_evt: Event 1
10-30 13:24:41.204 932-932/? E/JavaBinder: !!! FAILED BINDER TRANSACTION !!!
10-30 13:24:41.204 1189-1189/? D/StatusBar.NetworkController: refreshViews: Data not connected!! Set no data type icon / Roaming
10-30 13:24:41.204 932-932/? E/JavaBinder: !!! FAILED BINDER TRANSACTION !!!
10-30 13:24:41.294 406-1066/? D/QC-QMI: Thread state: conn_id=18, state=RX_THREAD_WAKELOCK_ACQUIRE
10-30 13:24:41.294 406-1066/? D/QC-QMI: Thread state: conn_id=18, state=RX_THREAD_WAIT_READ
10-30 13:24:41.294 406-1066/? D/QC-QMI: Thread state: conn_id=18, state=RX_THREAD_CLIENT_TX
10-30 13:24:41.294 406-1066/? D/QC-QMI: qmi_qmux: TX/RX - RX 95 bytes on conn_id=18
10-30 13:24:41.294 406-1066/? D/QC-QMI: qmuxd: TX message on fd=24, to qmux_client_id=0x3, len=129
10-30 13:24:41.294 406-1066/? D/QC-QMI: Thread state: conn_id=18, state=RX_THREAD_WAKELOCK_RELEASE
10-30 13:24:41.294 406-1066/? D/QC-QMI: Thread state: conn_id=18, state=RX_THREAD_WAIT_POLL

3 个答案:

答案 0 :(得分:0)

一些较小的Android制造商喜欢对操作系统进行的许多自定义操作中,其中之一就是自定义任务切换器。 Sone这样做的方式是使应用程序从屏幕上滑动,从而使应用程序处于“停止”状态。

在现有的Android设备上,从任务切换器上滑动应用程序不会使应用程序处于停止状态。从“设置”->“应用程序”进行面部停止。一旦应用程序处于停止状态,就好像从未启动过该应用程序一样。不允许它响应计时器或外部事件(如信标检测)来启动自己。用户必须及时启动它,以使其从停止的应用程序状态恢复。

目前尚不清楚这是这些制造商的有意更改还是错误更改。无论哪种方式,不幸的是您都无法做任何事情。

您可以通过运行stopped app detector来检查是否有其中一部电话。

有关更多信息,请参见此处:

https://altbeacon.github.io/android-beacon-library/resume-after-terminate.html

https://github.com/AltBeacon/android-beacon-library/issues/729

答案 1 :(得分:0)

要使自动重启正常工作,必须在自定义Application类(而不是显示的Activity类)的onCreate方法中构造RegionBootstap。该活动仅在手动启动时启动,因此在被杀死后自动重启后无法触发扫描。

答案 2 :(得分:0)

我设法解决了这个问题。下面是更正的代码。我将其分为2类。一种用于应用程序类,一种用于蓝牙扫描类。关闭应用程序(在最近的应用程序列表中将其关闭)时,应用程序类(MyApplication)将再次启动并启动蓝牙扫描类(ScanBT)。

MyApplication.java

public class MainApplication extends Application {      

    public void onCreate() {
        super.onCreate();
        Intent intent = new Intent(this, ScanBT.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        this.startActivity(intent); 
    }


}

ScanBT.java

public class ScanBT extends AppCompatActivity implements BootstrapNotifier, BeaconConsumer, RangeNotifier {

    private BeaconManager beaconManager;
    private RegionBootstrap regionBootstrap;
    private BackgroundPowerSaver backgroundPowerSaver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);     
        Log.i("foxy", "ScanBT - i am in onCreateeeeeeeee");

        //enable beacon features///////////////////////////////////////////////////////////////////////     
        beaconManager = BeaconManager.getInstanceForApplication(this);
        beaconManager.getBeaconParsers().clear();
        beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
        beaconManager.setEnableScheduledScanJobs(false);    
        beaconManager.setBackgroundBetweenScanPeriod(0);    
        beaconManager.setBackgroundScanPeriod(1100);    

        Region region = new Region("backgroundRegion", null, null, null);
        regionBootstrap = new RegionBootstrap(this, region);    

        backgroundPowerSaver = new BackgroundPowerSaver(this);  

        beaconManager.bind(this);   
        //////////////////////////////////////////////////////////////////////////////////////////////
    }

    //altbeacon bootstrapnotifier///////////////////////////////////////////////////////////////////////
    @Override
    public void didEnterRegion(Region region) {
        Log.i("foxy", "ScanBT - a beacon entered the region");


        try {
            beaconManager.startRangingBeaconsInRegion(region);  
        }
        catch (RemoteException e) {
            if (BuildConfig.DEBUG) Log.d("RangeNotifier", "Can't start ranging");
        }
    }

    @Override
    public void didDetermineStateForRegion(int state, Region region) {

    }   

    @Override
    public void didExitRegion(Region region) {

    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////

    //altbeacon BeaconConsumer///////////////////////////////////////////////////////////////////////
    @Override
    public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
        if (beacons.size() > 0) {
            Log.i("foxy", "ScanBT - didRangeBeaconsInRegion called with beacon count:  "+beacons.size());
            for (Beacon b : beacons) {
                Log.i("foxy", "ScanBT - The first beacon " + b.toString() + " is about " + b.getDistance() + " meters away.");
            }
        }
    }

    @Override
    public void onBeaconServiceConnect() {
        beaconManager.addRangeNotifier(this);
    }

    @Override 
    protected void onPause() {
        super.onPause();
    }

    @Override 
    protected void onResume() {
        super.onResume();
    }

    @Override 
    protected void onDestroy() {
        super.onDestroy();
        beaconManager.unbind(this);
    }
}