Java Code Examples for com.polidea.rxandroidble2.exceptions.BleScanException

The following examples show how to use com.polidea.rxandroidble2.exceptions.BleScanException. These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
@Override
public void verify(boolean checkLocationProviderState) {
    scanPreconditionVerifierApi18.verify(checkLocationProviderState);

    /*
     * Android 7.0 (API 24) introduces an undocumented scan throttle for applications that try to scan more than 5 times during
     * a 30 second window. More on the topic: https://blog.classycode.com/undocumented-android-7-ble-behavior-changes-d1a9bd87d983
     */

    // TODO: [DS] 27.06.2017 Think if persisting this information through Application close is needed
    final int oldestCheckTimestampIndex = getOldestCheckTimestampIndex();
    final long oldestCheckTimestamp = previousChecks[oldestCheckTimestampIndex];
    final long currentCheckTimestamp = timeScheduler.now(TimeUnit.MILLISECONDS);

    if (currentCheckTimestamp - oldestCheckTimestamp < EXCESSIVE_SCANNING_PERIOD) {
        throw new BleScanException(
                BleScanException.UNDOCUMENTED_SCAN_THROTTLE,
                new Date(oldestCheckTimestamp + EXCESSIVE_SCANNING_PERIOD)
        );
    }
    previousChecks[oldestCheckTimestampIndex] = currentCheckTimestamp;
}
 
Example 2
Source Project: RxAndroidBle   Source File: BackgroundScannerImpl.java    License: Apache License 2.0 6 votes vote down vote up
@RequiresApi(26 /* Build.VERSION_CODES.O */)
@Override
public void scanBleDeviceInBackground(@NonNull PendingIntent callbackIntent, ScanSettings scanSettings, ScanFilter... scanFilters) {
    if (Build.VERSION.SDK_INT < 26 /* Build.VERSION_CODES.O */) {
        RxBleLog.w("PendingIntent based scanning is available for Android O and higher only.");
        return;
    }
    if (!rxBleAdapterWrapper.isBluetoothEnabled()) {
        RxBleLog.w("PendingIntent based scanning is available only when Bluetooth is ON.");
        throw new BleScanException(BleScanException.BLUETOOTH_DISABLED);
    }

    RxBleLog.i("Requesting pending intent based scan.");
    final List<android.bluetooth.le.ScanFilter> nativeScanFilters = scanObjectsConverter.toNativeFilters(scanFilters);
    final android.bluetooth.le.ScanSettings nativeScanSettings = scanObjectsConverter.toNativeSettings(scanSettings);
    final int scanStartResult = rxBleAdapterWrapper.startLeScan(nativeScanFilters, nativeScanSettings, callbackIntent);

    if (scanStartResult != NO_ERROR) {
        final BleScanException bleScanException = new BleScanException(scanStartResult);
        RxBleLog.w(bleScanException, "Failed to start scan"); // TODO?
        throw bleScanException;
    }
}
 
Example 3
Source Project: RxAndroidBle   Source File: BackgroundScannerImpl.java    License: Apache License 2.0 6 votes vote down vote up
@Override
public List<ScanResult> onScanResultReceived(@NonNull Intent intent) {
    final int callbackType = intent.getIntExtra(BluetoothLeScanner.EXTRA_CALLBACK_TYPE, -1);
    final int errorCode = intent.getIntExtra(BluetoothLeScanner.EXTRA_ERROR_CODE, NO_ERROR);
    final List<android.bluetooth.le.ScanResult> nativeScanResults = extractScanResults(intent);
    ArrayList<ScanResult> scanResults = new ArrayList<>();

    if (errorCode == NO_ERROR) {
        for (android.bluetooth.le.ScanResult result : nativeScanResults) {
            scanResults.add(convertScanResultToRxAndroidBLEModel(callbackType, result));
        }

        return scanResults;
    } else {
        throw new BleScanException(errorCode);
    }
}
 
Example 4
Source Project: RxAndroidBle   Source File: ScanOperationApi21.java    License: Apache License 2.0 6 votes vote down vote up
@BleScanException.Reason
static int errorCodeToBleErrorCode(int errorCode) {
    switch (errorCode) {
        case ScanCallback.SCAN_FAILED_ALREADY_STARTED:
            return BleScanException.SCAN_FAILED_ALREADY_STARTED;
        case ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED:
            return BleScanException.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED;
        case ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED:
            return BleScanException.SCAN_FAILED_FEATURE_UNSUPPORTED;
        case ScanCallback.SCAN_FAILED_INTERNAL_ERROR:
            return BleScanException.SCAN_FAILED_INTERNAL_ERROR;
        case 5: // ScanCallback.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES
            return BleScanException.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES;
        default:
            RxBleLog.w("Encountered unknown scanning error code: %d -> check android.bluetooth.le.ScanCallback");
            return BleScanException.UNKNOWN_ERROR_CODE;
    }
}
 
