Android 蓝牙获取不到服务(特性信息)

SYD8801是一款低功耗高性能蓝牙低功耗SOC,集成了高性能2.4GHz射频收发机、32位ARM Cortex-M0处理器、128kB Flash存储器、以及丰富的数字接口。SYD8801片上集成了Balun无需阻抗匹配网络、高效率DCDC降压转换器,适合用于可穿戴、物联网设备等。具体可咨询:http://www.sydtek.com/

本文摘录于:http://blog.csdn.net/qq_29984105/article/details/51821837

Android 蓝牙4.0连接几次后出现连接不了,搜索不到服务的情况

最近做手机蓝牙与BLE设备的智能项目。遇到一个问题,记录下来。方便以后。

出现的情况是:手机蓝牙与蓝牙设备连接几次,交互信息后,无法再次连接与搜索到服务,需重启手机蓝牙或者关闭APP后,再次启动APP,才能再次连接设备。

上网查找了不少资料。才找资料。非常感谢此博文提供的参考解决方案http://bbs.eeworld.com.cn/thread-438571-1-1.html

/*多次创建gatt连接对象的直接结果是创建过6个以上gatt后就会再也连接不上任何设备,原因应该是Android中对BLE限制了同时连接的数量为6个

                         * 解决办法是在每一次重新连接时都执行一次gatt.close();关闭上一个连接。
                         * 有人说为什么不在gatt.disconnect();后加一条gatt.close();呢,原因是如果立即执行gatt.close();会导致gattCallback无法收到STATE_DISCONNECTED的状态。
                         * 当然,最好的办法是在gattCallback收到STATE_DISCONNECTED后再执行gatt.close();,这样逻辑上会更清析一些。
                         */

 

比如我的项目:

if (mBluetoothGatt != null) {
   mBluetoothGatt.close();
   //LogUtil.info("-------------关闭mBluetoothGatt");
}
//连接前先关闭之前 的

 mBluetoothGatt = device.connectGatt(context, false, mGattCallback);

再不行,可看:http://www.th7.cn/Program/Android/201604/818516.shtml
如下:

安卓系统蓝牙缓存的作用

 

安卓手机连接BLE设备的时候,系统会缓存相关的信息,这样再次连接的时候,就可以直接从缓存中读取一些信息,进而提高连接以及获取服务的速度。

 

 

 

清理蓝牙缓存的原因

 

既然安卓系统缓存蓝牙信息是有上述作用的,那为什么我们还要去清理呢?清理蓝牙缓存的原因主要如下所述:

1.BLE设备配置OAD升级之后,ImageA进行了压缩,将压缩的空间腾出来给ImageB,这个时候ImageA的服务和特性较ImageB就有可能减少掉一些与升级无关的部分,如果ImageA和ImageB的服务和特性不一样了,但是同属于一个设备,也就是MAC是一样的,这样就会出现明明从ImageA升级到ImageB成功了,但是搜到的服务和特性却仍然是ImageA的。

 

2.平常调试开发的时候,在某一块特定的开发板上升级不同服务和特性的软件,情形类似1中的描述,这个时候也会出现软件更换了,但是搜索到的服务和特性却没有变的情况。

 

综上所述,清理蓝牙缓存最主要的应用场景是针对配置了OAD升级功能的BLE设备以及平常的开发调试。

 

 

 

清理蓝牙缓存的方法

 

清理蓝牙缓存的方法分为软件方法和非软件方法。

首先,我们来介绍软件方法,其实也就是代码实现。

1.关闭蓝牙,然后重新打开,代码实现如下:

 

private static BluetoothManager mBluetoothManager;//通过BluetoothManager来获取BluetoothAdaptermBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);//一个Android系统只有一个BluetoothAdapter ,通过BluetoothManager 来获取mBtAdapter = mBluetoothManager.getAdapter();//打开蓝牙mBtAdapter.enable();//关闭蓝牙mBtAdapter.enable();

上述代码段中获取BluetoothAdapter的过程应该是在应用刚打开的时候,之所以都罗列到一起,是为了便于理解。

 

2.重启蓝牙是需要一定时间的,而且可能用户体验上会有不少瑕疵,之所以出现前面描述的问题是因为蓝牙缓存的问题,其实更深入的讲是因为GATT层的缓存信息的影响,所以个人建议直接清理GATT的缓存。

 

通过查阅安卓API,发现没有公开的清理GATT层蓝牙缓存的方法,但是在“android.bluetooth.BluetoothGatt”类中有一个“refresh”方法,该方法的描述中正是清理GATT层缓存的方法,但是该方法是隐藏的,截图显示如下:

 

 

 

隐藏的方法我们是无法直接调用的,如果非要使用,可以采用java的反射机制进行调用,实现源码如下:

 

	/**	 * Clears the internal cache and forces a refresh of the services from the	 * remote device.	 */	public boolean refreshDeviceCache() {		if (mBluetoothGatt != null) {			try {				BluetoothGatt localBluetoothGatt = mBluetoothGatt;				Method localMethod = localBluetoothGatt.getClass().getMethod(						"refresh", new Class[0]);				if (localMethod != null) {					boolean bool = ((Boolean) localMethod.invoke(							localBluetoothGatt, new Object[0])).booleanValue();					return bool;				}			} catch (Exception localException) {				Log.i(TAG, "An exception occured while refreshing device");			}		}		return false;	}

其中,“mBluetoothGatt”是在连接建立的时候设置的,另外对于该方法的使用,最好在断开连接成功的回调方法中使用,即在你自己实现的“BluetoothGattCallback”对象的“onConnectionStateChange”方法中判断“status”是“BluetoothProfile.STATE_DISCONNECTED”的时候调用。

 

下面来介绍一下非软件方法

1.手动开关蓝牙或者重启手机。

2.清理蓝牙缓存。找到你的安卓手机的“设置”,然后按照下述操作:

 

 

 

 

 

往下滑动,找到“清空缓存”,然后点击“清空缓存”,显示如下:


 

你可能感兴趣的:(蓝牙知识)