BLE Scan verhalten bei verschiedenen Devices

  • 2 Antworten
  • Neuester Beitrag
Diskutiere BLE Scan verhalten bei verschiedenen Devices im Android App Entwicklung im Bereich Betriebssysteme & Apps.
C

C3lt1c84

Neues Mitglied
Hi.
Ich programmiere schon eine sehr lange zeit in Android.
Aber es ist mir immer noch ein Phänomen wie unterschiedlich die Devices sind wenn
man die Hardwarekomponenten mit in seine App einbauen will.

Mein Problem ist das ich mir eine BLE Klasse geschrieben habe die für < Android 5 den normalen Scancallback nutzt,
und falls Api >= 5.0 den result Callback mit den Entsprechenden:
scanSettingsBuilder.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY);
Modus.

Das ganze klappt wunderbar mit vielen verschiedenen Devices. Nur bei der Samsungreihe S5 und höher, puffert er wieder die BLE Packete und gibt sie nur verzögert an das Event weiter.
Hat jemand eine Lösung parat wie man das ganze umgehen kann?

mfg C3lt1c
 
swa00

swa00

Moderator
Teammitglied
Hallo C3,

das gleiche Phänomen ist mir auch aufgefallen und habe auch noch keine Lösung gefunden.
(In meinem Falle A2DP und ELM327/OBD)

Ich finde mich allerdings damit mittlerweile ab , da ich es auf die Chips schiebe
 
C

C3lt1c84

Neues Mitglied
Mir ist gerade noch aufgefallen, wenn ich den Service von der Mainactivity aus starte alles ok ist.
Sobald ich dann Ble aus und einschalte oder der Service sich neu created nur noch langsam die BLE packete einfliegen.

Hier mal ein code ausschnitt aus meinem Service und der Singelton Ble Klasse die ich geschrieben habe.

Code:
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;



public class BleScannerService extends Service {

    private KeepAliveCountdownTimer keepAliveCountdownTimer;
    private Context mcontext;

    //--------------------------------------------------------------
    public BleScannerService(){

    }
    //--------------------------------------------------------------
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    //--------------------------------------------------------------

    private void printLog (final String text){
        Log.i("BLE", "[BleScannerService]>>\t" + text);
    }

    //--------------------------------------------------------------
    private void init(){
        printLog("init...");

        mcontext = this;

        IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
        getApplication().registerReceiver(bleBroadcastReceiver, filter);

        if (checkBleAdapterStatus()){
            BleScanner.getInstance().setContext(this);
            BleScanner.getInstance().startScan();
            printLog("start ble scanner...");
        }else{
            printLog("can not start ble scanner...");
        }

        keepAliveCountdownTimer = new KeepAliveCountdownTimer(10000,1000);
        keepAliveCountdownTimer.start();
    }
    //--------------------------------------------------------------

    @Override
    public void onCreate() {
        printLog("created...");

        init();
    }

    //--------------------------------------------------------------

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        printLog("onStartCommand...");


        return START_NOT_STICKY;
    }


    //--------------------------------------------------------------

    @Override
    public void onDestroy() {
        printLog("destroyed...");
        keepAliveCountdownTimer.cancel();
        BleScanner.getInstance().stopScan();
    }



    //--------------------------------------------------------------

    public void destroy(){
        keepAliveCountdownTimer.cancel();
        BleScanner.getInstance().stopScan();
        printLog("destroy...");
    }

    //--------------------------------------------------------------

    private class KeepAliveCountdownTimer extends CountDownTimer{

        public KeepAliveCountdownTimer(long millisInFuture, long countDownInterval) {
            super(millisInFuture, countDownInterval);
        }

        @Override
        public void onTick(long l) {
        }

        @Override
        public void onFinish() {
            printLog("keep alive...");
            start();
        }
    }

    //--------------------------------------------------------------


    private boolean checkBleAdapterStatus(){

        printLog("checkBleAdapterStatus...");
        BluetoothManager bluetoothManager = (BluetoothManager) getApplication().getSystemService(Context.BLUETOOTH_SERVICE);
        BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();

        if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()){
            printLog("bluetooth status false...");
            return false;
        }
        printLog("bluetooth status true...");
        return true;
    }
    //--------------------------------------------------------------
    private final BroadcastReceiver bleBroadcastReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();

            if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
                final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
                switch(state) {
                    case BluetoothAdapter.STATE_OFF:
                        printLog("BLE: STATE_OFF");
                        BleScanner.getInstance().stopScan();
                        break;
                    case BluetoothAdapter.STATE_TURNING_OFF:
                        printLog("BLE: STATE_TURNING_OFF");

                        break;
                    case BluetoothAdapter.STATE_ON:
                        printLog("BLE: STATE_ON");

                        BleScanner.getInstance().setContext(mcontext);
                       new Thread(new Runnable() {
                           @Override
                           public void run() {
                               try {
                                   Thread.sleep(2000);
                               } catch (InterruptedException e) {}
                               printLog("start ble scanner...");
                               BleScanner.getInstance().startScan();
                           }
                       }).start();


                        break;
                    case BluetoothAdapter.STATE_TURNING_ON:
                        printLog("BLE: STATE_TURNING_ON");
                        break;
                }

            }
        }
    };
    //------------------------------------------------------------------------



}
Code:
import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;


