Raphael Dejesus
Raphael Dejesus

Reputation: 33

BLE android 5.0 Crash

I have issues with android and BLE, any time i make a scan my app crash and i don't know the reason. I use startLeScan() can this be the reason? Here is a sample of my code.

here is the place where I initialize for api 18

//API 18
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {

    @Override
    public void onLeScan(final BluetoothDevice device, int rssi,
            byte[] scanRecord) {

        Sensortag sensortag = new Sensortag(device, SensortagScanner.this,
                mSensortagScannerCallback);

        synchronized (this) {
            for (Sensortag other : mDiscoveredDevices) {
                if (sensortag.getName().equals(other.getName())) {
                    Log.i("SensortagScanner",
                            "Discovered duplicate device: "
                                    + other.getName());
                    return;
                }
            }
        }

        mDiscoveredDevices.add(sensortag);
        Log.i("SensortagScanner",
                "Discovered a device named " + device.getName() + ".");
        mCallback.onSensorDiscovered(sensortag);
    }
};

here is where i initialize ScanCall and what seems to be wrong looking the error java nulle exception //API 21

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void initScanCallback() {

    if (scanCallback != null)
        return;
    this.scanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);
            // Do whatever you want
        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            super.onBatchScanResults(results);
            Log.d(TAG, "Batch scan results: ");
            for (ScanResult result : results) {
                Log.d(TAG, "Batch scan result: " + result.toString());
                // Do whatever you want
            }
        }

        @Override
        public void onScanFailed(int errorCode) {
            super.onScanFailed(errorCode);
            // scanListener.onScanFinished();
            Log.d(TAG, "Scan failed");
        }
    };
}

here is where i start the scan

    @Override
    public void startScan(SensorScannerCallback callback) {

    mCallback = callback;

    if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
        callback.onScannerUnavailable(this);
        return;
    }

    mHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            stopScan();
        }
    }, SCAN_PERIOD);

    Log.i("SensortagScanner", "Starting scan...");

    mScanning = true;

    // ////////////POUR API 21//////////////
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        mBluetoothAdapter.getBluetoothLeScanner().startScan(scanCallback);
    }

    // /////////POUR API <18////////////////
    else {
        mBluetoothAdapter.startLeScan(mLeScanCallback);
    }
}

Upvotes: 2

Views: 1421

Answers (2)

Footjy
Footjy

Reputation: 269

try using the method for Android 5 like in the snippet below. It might help. If it does not, please show more of your code and the error you have when the crash happens.

First, you need a callback, so initialize it correctly depending on the android version.

private void initScanCallback(){
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        initCallbackLollipop();
    }else{
        initScanCallbackSupport();
    }
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void initCallbackLollipop(){
    if(scanCallback != null) return;
    this.scanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);
            //Do whatever you want
        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            super.onBatchScanResults(results);
            Log.d(TAG, "Batch scan results: ");
            for (ScanResult result: results){
                Log.d(TAG, "Batch scan result: " + result.toString());
                //Do whatever you want
            }
        }

        @Override
        public void onScanFailed(int errorCode) {
            super.onScanFailed(errorCode);
            Log.d(TAG, "Scan failed");
        }
    };
}

private void initScanCallbackSupport(){
    if(callback != null) return;
    this.callback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(final BluetoothDevice device, int rssi, final byte[] scanRecord) {
            String address = device.toString();
            String name = device.getName();

            // parse uuids according to another stackoverflow post
            //List<UUID> uuids = parseUuids(scanRecord);

            // TODO Compare detected UUIDs with the uuidFilter
            //for(UUID discUUID : uuids)
            //    for(UUID uuid : BLEScanService.this.uuidFilter)
            //        if(discUUID.equals(uuid))
                        BLEScanService.this.scanListener.onDeviceScanned(address, name, uuids, rssi);
        }
    };
}

Then you can start the scan according to the android version:

public void startScanWithServices(List<String> uuidFilters){
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        scanLollipop(uuidFilters);
    }else{
        scanSupport(uuidFilters);
    }

    // Store filters for later filtering
    int size = uuidFilters.size();
    this.uuidFilter = new ArrayList<UUID>();
    for(int i = 0; i<size; i++){
        this.uuidFilter.add(UUID.fromString(uuidFilters.get(i)));
    }

    if(BuildConfig.DEBUG) Log.d(TAG, "BLE Scan started");
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void scanLollipop(List<String> uuidFilters){
    if(scanCallback == null)
        initCallbackLollipop();

    List<ScanFilter> filters = new ArrayList<ScanFilter>();

    ScanSettings settings = new ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) // or BALANCED previously
            .setReportDelay(0)
            .build();

    bluetoothAdapter.getBluetoothLeScanner().startScan(filters, settings, scanCallback);
    //bluetoothAdapter.getBluetoothLeScanner().startScan(scanCallback);
}

private void scanSupport(List<String> uuidFilters){
    if(callback == null)
        initScanCallbackSupport();

    //start scan
    //boolean success = bluetoothAdapter.startLeScan(uuids, callback);

    boolean success = bluetoothAdapter.startLeScan(callback);

    //check scan success
    if(!success) {
        if(BuildConfig.DEBUG) Log.d(TAG, "BLE Scan failed");
        scanListener.onScanFinished();
    }
}

And then you can stop the scan like this:

public void stopScan(){
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        // Stop scan and flush pending scan
        bluetoothAdapter.getBluetoothLeScanner().flushPendingScanResults(scanCallback);
        bluetoothAdapter.getBluetoothLeScanner().stopScan(scanCallback);
    }else{
        bluetoothAdapter.stopLeScan(callback);
    }

    if(BuildConfig.DEBUG) Log.d(TAG, "BLE Scan stopted");
}

Upvotes: 5

maciej
maciej

Reputation: 357

Check your manifest file. You should have these permissions

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

Upvotes: 0

Related Questions