升级到Android版本6.0后,只有在设备上启用了位置服务时,蓝牙低功耗(BLE)扫描才会起作用。请参阅此处以供参考:Bluetooth Low Energy startScan on Android 6.0 does not find devices
基本上,您需要为应用以及手机启用权限。这是一个错误吗?是否可以在没有实际启用位置服务的情况下扫描?我不想要为我的所有应用提供位置信息。
修改
我没有提到我在API 21中提供的startScan()
中使用了BluetoothLeScanner
方法。我对此方法所需的清单中的课程和精确位置权限感到满意。我只是不希望我的应用的用户必须在他们的设备(GPS等)上启用位置服务才能使用我的应用。
以前,startScan()
方法会在手机上禁用位置服务的情况下运行并返回结果。然而,在棉花糖上,相同的应用程序将扫描"但是,当手机上没有启用位置服务且课程/精确位置权限仍然在清单中时,默默地失败并且没有返回任何结果。
答案 0 :(得分:63)
不,这不是错误。
此issue已提交给Google,他们回复说这是预期的行为,他们无法修复。他们指示开发人员到this site,指出现在需要位置权限才能访问硬件标识符。现在,开发人员有责任让用户了解这一要求。
然而,在这个问题中,它没有解决为什么需要定位服务(GPS等)的原因并且他们似乎不会重新审视这个问题来解释这一点,因为它已被标记为预期行为。
回答问题的第二部分:是的,可以在不启用位置服务的情况下进行扫描。您可以使用BluetoothAdapter.getDefaultAdapter().startDiscovery()
进行蓝牙经典扫描,这将关闭位置服务。这将发现所有蓝牙设备,BLE和其他。但是,如果BLE设备被视为startScan()
的结果,则它们将没有扫描记录。
答案 1 :(得分:10)
我通过在gradle文件中将targetSdkVersion
设置为 22 来解决此问题。
您必须在清单中声明ACCESS_COARSE_LOCATION
,但即使用户从应用设置中拒绝此权限,BLE扫描也会有效。
这只是一个避免请求位置许可的黑客行为。最好定位最新的Android版本。
答案 2 :(得分:8)
我发现在Android 6之后您必须授予ACCESS_COARSE_LOCATION权限。但在某些设备上还需要打开手机定位服务(GPS),以便发现外围设备。我发现使用Nexus 5x和Android 7.0。
答案 3 :(得分:2)
我也在清单上试过这个,但没有请求许可,不知道为什么。你是应用程序在启动时提示输入位置权限吗?如果不是,我们需要request for permission on runtime。
此外,您可以检查此项以测试您的应用是否正常运行:
打开设置>应用> YourApplication>权限 并启用位置,然后尝试扫描结果。
只有在清单上提供了ACCESS_COARSE_LOCATION时,才会在此处列出位置。
答案 4 :(得分:2)
您可以使用BluetoothAdapter.startDiscovery()
它将扫描蓝牙智能和经典蓝牙设备,但不需要启用位置服务
(您仍然需要Android 6上的ACCESS_COARSE_LOCATION
权限。)
您可以在找到的设备上拨打BluetoothDevice.getType
来过滤蓝牙智能/低功耗设备。
答案 5 :(得分:1)
将 ACCESS_COARSE_LOCATION
添加到 Manifest 后,
请求运行时许可:
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();
}
}
为我工作!
答案 6 :(得分:0)
好吧,我查看了用Eclipse编写的代码,并在那里使用了startScan(API 21)函数,而没有在清单文件中声明位置内容。我仍然得到适当的回调。 您是否尝试过在没有位置声明的情况下运行代码? 另一方面 - 您可以使用不需要这些权限的已弃用的startLeScan(API 18)。但是,在我看来,使用API 18方法搜索和阅读服务中所需的特征会更复杂。
答案 7 :(得分:0)
根据我最近在android 8.0上注意到的内容,不需要打开GPS进行BLE扫描,但是您必须在清单中声明它,但是用户必须允许该权限。
当您尝试使用startScan()
方法进行扫描时,Android将提示用户允许位置权限。如果不允许该权限,扫描将失败。
答案 8 :(得分:0)
您可以使用CompanionDeviceManager(API26)扫描没有位置访问权限的BLE设备。 https://developer.android.com/reference/android/companion/CompanionDeviceManager。