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

时间:2021-11-03 00:01:12

After upgrading to Android version 6.0 Bluetooth Low Energy (BLE) scanning will only work if Location services are enabled on the device. See here for reference: Bluetooth Low Energy startScan on Android 6.0 does not find devices

升级到Android版本6.0后,只有在设备上启用了位置服务时,蓝牙低功耗(BLE)扫描才有效。请参阅此处以供参考:Android 6.0上的蓝牙低功耗startScan无法找到设备

Basically, you need to have the permission enabled for the app as well as on for the phone. Is this a bug? Is it possible to scan without location services actually enabled? I don't want to have to have location for all my apps.

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

EDIT I failed to mention that I am using the startScan() method in BluetoothLeScanner provided in API 21. I am okay with the course and fine location permissions in the manifest that this method require. I just don't want the users of my app to have to enable location services on their device (GPS, etc.) to use my app.

编辑我没有提到我在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.

以前,startScan()方法将在手机上禁用位置服务的情况下运行并返回结果。但是,在Marshmallow上,相同的应用程序将“扫描”但是静默失败并且在手机上未启用位置服务且课程/精确位置权限仍在清单中时未返回任何结果。

6 个解决方案

#1


34  

No, this is not a bug.

不,这不是一个错误。

This 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 where it points out that location permission is now needed for hardware identifier access. It is now the developer's responsibility to make their users aware of the requirement.

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

In the issue, however, it doesn't address why Location services (GPS, etc.) are required and it doesn't seem like they are going to revisit the issue to explain this since it has been marked as the intended behavior.

