【问题标题】:ScanCallback is Never Executed in Android Bluetooth Low Energy (BLE) Device Scanning App在 Android 蓝牙低功耗 (BLE) 设备扫描应用程序中从不执行 ScanCallback
【发布时间】:2020-04-09 18:34:29
【问题描述】:

我正在开发的应用程序的一项功能涉及与支持 BLE 的设备同步数据。

我正在一个单独的应用程序中开发蓝牙功能(可以在下面的代码中看到),一旦它工作,我会将它包含在主应用程序中。

我的问题与扫描 BLE 设备有关。当我执行我的代码时,它永远不会执行 LE ScanCallback,所以我显然无法继续传输数据等。

我已经阅读了https://developer.android.com/guide/topics/connectivity/bluetooth-le 的 Android 开发者文档,并且我已经阅读了有关 Stack Overflow 的类似问题,例如 Android BLE- How is onScanResult method being called in ScanCallback? 上的这个问题,但没有成功。

运行该应用程序的设备具有 Android 版本 9 (API 28),我确信范围内的 BLE 设备是可发现的(我已检查其他应用程序和内置蓝牙搜索)。

在清单中,我已授予BLUETOOTHBLUETOOTH_ADMINACCESS_FINE_LOCATIONACCESS_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 被执行,但它永远不会被执行(我已经在调试模式下检查了停止点并且我已经检查了日志)。

我以前从未在 Android 中使用过蓝牙,所以我担心我可能会误解它的工作原理。

【问题讨论】:

    标签: java android bluetooth-lowenergy


    【解决方案1】:

    确保您请求 BLUETOOTH、BLUETOOTH_ADMIN 权限以及 ACCESS_COARSE_LOCATION 或 ACCESS_FINE_LOCATION 权限。不幸的是,如果您不请求这些权限,扫描就会静默失败。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-09
    • 2014-09-29
    • 2016-06-14
    • 2014-04-23
    • 2013-11-26
    • 1970-01-01
    • 1970-01-01
    • 2021-10-27
    相关资源
    最近更新 更多