需要在 Android 6.0 上启用蓝牙低功耗扫描的位置
Location needs to be enabled for Bluetooth Low Energy Scanning on Android 6.0
升级到 Android 版本 6.0 蓝牙低功耗 (BLE) 扫描后,只有在设备上启用了位置服务后才能进行扫描。请参阅此处以供参考:Bluetooth Low Energy startScan on Android 6.0 does not find devices
基本上,您需要为应用程序和 phone 启用权限。这是一个错误吗?是否可以在没有实际启用位置服务的情况下进行扫描?我不想为我的所有应用程序设置位置。
编辑
我没有提到我正在使用 API 21 中提供的 BluetoothLeScanner
中的 startScan()
方法。我同意此方法需要的清单中的课程和精细位置权限。我只是不希望我的应用程序的用户必须在他们的设备(GPS 等)上启用定位服务才能使用我的应用程序。
以前,startScan()
方法将 运行 和 return 结果与 phone 上禁用的位置服务。然而,在 Marshmallow 上,当在 phone 和 course/fine 位置权限中未启用位置服务时,相同的应用程序会 "scan" 但默默地失败并且 return 没有结果清单。
好吧,我查看了用 Eclipse 编写的代码,并在那里使用了 startScan (API 21) 函数,但没有在清单文件中声明位置信息。我仍然得到适当的回调。
您是否尝试过 运行 没有位置声明的代码?
另一方面 - 您可以使用不需要这些权限的已弃用的 startLeScan (API 18)。但是,在我看来,使用 API 18 种方法在服务中搜索和读取所需的特性会更加复杂。
我也在清单上试过这个但没有请求许可,不知道为什么。您的应用程序是否在启动时提示位置权限?如果不是,我们需要 request for permission on runtime.
你也可以检查这个来测试你的应用程序是否正常工作:
打开设置 > 应用程序 > YourApplication > 权限
并启用位置,然后尝试扫描结果。
仅当您在清单上提供 ACCESS_COARSE_LOCATION 时,才会在此处列出位置。
您可以使用 BluetoothAdapter.startDiscovery()
.
它将扫描蓝牙智能和经典蓝牙设备,但不需要启用定位服务。
(您仍然需要 Android 6 的 ACCESS_COARSE_LOCATION
权限。)
您可以在找到的设备上调用 BluetoothDevice.getType
以过滤蓝牙智能/低功耗设备。
我发现在 Android 6 之后你必须授予 ACCESS_COARSE_LOCATION 权限。但在某些设备上,您的 phone 定位服务 (GPS) 也需要打开,以便您可以发现外围设备。我发现使用 Android 7.0 的 Nexus 5x。
我通过在 Gradle 文件中将 targetSdkVersion
设置为 22 来解决这个问题。
您必须在清单中声明 ACCESS_COARSE_LOCATION
,但是,即使用户从应用程序设置中拒绝此权限,BLE 扫描也将正常工作。
这只是为了避免请求位置权限而进行的黑客攻击。最好以最新的 android 版本为目标。
编辑
不应再使用此解决方案,因为 Google Play 将要求新应用至少面向 Android 8.0(API 级别 26)。应用程序应请求 BLE 扫描的位置权限。
不,这不是错误。
此 issue was brought up to Google where they responded saying that this was the intended behavior and they won't fix it. They directed developers to this site 指出现在需要位置许可才能访问硬件标识符。现在,开发人员有责任让用户了解该要求。
然而,在这个问题中,它没有解决为什么需要定位服务(GPS 等),而且他们似乎不会重新审视这个问题来解释这一点,因为它已被标记为预期的行为。
回答问题的第二部分:是的,可以在不启用位置服务的情况下进行扫描。您可以使用 BluetoothAdapter.getDefaultAdapter().startDiscovery()
进行蓝牙经典扫描,这将在关闭位置服务的情况下进行。这将发现所有蓝牙设备、BLE 和其他设备。但是,BLE 设备不会有扫描记录,如果它们被视为 startScan()
.
的结果,它们就会有扫描记录。
从我最近在android 8.0 上注意到的,不需要打开GPS 来进行BLE 扫描,但您必须在清单中声明它,但用户必须允许权限.
当您尝试使用 startScan()
方法进行扫描时,Android 将提示用户允许位置权限。如果不允许该权限,您的扫描将失败。
您可以使用 CompanionDeviceManager (API26) 扫描没有位置访问权限的 BLE 设备。
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();
}
}
对我有用!
升级到 Android 版本 6.0 蓝牙低功耗 (BLE) 扫描后,只有在设备上启用了位置服务后才能进行扫描。请参阅此处以供参考:Bluetooth Low Energy startScan on Android 6.0 does not find devices
基本上,您需要为应用程序和 phone 启用权限。这是一个错误吗?是否可以在没有实际启用位置服务的情况下进行扫描?我不想为我的所有应用程序设置位置。
编辑
我没有提到我正在使用 API 21 中提供的 BluetoothLeScanner
中的 startScan()
方法。我同意此方法需要的清单中的课程和精细位置权限。我只是不希望我的应用程序的用户必须在他们的设备(GPS 等)上启用定位服务才能使用我的应用程序。
以前,startScan()
方法将 运行 和 return 结果与 phone 上禁用的位置服务。然而,在 Marshmallow 上,当在 phone 和 course/fine 位置权限中未启用位置服务时,相同的应用程序会 "scan" 但默默地失败并且 return 没有结果清单。
好吧,我查看了用 Eclipse 编写的代码,并在那里使用了 startScan (API 21) 函数,但没有在清单文件中声明位置信息。我仍然得到适当的回调。 您是否尝试过 运行 没有位置声明的代码? 另一方面 - 您可以使用不需要这些权限的已弃用的 startLeScan (API 18)。但是,在我看来,使用 API 18 种方法在服务中搜索和读取所需的特性会更加复杂。
我也在清单上试过这个但没有请求许可,不知道为什么。您的应用程序是否在启动时提示位置权限?如果不是,我们需要 request for permission on runtime.
你也可以检查这个来测试你的应用程序是否正常工作:
打开设置 > 应用程序 > YourApplication > 权限 并启用位置,然后尝试扫描结果。
仅当您在清单上提供 ACCESS_COARSE_LOCATION 时,才会在此处列出位置。
您可以使用 BluetoothAdapter.startDiscovery()
.
它将扫描蓝牙智能和经典蓝牙设备,但不需要启用定位服务。
(您仍然需要 Android 6 的 ACCESS_COARSE_LOCATION
权限。)
您可以在找到的设备上调用 BluetoothDevice.getType
以过滤蓝牙智能/低功耗设备。
我发现在 Android 6 之后你必须授予 ACCESS_COARSE_LOCATION 权限。但在某些设备上,您的 phone 定位服务 (GPS) 也需要打开,以便您可以发现外围设备。我发现使用 Android 7.0 的 Nexus 5x。
我通过在 Gradle 文件中将 targetSdkVersion
设置为 22 来解决这个问题。
您必须在清单中声明 ACCESS_COARSE_LOCATION
,但是,即使用户从应用程序设置中拒绝此权限,BLE 扫描也将正常工作。
这只是为了避免请求位置权限而进行的黑客攻击。最好以最新的 android 版本为目标。
编辑
不应再使用此解决方案,因为 Google Play 将要求新应用至少面向 Android 8.0(API 级别 26)。应用程序应请求 BLE 扫描的位置权限。
不,这不是错误。
此 issue was brought up to Google where they responded saying that this was the intended behavior and they won't fix it. They directed developers to this site 指出现在需要位置许可才能访问硬件标识符。现在,开发人员有责任让用户了解该要求。
然而,在这个问题中,它没有解决为什么需要定位服务(GPS 等),而且他们似乎不会重新审视这个问题来解释这一点,因为它已被标记为预期的行为。
回答问题的第二部分:是的,可以在不启用位置服务的情况下进行扫描。您可以使用 BluetoothAdapter.getDefaultAdapter().startDiscovery()
进行蓝牙经典扫描,这将在关闭位置服务的情况下进行。这将发现所有蓝牙设备、BLE 和其他设备。但是,BLE 设备不会有扫描记录,如果它们被视为 startScan()
.
从我最近在android 8.0 上注意到的,不需要打开GPS 来进行BLE 扫描,但您必须在清单中声明它,但用户必须允许权限.
当您尝试使用startScan()
方法进行扫描时,Android 将提示用户允许位置权限。如果不允许该权限,您的扫描将失败。
您可以使用 CompanionDeviceManager (API26) 扫描没有位置访问权限的 BLE 设备。 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();
}
}
对我有用!