需要为Android 6.0上的蓝牙低功耗扫描启用位置

时间:2015-10-09 19:14:39

标签: android bluetooth bluetooth-lowenergy android-6.0-marshmallow

升级到Android版本6.0后,只有在设备上启用了位置服务时,蓝牙低功耗(BLE)扫描才会起作用。请参阅此处以供参考:Bluetooth Low Energy startScan on Android 6.0 does not find devices

基本上,您需要为应用以及手机启用权限。这是一个错误吗?是否可以在没有实际启用位置服务的情况下扫描?我不想要为我的所有应用提供位置信息。

修改 我没有提到我在API 21中提供的startScan()中使用了BluetoothLeScanner方法。我对此方法所需的清单中的课程和精确位置权限感到满意。我只是不希望我的应用的用户必须在他们的设备(GPS等)上启用位置服务才能使用我的应用。

以前,startScan()方法会在手机上禁用位置服务的情况下运行并返回结果。然而,在棉花糖上,相同的应用程序将扫描"但是,当手机上没有启用位置服务且课程/精确位置权限仍然在清单中时,默默地失败并且没有返回任何结果。

9 个答案:

答案 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