Android BLE4.+ 蓝牙开发国产手机兼容性解决方案

本文主要探讨了Android BLE4.0+蓝牙开发在国内遇到的兼容性问题,包括扫描不到设备、假断开连接以及扫描失败等问题,并提供了针对华为、小米、魅族等国产手机的反射调用系统源码的解决方案。作者分享了多年智能穿戴BLE开发的经验,建议开发者注意蓝牙app状态刷新、连接状态判断和扫描失败的处理方法。
摘要由CSDN通过智能技术生成

算是做了n年的智能穿戴BLE开发了, 首先对国内的安卓开发者提醒下 , BLE开发是真的很坑, 特别是安卓, ios端也坑, 但没安卓坑 因为国产有很多手机 各种奇葩兼容都有,
其实这些方案我很早就写到云笔记里了,一直没公开, 这里的解决方案大部分都是网上搜不到 或者网上搜到类似的问题, 但回复基本上是回答[无法解决] 或 [重启手机解决]等 没意义的解决办法,让我很无语…

以下内容可能涉及到各种系统类源码
你可以通过这里阅读 https://www.androidos.net.cn/

废话不多说, 希望对你们有用

1.刷新蓝牙app的状态

#####问题描述:
某些手机用久了会出现扫描不到任何设备的bug,
此时是因为手机误认为本app不是[ble类] app , f**k!!! 还有这种操作???
但值得注意的是, 这只是一种原因,[ 扫描不到任何设备的bug] 有很多种原因, 详情请看第3点
#####解决方案:
[目前网上没有与我类似的解决办法, 所以具体副作用自测]
参考 IBluetoothManager.aidl 系统源码

出现该问题时于是通过查看系统源码找到isBleAppPresent 方法 ,反射调用其后居然返回false ,
换了一台能正常使用的手机 调用该方法 返回true 因此证实了这个问题,
然后发现系统有私有的updateBleAppCount方法, 可以刷新ble类app的状态,反射调用之…
因此解决了 [偶尔ble设备扫描不出来]的bug),
通过传入你的app包名 以 刷新 蓝牙app的错误状态

 public static void refreshBleAppFromSystem(Context context, String packageName) {
   
        //6.0以上才有该功能,不是6.0以上就算了
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
   
            return;
        }

        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        if (adapter == null) {
   
            return;
        }
        if (!adapter.isEnabled()) {
   
            return;
        }
        try {
   
            Object mIBluetoothManager = getIBluetoothManager(adapter);
            Method isBleAppPresentM = mIBluetoothManager.getClass().getDeclaredMethod("isBleAppPresent");
            isBleAppPresentM.setAccessible(true);
            boolean isBleAppPresent = (Boolean) isBleAppPresentM.invoke(mIBluetoothManager);
            if (isBleAppPresent) {
   
                return;
            }
            Field mIBinder = BluetoothAdapter.class.getDeclaredField("mToken");
            mIBinder.setAccessible(true);
            Object mToken = mIBinder.get(adapter);

            //刷新偶尔系统无故把app视为非 BLE应用 的错误标识 导致无法扫描设备
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
   
                //8.0+ (部分手机是7.1.2 也是如此)
                Method updateBleAppCount = mIBluetoothManager.getClass().getDeclaredMethod("updateBleAppCount", IBinder.class, boolean.class, String.class);
                updateBleAppCount.setAccessible(true);
                //关一下 再开
                updateBleAppCount.invoke(mIBluetoothManager, mToken, false, packageName);
                updateBleAppCount.invoke(mIBluetoothManager, mToken, true, packageName);

            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
   

                try {
   
                    //6.0~7.1.1

                    Method updateBleAppCount = mIBluetoothManager.getClass().getDeclaredMethod("updateBleAppCount", IBinder.class, boolean.class);
                    updateBleAppCount.setAccessible(true);
                    //关一下 再开
                    updateBleAppCount.invoke(mIBluetoothManager, mToken, false);
                    updateBleAppCount.invoke(mIBluetoothManager, mToken, true);
                } catch (NoSuchMethodException e) {
   
                    //8.0+ (部分手机是7.1.2 也是如此)
                    try {
   
                        Method updateBleAppCount = mIBluetoothManager.getClass().getDeclaredMethod("updateBleAppCount", IBinder.class, boolean.class, String.class);
                        updateBleAppCount.setAccessible(true);
                        //关一下 再开
                        updateBleAppCount.invoke(mIBluetoothManager, mToken, false, packageName);
                        updateBleAppCount.invoke(mIBluetoothManager, mToken, true, packageName);
                    } catch (NoSuchMethodException e1) {
   
                        e1.printStackTrace();
                    }
                }
            }
        } catch (Throwable e)
  • 11
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 20
    评论
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值