Example 5
Source Project: RxAndroidBle   Source File: ScanOperation.java    License: Apache License 2.0 6 votes vote down vote up
@Override
final protected void protectedRun(final ObservableEmitter<SCAN_RESULT_TYPE> emitter, QueueReleaseInterface queueReleaseInterface) {

    final SCAN_CALLBACK_TYPE scanCallback = createScanCallback(emitter);

    try {
        emitter.setCancellable(new Cancellable() {
            @Override
            public void cancel() {
                RxBleLog.i("Scan operation is requested to stop.");
                stopScan(rxBleAdapterWrapper, scanCallback);
            }
        });
        RxBleLog.i("Scan operation is requested to start.");
        boolean startLeScanStatus = startScan(rxBleAdapterWrapper, scanCallback);

        if (!startLeScanStatus) {
            emitter.tryOnError(new BleScanException(BleScanException.BLUETOOTH_CANNOT_START));
        }
    } catch (Throwable throwable) {
        RxBleLog.w(throwable, "Error while calling the start scan function");
        emitter.tryOnError(new BleScanException(BleScanException.BLUETOOTH_CANNOT_START, throwable));
    } finally {
        queueReleaseInterface.release();
    }
}
 
Example 6
Source Project: RxAndroidBle   Source File: RxBleClientImpl.java    License: Apache License 2.0 6 votes vote down vote up
/**
 * This {@link Observable} will not emit values by design. It may only emit {@link BleScanException} if
 * bluetooth adapter is turned down.
 */
<T> Observable<T> bluetoothAdapterOffExceptionObservable() {
    return rxBleAdapterStateObservable
            .filter(new Predicate<BleAdapterState>() {
                @Override
                public boolean test(BleAdapterState state) {
                    return state != BleAdapterState.STATE_ON;
                }
            })
            .firstElement()
            .flatMap(new Function<BleAdapterState, MaybeSource<T>>() {
                @Override
                public MaybeSource<T> apply(BleAdapterState bleAdapterState) {
                    return Maybe.error(new BleScanException(BleScanException.BLUETOOTH_DISABLED));
                }
            })
            .toObservable();
}
 
Example 7
Source Project: RxAndroidBle   Source File: BackgroundScanActivity.java    License: Apache License 2.0 6 votes vote down vote up
private void scanBleDeviceInBackground() {
    if (VERSION.SDK_INT >= VERSION_CODES.O) {
        try {
            rxBleClient.getBackgroundScanner().scanBleDeviceInBackground(
                    callbackIntent,
                    new ScanSettings.Builder()
                            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                            .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
                            .build(),
                    new ScanFilter.Builder()
                            .setDeviceAddress("5C:31:3E:BF:F7:34")
                            // add custom filters if needed
                            .build()
            );
        } catch (BleScanException scanException) {
            Log.w("BackgroundScanActivity", "Failed to start background scan", scanException);
            ScanExceptionHandler.handleException(this, scanException);
        }
    }
}
 
Example 8
Source Project: RxAndroidBle   Source File: ScanExceptionHandler.java    License: Apache License 2.0 6 votes vote down vote up
/**
 * Show toast with error message appropriate to exception reason.
 *
 * @param context   current Activity context
 * @param exception BleScanException to show error message for
 */
public static void handleException(final Activity context, final BleScanException exception) {
    final String text;
    final int reason = exception.getReason();

    // Special case, as there might or might not be a retry date suggestion
    if (reason == BleScanException.UNDOCUMENTED_SCAN_THROTTLE) {
        text = getUndocumentedScanThrottleErrorMessage(context, exception.getRetryDateSuggestion());
    } else {
        // Handle all other possible errors
        final Integer resId = ERROR_MESSAGES.get(reason);
        if (resId != null) {
            text = context.getString(resId);
        } else {
            // unknown error - return default message
            Log.w("Scanning", String.format("No message found for reason=%d. Consider adding one.", reason));
            text = context.getString(R.string.error_unknown_error);
        }
    }

    Log.w("Scanning", text, exception);
    Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
}
 
