Android 6.0 扫描不到 Ble 设备需开启位置权限

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 6.0 扫描不到 Ble 设备需开启位置权限相关的知识,希望对你有一定的参考价值。

参考技术A 最近总是有用户反馈说APP扫描不到设备,让我很费解了一段时间,尤其是华为和OPPO,公司还专门买了这款手机,然后测试没问题,直到一个偶然,我把手机定位给关了,才发现这个问题,android 6.0 扫描设备需开启位置权限,用户突然一天把定位给关了,我们在扫描之前又没检测,唉,一个逻辑不严谨就会出现各种问题,现在记录一下

权限获取

<uses-permission android:name="android.permission.BLUETOOTH"/> 使用蓝牙所需要的权限

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> 使用扫描和设置蓝牙的权限(申明这一个权限必须申明上面一个权限)

在Android5.0之前,是默认申请GPS硬件功能的。而在Android 5.0 之后,需要在manifest 中申明GPS硬件模块功能的使用。

<!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->

    <uses-feature android:name="android.hardware.location.gps" />

在 Android 6.0 及以上,还需要打开位置权限。如果应用没有位置权限,蓝牙扫描功能不能使用(其它蓝牙操作例如连接蓝牙设备和写入数据不受影响)

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

除了上面的设置之外,如果想设置设备只支持 BLE,可以加上下面这句话

<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>

同样,如果不想添加 BLE 的支持,那么可以设置 required="false"

然后可以在运行时判断设备是否支持 BLE,

// Use this check to determine whether BLE is supported on the device. Then

    // you can selectively disable BLE-related features.

    if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE))

        Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();

        finish();

   

打开定位 (Location)

首先检查定位是否打开,可以像下面这样操作:

/**

* Location service if enable

*

* @param context

* @return location is enable if return true, otherwise disable.

*/

public static final boolean isLocationEnable(Context context)

    LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);

    boolean networkProvider = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

    boolean gpsProvider = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

    if (networkProvider || gpsProvider) return true;

    return false;



如果定位已经打开,可以搜索到 ble 设备;如果定位没有打开,则需要用户去打开,像下面这样:

private static final int REQUEST_CODE_LOCATION_SETTINGS = 2;

private void setLocationService()

    Intent locationIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);

    this.startActivityForResult(locationIntent, REQUEST_CODE_LOCATION_SETTINGS);



进入定位设置界面,让用户自己选择是否打开定位。选择的结果获取:

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data)

    if (requestCode == REQUEST_CODE_LOCATION_SETTINGS)

        if (isLocationEnable(this))

            //定位已打开的处理

        else

            //定位依然没有打开的处理

       

    else super.onActivityResult(requestCode, resultCode, data);

通过 BLE 设备发送命令

【中文标题】通过 BLE 设备发送命令【英文标题】:send command over BLE device 【发布时间】:2015-03-06 16:49:18 【问题描述】:

我正在尝试使用我的 Android 手机中的 BLE 配置文件连接到 BC127。我能够搜索 BLE 设备但我不确定如何检索远程 BLE 设备上可用的服务。我看到了几个示例,但都包含服务的 UUID。如何知道服务的 UUID?

【问题讨论】:

【参考方案1】:

搜索BLE设备后,

您可以关注Android开发者“http://developer.android.com/samples/BluetoothLeGatt/project.html”连接设备。

在“BluetoothLeService.java”中,通过gatt.discoverServices()连接设备成功后即可获取服务(可以在onConnectionStateChange中运行)。

会触发onServicesDiscovered()

onServicesDiscovered() 中,尝试gatt.getServices() 来获取服务列表,在每个服务中尝试service.getCharacteristics() 来获取特性列表,在每个特性中,尝试characteristics.getDescriptors() 来获取描述符。

在每个服务、特征和描述符中,使用getUUID() 获取 UUID 信息。

希望对你有用

谢谢, 德文。

【讨论】:

谢谢德文。这就是我所做的但是在logcat中我得到“客户端注册,等待回调”我搜索了这个并得到我们必须为ConnectGatt()创建新线程。我也这样做了,但我不知道出了什么问题 这些是我正在遵循的步骤 1. 搜索 BLE 设备 2. 使用 ConnectGatt() 连接 3. 等待回调调用 OnConnectionStateChanged() 我调用 gatt.getServices() 来探索服务在远程设备上。

以上是关于Android 6.0 扫描不到 Ble 设备需开启位置权限的主要内容,如果未能解决你的问题,请参考以下文章

杂记:解决Android扫描BLE设备名称不刷新问题

Android 6.0 Marshmallow BLE 连接问题

Android-Ble蓝牙开发Demo示例–扫描,连接,发送和接收数据,分包解包(附源码)

Android代码不扫描BLE设备CC2650

BLE 5 外围设备未在支持 BLE 5 的 Android 手机和 iPhone 上得到扫描

Android 4.4:低功耗蓝牙;无需扫描 BLE 设备即可连接