由于棉花糖使用 BluetoothAdapter.getDefaultAdapter().startDiscovery(); 更新蓝牙发现;被打破

Since marshmallow update Bluetooth discovery using BluetoothAdapter.getDefaultAdapter().startDiscovery(); is broken

我有一个使用蓝牙并连接到设备的应用程序,使用 BluetoothAdapter.getDefaultAdapter().startDiscovery(); 找不到任何设备;它在发现之前运行良好。也试过其他应用程序,它也不适用于其他应用程序。但是我尝试配对的设备 (Arduino bt-module) 可以在 Android 设置中找到。知道我可以尝试什么吗?我实现了 http://developer.android.com/guide/topics/connectivity/bluetooth.html 中描述的所有内容,并且在更新之前有效。

蓝牙适配器已在 Android 6.0

中更改

您需要设置权限ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION权限,需要使用 BluetoothLeScanner.startScan() 方法开始扫描。

以下是更改日志中的描述:

为了向用户提供更好的数据保护,在 Android 6.0 中,Android 删除了使用 Wi-Fi 和蓝牙 APIs 的应用对设备本地硬件标识符的编程访问. WifiInfo.getMacAddress() 和 BluetoothAdapter.getAddress() 方法现在 return 为 02:00:00:00:00:00.

的常量值

要通过蓝牙和 Wi-Fi 扫描访问附近外部设备的硬件标识符,您的应用现在必须具有 ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION 权限:

WifiManager.getScanResults()
BluetoothDevice.ACTION_FOUND
BluetoothLeScanner.startScan()

注意:当设备 运行 Android 6.0(API 级别 23)启动后台 Wi-Fi 或蓝牙扫描时,外部设备可以看到该操作源自随机 MAC 地址。

您可以从这里获得更多详细信息 link: http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html

只需在“设置”中启用“位置”即可,效果很好!!

从 API 级别 23 开始,蓝牙发现也需要位置访问权限(ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION)。

https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id

并且仅在清单文件中添加权限是不够的,因为权限属于 "dangerous" 保护级别。 需要用户同意才能在 运行 时请求权限。

已将权限添加到 AndroidManifest.xml:

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

在 运行 时间请求 ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION:

private void accessLocationPermission() {
    int accessCoarseLocation = checkSelfPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION);
    int accessFineLocation   = checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION);

    List<String> listRequestPermission = new ArrayList<String>();

    if (accessCoarseLocation != PackageManager.PERMISSION_GRANTED) {
        listRequestPermission.add(android.Manifest.permission.ACCESS_COARSE_LOCATION);
    }
    if (accessFineLocation != PackageManager.PERMISSION_GRANTED) {
        listRequestPermission.add(android.Manifest.permission.ACCESS_FINE_LOCATION);
    }

    if (!listRequestPermission.isEmpty()) {
        String[] strRequestPermission = listRequestPermission.toArray(new String[listRequestPermission.size()]);
        requestPermissions(strRequestPermission, REQUEST_CODE_LOC);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case REQUEST_CODE_LOC:
            if (grantResults.length > 0) {
                for (int gr : grantResults) {
                    // Check if request is granted or not
                    if (gr != PackageManager.PERMISSION_GRANTED) {
                        return;
                    }
                }

                //TODO - Add your code here to start Discovery

            }
            break;
        default:
            return;
    }
}

有关权限的更多详细信息: https://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en