Example 9
Source Project: xDrip   Source File: PendiqService.java    License: GNU General Public License v3.0 6 votes vote down vote up
private synchronized void onScanFailure(Throwable throwable) {
    UserError.Log.d(TAG, "onScanFailure: " + throwable);
    if (throwable instanceof BleScanException) {
        final String info = handleBleScanException((BleScanException) throwable);
        //   lastScanError = info;
        UserError.Log.d(TAG, info);
        if (((BleScanException) throwable).getReason() == BleScanException.BLUETOOTH_DISABLED) {
            // Attempt to turn bluetooth on
            if (ratelimit("bluetooth_toggle_on", 30)) {
                UserError.Log.d(TAG, "Pause before Turn Bluetooth on");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    //
                }
                UserError.Log.e(TAG, "Trying to Turn Bluetooth on");
                JoH.setBluetoothEnabled(xdrip.getAppContext(), true);
            }
        }
    }
    // TODO count scan duration
    stopScan();
    releaseWakeLock();
    background_automata(5000);
}
 
Example 10
Source Project: xDrip-plus   Source File: PendiqService.java    License: GNU General Public License v3.0 6 votes vote down vote up
private synchronized void onScanFailure(Throwable throwable) {
    UserError.Log.d(TAG, "onScanFailure: " + throwable);
    if (throwable instanceof BleScanException) {
        final String info = handleBleScanException((BleScanException) throwable);
        //   lastScanError = info;
        UserError.Log.d(TAG, info);
        if (((BleScanException) throwable).getReason() == BleScanException.BLUETOOTH_DISABLED) {
            // Attempt to turn bluetooth on
            if (ratelimit("bluetooth_toggle_on", 30)) {
                UserError.Log.d(TAG, "Pause before Turn Bluetooth on");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    //
                }
                UserError.Log.e(TAG, "Trying to Turn Bluetooth on");
                JoH.setBluetoothEnabled(xdrip.getAppContext(), true);
            }
        }
    }
    // TODO count scan duration
    stopScan();
    releaseWakeLock();
    background_automata(5000);
}
 
Example 11
@Override
public void verify(boolean checkLocationProviderState) {
    if (!rxBleAdapterWrapper.hasBluetoothAdapter()) {
        throw new BleScanException(BleScanException.BLUETOOTH_NOT_AVAILABLE);
    } else if (!rxBleAdapterWrapper.isBluetoothEnabled()) {
        throw new BleScanException(BleScanException.BLUETOOTH_DISABLED);
    } else if (!locationServicesStatus.isLocationPermissionOk()) {
        throw new BleScanException(BleScanException.LOCATION_PERMISSION_MISSING);
    } else if (checkLocationProviderState && !locationServicesStatus.isLocationProviderOk()) {
        throw new BleScanException(BleScanException.LOCATION_SERVICES_DISABLED);
    }
}
 
Example 12
Source Project: RxAndroidBle   Source File: ScanReceiver.java    License: Apache License 2.0 5 votes vote down vote up
@RequiresApi(26 /* Build.VERSION_CODES.O */)
@Override
public void onReceive(Context context, Intent intent) {
    BackgroundScanner backgroundScanner = SampleApplication.getRxBleClient(context).getBackgroundScanner();

    try {
        final List<ScanResult> scanResults = backgroundScanner.onScanResultReceived(intent);
        Log.i("ScanReceiver", "Scan results received: " + scanResults);
    } catch (BleScanException exception) {
        Log.w("ScanReceiver", "Failed to scan devices", exception);
    }
}
 
Example 13
Source Project: xDrip   Source File: ScanMeister.java    License: GNU General Public License v3.0 5 votes vote down vote up
protected synchronized void onScanFailure(Throwable throwable) {
    UserError.Log.d(TAG, "onScanFailure: " + throwable);
    if (throwable instanceof BleScanException) {
        final String info = HandleBleScanException.handle(TAG, (BleScanException) throwable);
        UserError.Log.d(TAG, "Scan failure: " + info);
        if (!lastFailureReason.equals(info) || JoH.ratelimit("scanmeister-fail-error", 600)) {
            UserError.Log.e(TAG, "Failed to scan: " + info);
            lastFailureReason = info;
        }
        if (((BleScanException) throwable).getReason() == BleScanException.BLUETOOTH_DISABLED) {
            // Attempt to turn bluetooth on
            if (ratelimit("bluetooth_toggle_on", 30)) {
                UserError.Log.d(TAG, "Pause before Turn Bluetooth on");
                JoH.threadSleep(2000);
                UserError.Log.e(TAG, "Trying to Turn Bluetooth on");
                JoH.setBluetoothEnabled(xdrip.getAppContext(), true);
            }
        }
        processCallBacks(address, SCAN_FAILED_CALLBACK);
    } else if (throwable instanceof TimeoutException) {
        // note this code path not always reached - see inevitable task
        processCallBacks(address, SCAN_TIMEOUT_CALLBACK);
    }

    stopScan("Scan failure");
    releaseWakeLock();
}
 