public class BleScanner {
    private static BleScanner ourInstance = new BleScanner();

    private Context context;

    private BluetoothManager bluetoothManager;
    private BluetoothAdapter mBluetoothAdapter;
    private ScanSettings.Builder scanSettingsBuilder;
    private ScanSettings scanSettings;
    private BluetoothLeScanner bluetoothLeScanner;
    private ArrayList< ScanFilter> filters;

    private long bleTimestamp = 0;

    private boolean bleScanActive = true;
    ScanCallback mScanCallback;
    private BluetoothAdapter.LeScanCallback mLeScanCallback;


    public static BleScanner getInstance() {

        return ourInstance;
    }
    //------------------------------------------------------------------------
    private BleScanner() {
        printLog("created...");

    }

    //------------------------------------------------------------------------

    public void setContext(Context context) {
        this.context = context;
        init();
    }


    //------------------------------------------------------------------------

    private void resetAllVars(){
        printLog("reset all vars");
        bluetoothManager = null;
        mBluetoothAdapter= null;
        scanSettingsBuilder= null;
        scanSettings= null;
        bluetoothLeScanner= null;
        filters= null;

        bleTimestamp = 0;

        bleScanActive = true;
        mScanCallback= null;
        mLeScanCallback= null;
    }

    //------------------------------------------------------------------------

    private void printLog (final String text){
        Log.i("BLE", "[BleScanner]>>\t" + text);
    }


    //------------------------------------------------------------------------


    public boolean stopScan(){
        printLog("stopScan...");

      try{
          if (Build.VERSION.SDK_INT >= 21) {
              if (bluetoothLeScanner != null || mBluetoothAdapter != null){
                  printLog("stopped...");
                  bluetoothLeScanner.stopScan(mScanCallback);
              }
          }else{
              if (bluetoothLeScanner != null || mBluetoothAdapter != null){
                  printLog("stopped...");
                  mBluetoothAdapter.stopLeScan(mLeScanCallback);
              }
          }
      }catch (Exception e){

      }


         return true;
    }

    //------------------------------------------------------------------------

    public boolean startScan(){
        printLog("startScan...");
        if (Build.VERSION.SDK_INT >= 21) {
            bluetoothLeScanner.startScan(filters,scanSettings, mScanCallback );
        }else{
            mBluetoothAdapter.startLeScan(mLeScanCallback);
        }
        return true;
    }
    //------------------------------------------------------------------------
    private void init(){
        printLog("init...");
        initBLE();
    }
    //------------------------------------------------------------------------
    private void initBLE(){
        printLog("initBLE...");
        generateCallBack();
        getBleTimeStamp();
        bluetoothManager = (BluetoothManager) context.getSystemService(context.getApplicationContext().BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();
        if (Build.VERSION.SDK_INT >= 21) {
            printLog("config ble settings...");
            scanSettingsBuilder = new ScanSettings.Builder();
            scanSettingsBuilder.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY);

            scanSettings = scanSettingsBuilder.build();
            bluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
            filters = new ArrayList<ScanFilter>();
        }

        filters = new ArrayList<ScanFilter>();
    }

    //------------------------------------------------------------------------

    private void generateCallBack(){
        if (Build.VERSION.SDK_INT >= 21) {
            printLog("use new ble scanmode...");
            printLog("generateCallBack...");

            if (mScanCallback != null) return;
            mScanCallback = new ScanCallback() {

                @TargetApi(21)
                @Override
                public void onScanResult(int callbackType, ScanResult result) {


                    if (bleScanActive && result == null) return;
                    if (result.getDevice().getName() == null) return;

                    printLog("+++BLE Event+++" );
                    printLog("TIMEDIFF: " + getBleTimeStamp());
                    printLog("LOCALNAME: " + result.getDevice().getName() +"\tMAC: " + result.getDevice().getAddress() + "\tRSSI: " + result.getRssi());



                }

                @Override
                public void onScanFailed(int errorCode) {
                    super.onScanFailed(errorCode);
                }
            };
        }else{

            printLog("use old ble scanmode...");

            if (mLeScanCallback != null) return;

            mLeScanCallback =
                    new BluetoothAdapter.LeScanCallback() {
                        @Override
                        public void onLeScan(final BluetoothDevice device, int rssi,
                                             byte[] scanRecord) {




                            if (bleScanActive && scanRecord == null) return;
                            if (device == null) return;
                        
                        }

                    };
        }
    }



    private long getBleTimeStamp(){

        long timeStamp = new Date().getTime() - bleTimestamp  ;

        bleTimestamp  = new Date().getTime();

        return timeStamp;
    }

    //------------------------------------------------------------------------
}