然而,在这个问题中,它没有解决为什么需要定位服务(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().

要回答问题的第二部分:是的,可以在不启用位置服务的情况下进行扫描。您可以使用BluetoothAdapter.getDefaultAdapter()。startDiscovery()进行蓝牙经典扫描,这将关闭位置服务。这将发现所有蓝牙设备,BLE和其他。但是,如果BLE设备被视为startScan()的结果,它们将没有扫描记录。

#2


9  

I solved this by setting targetSdkVersion to 22 in gradle file. You must declare ACCESS_COARSE_LOCATION in the manifest but, BLE scanning will work even if user denies this permission from App Settings.

我通过在gradle文件中将targetSdkVersion设置为22来解决这个问题。您必须在清单中声明ACCESS_COARSE_LOCATION,但即使用户从App Settings拒绝此权限,BLE扫描也会起作用。

#3


5  

What I found is that after Android 6 you must grant ACCESS_COARSE_LOCATION permission. But on some devices is also necessary your phone location service (GPS) to be switched on, so you can discover peripheral devices. I found that using Nexus 5x, with Android 7.0.

我发现在Android 6之后你必须授予ACCESS_COARSE_LOCATION权限。但在某些设备上还需要打开手机定位服务(GPS),以便发现外围设备。我发现使用Nexus 5x和Android 7.0。

#4


2  

You can use BluetoothAdapter.startDiscovery().
It will scan for both Bluetooth Smart and classic Bluetooth devices, but location services do not need to be enabled.
(You still need ACCESS_COARSE_LOCATION permissions on Android 6.)

您可以使用BluetoothAdapter.startDiscovery()。它将扫描蓝牙智能和经典蓝牙设备,但不需要启用位置服务。 (您仍然需要Android 6上的ACCESS_COARSE_LOCATION权限。)

You can call BluetoothDevice.getType on found devices to filter for Bluetooth Smart / Low Energy devices.

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

#5


1  

I also tried this on manifest but did not request permission, not sure why. Is you app prompting for Location permission on startup? If it's not, we need to request for permission on runtime.

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

Also you can check this to test if your app is working fine:

此外,您可以检查此项以测试您的应用是否正常工作:

Open Settings > Apps > YourApplication > Permissions and enable Location and then try to scan for results.

打开设置>应用> YourApplication>权限并启用位置,然后尝试扫描结果。

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

只有在清单上提供了ACCESS_COARSE_LOCATION时,才会在此处列出位置。

#6


0  

Well, I have looked at my code written in Eclipse and I use there the startScan (API 21) function without declaring location stuff in manifest file. I still get the proper callback. Have you tried running the code without the location declaration? In the other hand - you can use the deprecated startLeScan (API 18) which does not require these permissions. However, in my opinion searching and reading desired characteristic in service is more complicated with API 18 methods.

好吧,我查看了我在Eclipse中编写的代码,并在那里使用了startScan(API 21)函数,而没有在清单文件中声明位置内容。我仍然得到适当的回调。您是否尝试在没有位置声明的情况下运行代码?另一方面 - 您可以使用不需要这些权限的已弃用的startLeScan(API 18)。但是,在我看来,使用API​​ 18方法搜索和阅读服务中所需的特性会更复杂。

#1


34  

No, this is not a bug.

不,这不是一个错误。

This 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 where it points out that location permission is now needed for hardware identifier access. It is now the developer's responsibility to make their users aware of the requirement.

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

In the issue, however, it doesn't address why Location services (GPS, etc.) are required and it doesn't seem like they are going to revisit the issue to explain this since it has been marked as the intended behavior.

然而,在这个问题中,它没有解决为什么需要定位服务(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().

要回答问题的第二部分:是的,可以在不启用位置服务的情况下进行扫描。您可以使用BluetoothAdapter.getDefaultAdapter()。startDiscovery()进行蓝牙经典扫描,这将关闭位置服务。这将发现所有蓝牙设备,BLE和其他。但是,如果BLE设备被视为startScan()的结果,它们将没有扫描记录。

#2


9  

I solved this by setting targetSdkVersion to 22 in gradle file. You must declare ACCESS_COARSE_LOCATION in the manifest but, BLE scanning will work even if user denies this permission from App Settings.

我通过在gradle文件中将targetSdkVersion设置为22来解决这个问题。您必须在清单中声明ACCESS_COARSE_LOCATION,但即使用户从App Settings拒绝此权限,BLE扫描也会起作用。

#3


5  

What I found is that after Android 6 you must grant ACCESS_COARSE_LOCATION permission. But on some devices is also necessary your phone location service (GPS) to be switched on, so you can discover peripheral devices. I found that using Nexus 5x, with Android 7.0.

我发现在Android 6之后你必须授予ACCESS_COARSE_LOCATION权限。但在某些设备上还需要打开手机定位服务(GPS),以便发现外围设备。我发现使用Nexus 5x和Android 7.0。

#4


2  

You can use BluetoothAdapter.startDiscovery().
It will scan for both Bluetooth Smart and classic Bluetooth devices, but location services do not need to be enabled.
(You still need ACCESS_COARSE_LOCATION permissions on Android 6.)

您可以使用BluetoothAdapter.startDiscovery()。它将扫描蓝牙智能和经典蓝牙设备,但不需要启用位置服务。 (您仍然需要Android 6上的ACCESS_COARSE_LOCATION权限。)

You can call BluetoothDevice.getType on found devices to filter for Bluetooth Smart / Low Energy devices.

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

#5


1  

I also tried this on manifest but did not request permission, not sure why. Is you app prompting for Location permission on startup? If it's not, we need to request for permission on runtime.

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

Also you can check this to test if your app is working fine:

此外,您可以检查此项以测试您的应用是否正常工作:

Open Settings > Apps > YourApplication > Permissions and enable Location and then try to scan for results.

打开设置>应用> YourApplication>权限并启用位置,然后尝试扫描结果。

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

只有在清单上提供了ACCESS_COARSE_LOCATION时,才会在此处列出位置。

#6


0  

Well, I have looked at my code written in Eclipse and I use there the startScan (API 21) function without declaring location stuff in manifest file. I still get the proper callback. Have you tried running the code without the location declaration? In the other hand - you can use the deprecated startLeScan (API 18) which does not require these permissions. However, in my opinion searching and reading desired characteristic in service is more complicated with API 18 methods.

好吧,我查看了我在Eclipse中编写的代码,并在那里使用了startScan(API 21)函数,而没有在清单文件中声明位置内容。我仍然得到适当的回调。您是否尝试在没有位置声明的情况下运行代码?另一方面 - 您可以使用不需要这些权限的已弃用的startLeScan(API 18)。但是,在我看来,使用API​​ 18方法搜索和阅读服务中所需的特性会更复杂。