Example 14
Source Project: xDrip   Source File: ScanMeister.java    License: GNU General Public License v3.0 5 votes vote down vote up
protected synchronized void onScanFailure(Throwable throwable) {
    UserError.Log.d(TAG, "onScanFailure: " + throwable);
    if (throwable instanceof BleScanException) {
        final String info = HandleBleScanException.handle(TAG, (BleScanException) throwable);
        UserError.Log.d(TAG, "Scan failure: " + info);
        if (!lastFailureReason.equals(info) || JoH.ratelimit("scanmeister-fail-error", 600)) {
            UserError.Log.e(TAG, "Failed to scan: " + info);
            lastFailureReason = info;
        }
        if (((BleScanException) throwable).getReason() == BleScanException.BLUETOOTH_DISABLED) {
            // Attempt to turn bluetooth on
            if (ratelimit("bluetooth_toggle_on", 30)) {
                UserError.Log.d(TAG, "Pause before Turn Bluetooth on");
                JoH.threadSleep(2000);
                UserError.Log.e(TAG, "Trying to Turn Bluetooth on");
                JoH.setBluetoothEnabled(xdrip.getAppContext(), true);
            }
        }
        processCallBacks(address, SCAN_FAILED_CALLBACK);
    } else if (throwable instanceof TimeoutException) {
        // note this code path not always reached - see inevitable task
        processCallBacks(address, SCAN_TIMEOUT_CALLBACK);
    }

    stopScan("Scan failure");
    releaseWakeLock();
}
 
Example 15
Source Project: xDrip   Source File: BackgroundScanReceiver.java    License: GNU General Public License v3.0 5 votes vote down vote up
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onReceive(Context context, Intent intent) {

    final String action = intent.getAction();

    android.util.Log.d("BackgroundScanReceiver", "GOT SCAN INTENT!! " + action);

    if (action != null && action.equals(ACTION_NAME)) {

        String caller = intent.getStringExtra(CALLING_CLASS);
        if (caller == null) caller = this.getClass().getSimpleName();

        // TODO by class name?
        final BackgroundScanner backgroundScanner = RxBleProvider.getSingleton().getBackgroundScanner();
        try {
            final List<ScanResult> scanResults = backgroundScanner.onScanResultReceived(intent);
            final String matchedMac = scanResults.get(0).getBleDevice().getMacAddress();
            final String matchedName = scanResults.get(0).getBleDevice().getName();
            final boolean calledBack = processCallbacks(caller, matchedMac, matchedName, SCAN_FOUND_CALLBACK);
            UserError.Log.d(caller, "Scan results received: " + matchedMac + " " + scanResults);
            if (!calledBack) {
                try {
                    // bit of an ugly fix to system wide persistent nature of background scans and lack of proper support for one hit over various android devices
                    backgroundScanner.stopBackgroundBleScan(PendingIntent.getBroadcast(xdrip.getAppContext(), 142, // must match original
                            intent, PendingIntent.FLAG_UPDATE_CURRENT));
                } catch (Exception e) {
                    //
                }
            }
        } catch (NullPointerException | BleScanException exception) {
            UserError.Log.e(caller, "Failed to scan devices" + exception);
        }

    }

    // ignore invalid actions
}
 
Example 16
Source Project: xDrip-plus   Source File: ScanMeister.java    License: GNU General Public License v3.0 5 votes vote down vote up
protected synchronized void onScanFailure(Throwable throwable) {
    UserError.Log.d(TAG, "onScanFailure: " + throwable);
    if (throwable instanceof BleScanException) {
        final String info = HandleBleScanException.handle(TAG, (BleScanException) throwable);
        UserError.Log.d(TAG, "Scan failure: " + info);
        if (!lastFailureReason.equals(info) || JoH.ratelimit("scanmeister-fail-error", 600)) {
            UserError.Log.e(TAG, "Failed to scan: " + info);
            lastFailureReason = info;
        }
        if (((BleScanException) throwable).getReason() == BleScanException.BLUETOOTH_DISABLED) {
            // Attempt to turn bluetooth on
            if (ratelimit("bluetooth_toggle_on", 30)) {
                UserError.Log.d(TAG, "Pause before Turn Bluetooth on");
                JoH.threadSleep(2000);
                UserError.Log.e(TAG, "Trying to Turn Bluetooth on");
                JoH.setBluetoothEnabled(xdrip.getAppContext(), true);
            }
        }
        processCallBacks(address, SCAN_FAILED_CALLBACK);
    } else if (throwable instanceof TimeoutException) {
        // note this code path not always reached - see inevitable task
        processCallBacks(address, SCAN_TIMEOUT_CALLBACK);
    }

    stopScan("Scan failure");
    releaseWakeLock();
}
 
