Android上见鬼的蓝牙
以前发的各种蓝牙开发的文章中使用的程序,都是在我自己的手机上完美运行过的.
我信心满满的就把app发布了.
之后就收到了很多邮件…各种投诉,说蓝牙完全搜索不到啦!蓝牙连不上啦!用不了啦!
和公司之前所有Android版本的蓝牙功能相比,我做的这个版本在扫描附近蓝牙的时候,可以实时的更新蓝牙信号的强度.
完美解决了之前用户拿着app不知道哪一个蓝牙是前轮,哪一个蓝牙是后轮.
这一套在我自己的手机(Nexus 6P)上完美流畅的运行了,在一些用户的手机上竟然出现了,完全扫描不到蓝牙外设的情况!
其实在发布之前,我们公司内部所有的android手机都参与了测试,虽然手机不同,性能不同,但是都没有出现完全搜索不到的现象.
于是我掏出我的坚果手机(不是坚果pro),打开了搜索界面,也出现了搜索的结果,只不过…过了一会儿,它们就消失了!
Debug
于是我就接上电脑看看控制台都说了一些什么…
在搜索到了某一个设备的蓝牙广播之后,系统好像就不想再收这个蓝牙外设的广播信号了!
我的搜索界面是定时刷新可用的蓝牙外设列表的,在判断某一个蓝牙外设是不是还存在的时候,我用了时间戳.每次底层搜索到蓝牙外设的时候,我会在model层更新这个蓝牙外设的时间戳.每次View层获取最新列表数据的时候,把每个设备的更新时间戳减去当前的时间戳,如果超过一个阈值,说明这个蓝牙外设已经不存在了.
public class ScanItem {
private BluetoothDevice device;
private int rssi;
private int model;
private long updateTime;
private boolean connecting;
private boolean connected;
/**
...
**/
public boolean isAvailable(){
return ((System.currentTimeMillis()-updateTime)<2000);
}
}
在判断这里我的阈值是2秒,看来在某些垃圾手机上面,是不能酱紫的.于是我就改成了20秒.
运行起来,发现还是不行……
因为,不管过多少秒,这个垃圾系统都不在把收到的广播信息返回给我了!
See see dalao’s work
然后我想到,有那么多做蓝牙的app,我看看它们怎么运行的,怎么实时更新信号强度的.
我下载了我最喜欢的BLE Scanner,运行了起来,发现很完美啊.
然后我就在控制台里面看,发现这个app在一个劲的停止搜索,开始搜索,停止搜索,开始搜索……
或许这是一个好方法!既然这种破系统一次扫描对一个设备只会给一次广播信号,那我只能多次停止扫描开启扫描咯.
if (VKBluetoothManager.getInstance().isScanning()){
VKBluetoothManager.getInstance().stopScan();
handler.postDelayed(scanControlRunnable,50);
}else {
VKBluetoothManager.getInstance().scanDevices();
handler.postDelayed(scanControlRunnable,950);
}
心满意足的运行了起来,发现完美,这个破坚果终于达成了实时刷新的效果!
But……在Nexus 6P上面竟然出现了系统错误
E/BtGatt.GattService: App 'XuanWheel' is scanning too frequently
Are you f**king kidding me?
这样不行,那样也不行~
扫描的太频繁,意思应该是刚结束扫描后,再次开始的时间间隔太短了吧.
于是我就改了两个时间postdelay的延迟时间
if (VKBluetoothManager.getInstance().isScanning()){
VKBluetoothManager.getInstance().stopScan();
handler.postDelayed(scanControlRunnable,2000);
}else {
VKBluetoothManager.getInstance().scanDevices();
handler.postDelayed(scanControlRunnable,4000);
}
这样子就可以了!
嗯,虽然说这样子实现了实时刷新信号强度的功能,但是毕竟刷新率还是很低的……而且本来Nexus 6p可以拥有更高的刷新率,为了兼容这些臭系统,只能一起降低效果了……这么看起来,还是iOS比较好~
Why
那么,为啥某些Android系统要这么搞呢!
我猜,他们为了提高电池寿命,节省CPU资源,让UI更加流畅,所以牺牲了一些使用频率不那么高的外设的性能,于是我们可怜的蓝牙,就这么被阉割了.不过你们在系统里面搞幺蛾子,用户不会说什么,但是用户的手机在使用需要蓝牙的app的时候,这些开发者就很悲催了呀~他们(我们)明明遵守着设计准则,却发现自己的程序跑在了假系统上,还被用户吐槽,被打一星,真是有苦说不清啊…