java - 无法在 Android 中扫描或发现 BT 和 BLE 设备

标签 java android bluetooth bluetooth-lowenergy

我是 Java 和 Android 方面的新手。我正在尝试创建一个测试应用程序来监听附近的 BLE 和 BT 设备。我有另一个设备,我在其中编写了一些逻辑来广播其 BLE 信标。我使用 Playstore 应用程序验证了它。现在我正在尝试在 Android 上编写自己的应用程序。 我一直在阅读 Android 开发者页面来寻求指导。我确实遵循了以下页面的每一步

https://developer.android.com/guide/topics/connectivity/bluetooth/setup

https://developer.android.com/guide/topics/connectivity/bluetooth/permissions

https://developer.android.com/guide/topics/connectivity/bluetooth/find-bluetooth-devices

https://developer.android.com/guide/topics/connectivity/bluetooth/find-ble-devices

另外,请注意,我使用了 Android 开发者页面中的BARE MINIMUM CODE,所以这就是我所做的。

<强>1。首先,我在 AndroidManifest 下添加了我的权限

注 1:我正在将此应用部署到运行 Android 11 的手机

注2:所有这些代码都写在MainActivity 中。我还没有创建任何其他 Activity 类

<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

<强>2。接下来我检查我的 BT 是否已启用。

        if (bluetoothAdapter == null) {
            blefinder.append("\nDEVICE DOES NOT SUPPORT BLUETOOTH");
        }
        else {
            blefinder.append("\nDEVICE SUPPORTS BLUETOOTH");
        }

我收到成功消息,表明 BT 当然已启用

<强>3。接下来我检查我的设备是否支持 BLE

        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            blefinder.append("\nBLE NOT SUPPORTED ON THIS DEVICE : ");
            finish();
        }
        else{
            blefinder.append("\nBLE IS SUPPORTED ON THIS DEVICE : ");
        }

我收到支持 BLE 的消息

<强>4。接下来,我列出我已经配对/绑定(bind)的设备

为此,我在上述步骤之后立即在 onCreate() 本身中调用 ListPairedAndBondedDevices(); 。函数定义如下。

private void ListPairedAndBondedDevices(){
        @SuppressLint("MissingPermission") Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();

        if (pairedDevices.size() > 0) {
            // There are paired devices. Get the name and address of each paired device.
            blefinder.append("\nPAIRED/BONDED DEVICES");
            for (BluetoothDevice device : pairedDevices) {
                blefinder.append("\n" + device.getName() + " | " + device.getAddress());
            }
        }
    }

这也像一个魅力,打印出我的配对设备。接下来的两部分是我面临问题的地方。

<强>5。问题步骤|第 1 部分:

在这里,我注册了一个广播接收器来发现附近的所有 BT 设备。我已解开我的 BT 耳机并将其保持在配对模式以验证这一点。

ListPairedAndBondedDevices(); // From previous code snippet
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); // New code statement 
registerReceiver(BTReceiver, filter);// New code statement 

广播接收器实现

    private final BroadcastReceiver BTReceiver = new BroadcastReceiver() {
        @SuppressLint("MissingPermission")
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                // Discovery has found a device. Get the BluetoothDevice
                // object and its info from the Intent.
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                blefinder.append("\n" + device.getName() + " | " + device.getAddress());

            }
        }
    };

所以这部分不起作用:(

如果您看到上面的内容,我会在列出已配对的设备后立即在 onCreate 中注册 BTReceiver(通过调用 ListPairedAndBondedDevices()) .

当我运行调试器时,这个广播接收器永远不会被调用。

<强>6。问题步骤|第 2 部分:

紧接着,我尝试通过调用 scanLeDevice() 来扫描 BLE 设备

ListPairedAndBondedDevices(); // From previous snippet
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); // From previous snippet
registerReceiver(BTReceiver, filter);// From previous snippet
scanLeDevice(); // ---------------->>> CALLING THIS FUNCTION TO SCAN FOR BLE DEVICES

scanLeDevice()的实现

    private void scanLeDevice() {
        if (!scanning) {
            // Stops scanning after a predefined scan period.
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    scanning = false;
                    bluetoothLeScanner.stopScan(leScanCallback);
                    blefinder.append("\nSTOPPING BLE SCAN... TIMEOUT REACHED");
                }
            }, SCAN_PERIOD);

            scanning = true;
            bluetoothLeScanner.startScan(leScanCallback);
        } else {
            scanning = false;
            bluetoothLeScanner.stopScan(leScanCallback);
            blefinder.append("\nSTOPPING BLE SCAN");
        }
    }

不幸的是,这也失败了。调试器告诉我这部分代码正在被调用。 在 SCAN_PERIOD(我设置的超时)30 秒后,我收到扫描已停止的消息 (STOPPING BLE SCAN)

现在我也实现了leScanCallback(即设备扫描回调)

    private ScanCallback leScanCallback =
            new ScanCallback() {
                @Override
                public void onScanResult(int callbackType, ScanResult result) {
                    super.onScanResult(callbackType, result);
                    blefinder.append("SOMETHING GOT SCANNED?");
                    blefinder.append("\n"+result.getDevice().toString());
                //  leDeviceListAdapter.addDevice(result.getDevice());
                //  leDeviceListAdapter.notifyDataSetChanged();
                }
            };

请注意,我没有使用 ListAdapter 因为我不知道这个概念。因此,对于初学者来说,我只是尝试将结果转储到由 blefinder 表示的 TextView 中。此 blefinder 打印所有其他文本,因此该 TextView 变量没有任何问题。当我使用调试器运行时,即使在执行 scanLeDevice() 函数后 30 秒后,它也根本没有进入 leScanCallback 代码定义。

我在这里有点迷失。我可能遗漏或做错了什么吗?它应该是一个简单的列表,列出我附近的 ble/bt 设备。

如果我错过了任何进一步的信息,我很乐意分享。请在评论中告诉我。

最佳答案

首先,您应该在“设置”应用 > 应用 > 权限中检查您的应用是否已被授予位置权限。一些permissions (如 ACCESS_*_LOCATION 和 BLUETOOTH_ADMIN)需要为 requested在运行时并由用户通过弹出窗口授予。通常,当尝试执行需要您的应用没有的权限的代码时,您应该收到 SecurityException 或 logcat 警告,但 Android 跳过错误处理的情况并不罕见。

考虑使用this method开始扫描,以检查其结果代码,以获取有关正在发生(未发生)的情况的潜在附加信息。

您还可以通过记录 BTReceiver.onReceive() 中收到的所有操作(而不仅仅是找到的操作)来获得一些线索。

最后检查您设备上的位置设置,以确保蓝牙扫描已打开(设置应用程序 > 位置 > wifi 和蓝牙扫描)

关于java - 无法在 Android 中扫描或发现 BT 和 BLE 设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71814870/

相关文章:

android - 检测用户何时关闭软键盘

java - 如何使用按位运算检查置换的十六进制整数是否与另一个匹配(性能优化)

android - 低功耗蓝牙安全性如何在 Android 应用程序和 BLE 设备之间发挥作用?

ios - 在文本字段中键入时不会禁用 UIKeyCommand (Swift)

java - 在调用 session.gettransaction 之前,我是否必须确保它存在?

java - JAXB 返回 null 而不是空字符串

ScrollView 扩展时 Android Studio 自动滚动到底部?

android - 在 Android 中启用禁用蓝牙

Java EE 7 动态用户角色

java - 适配器上的 notifydataSetChanged 将更新新项目,但不会更新现有项目