Example 17
Source Project: xDrip-plus   Source File: ScanMeister.java    License: GNU General Public License v3.0 5 votes vote down vote up
protected synchronized void onScanFailure(Throwable throwable) {
    UserError.Log.d(TAG, "onScanFailure: " + throwable);
    if (throwable instanceof BleScanException) {
        final String info = HandleBleScanException.handle(TAG, (BleScanException) throwable);
        UserError.Log.d(TAG, "Scan failure: " + info);
        if (!lastFailureReason.equals(info) || JoH.ratelimit("scanmeister-fail-error", 600)) {
            UserError.Log.e(TAG, "Failed to scan: " + info);
            lastFailureReason = info;
        }
        if (((BleScanException) throwable).getReason() == BleScanException.BLUETOOTH_DISABLED) {
            // Attempt to turn bluetooth on
            if (ratelimit("bluetooth_toggle_on", 30)) {
                UserError.Log.d(TAG, "Pause before Turn Bluetooth on");
                JoH.threadSleep(2000);
                UserError.Log.e(TAG, "Trying to Turn Bluetooth on");
                JoH.setBluetoothEnabled(xdrip.getAppContext(), true);
            }
        }
        processCallBacks(address, SCAN_FAILED_CALLBACK);
    } else if (throwable instanceof TimeoutException) {
        // note this code path not always reached - see inevitable task
        processCallBacks(address, SCAN_TIMEOUT_CALLBACK);
    }

    stopScan("Scan failure");
    releaseWakeLock();
}
 
Example 18
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onReceive(Context context, Intent intent) {

    final String action = intent.getAction();

    android.util.Log.d("BackgroundScanReceiver", "GOT SCAN INTENT!! " + action);

    if (action != null && action.equals(ACTION_NAME)) {

        String caller = intent.getStringExtra(CALLING_CLASS);
        if (caller == null) caller = this.getClass().getSimpleName();

        // TODO by class name?
        final BackgroundScanner backgroundScanner = RxBleProvider.getSingleton().getBackgroundScanner();
        try {
            final List<ScanResult> scanResults = backgroundScanner.onScanResultReceived(intent);
            final String matchedMac = scanResults.get(0).getBleDevice().getMacAddress();
            final String matchedName = scanResults.get(0).getBleDevice().getName();
            final boolean calledBack = processCallbacks(caller, matchedMac, matchedName, SCAN_FOUND_CALLBACK);
            UserError.Log.d(caller, "Scan results received: " + matchedMac + " " + scanResults);
            if (!calledBack) {
                try {
                    // bit of an ugly fix to system wide persistent nature of background scans and lack of proper support for one hit over various android devices
                    backgroundScanner.stopBackgroundBleScan(PendingIntent.getBroadcast(xdrip.getAppContext(), 142, // must match original
                            intent, PendingIntent.FLAG_UPDATE_CURRENT));
                } catch (Exception e) {
                    //
                }
            }
        } catch (NullPointerException | BleScanException exception) {
            UserError.Log.e(caller, "Failed to scan devices" + exception);
        }

    }

    // ignore invalid actions
}
 
Example 19
Source Project: RxAndroidBle   Source File: ScanOperation.java    License: Apache License 2.0 4 votes vote down vote up
@Override
protected BleException provideException(DeadObjectException deadObjectException) {
    return new BleScanException(BleScanException.BLUETOOTH_DISABLED, deadObjectException);
}
 
Example 20
Source Project: RxAndroidBle   Source File: ScanActivity.java    License: Apache License 2.0 4 votes vote down vote up
private void onScanFailure(Throwable throwable) {
    if (throwable instanceof BleScanException) {
        ScanExceptionHandler.handleException(this, (BleScanException) throwable);
    }
}
 
Example 21
protected String handleBleScanException(BleScanException bleScanException) {
    return HandleBleScanException.handle(TAG, bleScanException);
}
 
Example 22
protected String handleBleScanException(BleScanException bleScanException) {
    return HandleBleScanException.handle(TAG, bleScanException);
}
 
Example 23
Source Project: RxAndroidBle   Source File: ScanPreconditionsVerifier.java    License: Apache License 2.0 votes vote down vote up
void verify(boolean checkLocationProviderState) throws BleScanException;