Android Beacon прекратил сканирование после закрытия приложения (удалив его в списке последних приложений) - PullRequest
0 голосов
/ 30 октября 2018

Я использую Библиотека Android Beacon для сканирования ibeacon. В этих кодах он будет сканировать ibeacon в фоновом режиме, используя интерфейс BootstrapNotifier. Как только iBeacon обнаружен, включается интерфейс RangeNotifier, который отображает информацию о маяке в виде текста. Когда я закрывал это приложение (смахивая его в списке последних приложений), фоновое сканирование прекращалось. По праву он не должен останавливать сканирование на примере здесь . Ниже приведены коды. Ценю, если кто-нибудь может помочь. Заранее спасибо.

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 голосов
/ 03 ноября 2018

Чтобы автоматический перезапуск работал, вы должны создать RegionBootstap в методе onCreate пользовательского класса Application, а не класса Activity, как вы показали. Действие запускается только при запуске вручную, поэтому оно не будет запускать сканирование после автоматического перезапуска после уничтожения.

0 голосов
/ 05 ноября 2018

Мне удалось решить проблему. Ниже приведены исправленные коды. Я разделил его на 2 класса. Один для класса приложения и один для класса сканирования Bluetooth. когда приложение закрывается (смахивая его в списке последних приложений), класс приложения (MyApplication) будет запущен снова и запустит класс сканирования Bluetooth (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);
    }
}
0 голосов
/ 30 октября 2018

Среди множества настроек, которые некоторые мелкие производители Android предпочитают вносить в операционную систему, можно настроить переключатель задач. Sone делает это таким образом, что при смахивании приложений с экрана приложение переходит в состояние «остановлено».

В стоковой версии Android при удалении приложений из переключателя задач приложения не переводятся в состояние остановки. Делать остановку лица из Настройки -> Приложения делает. Когда приложение находится в остановленном состоянии, оно выглядит так, как будто оно никогда ранее не запускалось. Запрещается запускаться в ответ на таймеры или внешние события, такие как обнаружение маяка. Пользователь должен запустить его, чтобы вернуть его из состояния остановленного приложения.

Неясно, является ли это преднамеренным или ошибочным изменением этих производителей. В любом случае, к сожалению, вы ничего не можете с этим поделать.

Вы можете проверить, есть ли у вас один из этих телефонов, запустив детектор остановленных приложений .

Смотрите здесь для получения дополнительной информации:

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...