在 Android 6.0上需要启用位置低耗电蓝牙扫描

升级到 Android 版本6.0后,低耗电蓝牙扫描只有在设备上启用位置服务的情况下才能工作。请参阅此处: 安卓6.0低耗电蓝牙的 startScan 没有找到任何设备

基本上,您需要为应用程序和手机启用许可。这是窃听器吗?是否有可能在没有实际启用定位服务的情况下进行扫描?我不想为我所有的应用程序定位。

剪辑 我没有提到我正在使用 API 21中提供的 BluetoothLeScanner中的 startScan()方法。我对此方法需要的清单中的过程和精细位置权限没有意见。我只是不希望我的应用程序的用户必须在他们的设备(GPS 等)上启用定位服务才能使用我的应用程序。

Previously, the startScan() method would run and return results with the Location services disabled on the phone. On Marshmallow, however, the same application would "scan" but silently failed and returned no results when location services were not enabled on the phone and course/fine location permissions were still in the manifest.

102885 次浏览

好的,我已经查看了在 Eclipse 中编写的代码,并且在那里使用 startScan (API 21)函数,而没有在清单文件中声明位置信息。我还是会得到正式的复试。 你试过在没有位置声明的情况下运行代码吗? 另一方面,您可以使用不推荐的 startLeScan (API 18) ,它不需要这些权限。然而,在我看来,使用 API 18方法搜索和阅读服务中所需的特征要复杂得多。

我也在清单上尝试了这个,但没有请求许可,不知道为什么。启动时是否提示应用程序获得位置权限?如果不是,我们需要 请求运行时权限

你也可以检查一下你的应用程序是否正常工作:

打开设置 > 应用程序 > 你的应用程序 > 权限 启用 Location,然后尝试扫描结果。

Location will be listed here only if you have provided ACCESS_COARSE_LOCATION on manifest.

你可以使用 BluetoothAdapter.startDiscovery()
它将扫描蓝牙智能和经典的蓝牙设备,但位置服务不需要启用。
(You still need ACCESS_COARSE_LOCATION permissions on Android 6.)

您可以在已找到的设备上调用 BluetoothDevice.getType来过滤蓝牙智能/低能耗设备。

我发现,在 Android 6之后,您必须授予 ACCESS _ COARSE _ LOCATION 权限。但是在一些设备上也需要开启你的手机定位服务(GPS) ,这样你就可以发现外围设备。我发现使用 Nexus 5x 和 Android 7.0。

我解决这个问题的方法是在 Gradle 文件中将 targetSdkVersion设置为 22。 您必须在清单中声明 ACCESS_COARSE_LOCATION,但是,即使用户拒绝 App Settings 的此权限,仍然可以进行 ABLE 扫描。

这只是一个避免请求位置权限的黑客攻击,最好是针对最新的 Android 版本。

Edit

This solution should no longer be used as Google Play will require that new apps target at least Android 8.0 (API level 26). Apps should request for location permission for BLE scanning.

不,这不是窃听器。

这个 问题被带到谷歌,在那里他们回应说,这是预期的行为,他们不会修复它。他们指示开发人员到 这个网站,在那里它指出现在需要位置权限才能访问硬件标识符。现在开发人员有责任让他们的用户了解需求。

然而,在这个问题中,它没有解决为什么需要定位服务(GPS 等) ,而且似乎他们也不打算重新讨论这个问题来解释这个问题,因为它已经被标记为预期的行为。

To answer the second part of the question: Yes, it is possible to scan without enabling Location services. You can do a Bluetooth classic scan using BluetoothAdapter.getDefaultAdapter().startDiscovery() and that will work with Location services off. This will discover all Bluetooth devices, BLE and otherwise. However, BLE devices won't have a scan record that they would have had if they were seen as a result of startScan().

从我最近在 android 8.0上注意到的情况来看,不需要打开您的 GPS 来做一个 ABLE 扫描,但是您必须在清单中声明它,但是用户必须允许这个权限。

Android will prompt the user to allow location permission when you attempt to do a scan with startScan() method. Your scan will fail if the permission is not allowed.

You can scan BLE devices without location access using CompanionDeviceManager (API26). Https://developer.android.com/reference/android/companion/companiondevicemanager.

ACCESS_COARSE_LOCATION添加到舱单后, 请求运行时许可:

 public void checkPermission() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && checkSelfPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {


} else {
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,}, 1);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
} else {
checkPermission();
}
}

为我工作!