ScanCallback никогда не выполняется в Android-приложении Bluetooth для сканирования устройств с низким энергопотреблением (BLE) - PullRequest
0 голосов
/ 19 мая 2019

Одной из особенностей приложения, которое я разрабатываю, является синхронизация данных с устройством с поддержкой BLE.

Я разрабатываю функциональность Bluetooth в отдельном приложении (это можно увидеть в приведенном ниже коде) и включу его в основное приложение, как только оно заработает.

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

Я прочитал документацию для разработчиков Android на https://developer.android.com/guide/topics/connectivity/bluetooth-le и прочитал похожие вопросы о переполнении стека, например, на Android BLE. Как вызывается метод onScanResult в ScanCallback? без успех.

Устройство, на котором запущено приложение, имеет версию Android 9 (API 28), и я уверен, что устройства BLE в радиусе действия могут быть обнаружены (я проверял другие приложения и встроенный поиск Bluetooth).

В манифесте я дал разрешение BLUETOOTH, BLUETOOTH_ADMIN, ACCESS_FINE_LOCATION и ACCESS_COARSE_LOCATION. Я убедился, что мое местоположение включено, когда я запускаю код, но все не имеют преимуществ.

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_ENABLE_BT = 0;
    private static final int REQUEST_DISCOVERABLE_BT = 0;
    private static final long SCAN_PERIOD = 20000;
    private String TAG = "Tag: ";

    private BluetoothAdapter mBluetoothAdapter;
    private boolean mScanning;
    private Handler mHandler;

    private ArrayList<BluetoothDevice> mScannedDevices;

    private ScanCallback mLeScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);

            System.out.println("BLE// onScanResult");
            Log.i("callbackType", String.valueOf(callbackType));
            Log.i("result", result.toString());
            Log.i("Device Name: ", result.getDevice().getName());

            BluetoothDevice btDevice = result.getDevice();
            mScannedDevices.add(btDevice);
        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            super.onBatchScanResults(results);

            System.out.println("BLE// onBatchScanResults");
            for (ScanResult sr : results) {
                Log.i("ScanResult - Results", sr.toString());
            }
        }

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

            System.out.println("BLE// onScanFailed");
            Log.e("Scan Failed", "Error Code: " + errorCode);
        }
    };

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

        // Initialise variables
        mScannedDevices = new ArrayList<>();
        mHandler = new Handler();

        // Initializes Bluetooth adapter.
        final BluetoothManager bluetoothManager =
                (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();

        // Check if device supports Bluetooth
        if (mBluetoothAdapter == null) {
            Toast.makeText(this, "Device DOES NOT support Bluetooth", Toast.LENGTH_LONG).show();
            // Disable bluetooth interactivity
            // ...
        } else {
            Toast.makeText(this, "Device DOES support Bluetooth", Toast.LENGTH_LONG).show();
        }

    }

    public void btOn(View v) {
        // Enable Bluetooth
        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            Toast.makeText(this, "Turned on", Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(this, "Already on", Toast.LENGTH_LONG).show();
        }
    }

    public void btOff(View v) {
        mBluetoothAdapter.disable();
        Toast.makeText(getApplicationContext(), "Turned off", Toast.LENGTH_LONG).show();
    }

    public void btDiscoverable(View v) {
        Intent enableBTVisibility = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
        startActivityForResult(enableBTVisibility, REQUEST_DISCOVERABLE_BT);
    }

    public void btSearch(View v) {
        mScannedDevices.clear();
        scanLeDevice(true);
    }

    public void btStopSearch(View v) {
        scanLeDevice(false);
    }

    private void scanLeDevice(final boolean enable) {
        // Ensure Bluetooth and Location are on
        // ...

        // Bluetooth scanner object
        final BluetoothLeScanner bluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();

        if (enable) {
            // Stops scanning after a pre-defined scan period.
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mScanning = false;
                    bluetoothLeScanner.stopScan(mLeScanCallback);
                }
            }, SCAN_PERIOD);

            mScanning = true;
            bluetoothLeScanner.startScan(mLeScanCallback);
        } else {
            mScanning = false;
            bluetoothLeScanner.stopScan(mLeScanCallback);
        }
    }

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

        scanLeDevice(false);
        mScannedDevices.clear();
    }

}

Я ожидаю, что mLeScanCallback будет выполнено, однако это никогда не выполняется (я проверил точки останова в режиме отладки и проверил журналы).

Я никогда раньше не работал с Bluetooth в Android, поэтому боюсь, что я могу неправильно понять, как он работает.

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