纪念一下坑爹的蓝牙扫描枪连接(Android外接输入设备)

Android外接输入设备(蓝牙扫描枪)连接心得

搞了好久,知道真相的我,心真的好累!!!
!@#¥%%%…………好啦,抱怨的话就不多说了,上正餐吧。

以上都是我在搞蓝牙外接键盘过程中,因“外接设备接入,app崩溃(或重启),报错信息不明确,logcat打印 设备连接异常,即将关闭。。。”这事件所引起的蝴蝶效应,不得已逐步深入了解的蓝牙相关知识。
首先,我先声明一下,问题的解决方法在最后,简直简单到令人发指!!!
1.对于app崩溃没有日志,我最先观察到的是:系统提示设备连接异常。那么无外乎就是我们的蓝牙扫描枪接入出问题了嘛,于是开始搜索“Android外接输入法(扫描枪)崩溃”。百度上一大堆的输入法相关的东西立马展示在我眼前!

具体内容我就不一一展示了,请参考:系统键盘的管理类InputMethodManager的使用详细介绍!由于这个跟我要解决的并不是很相关,所以留个学习地址,直接pass掉了。

2.于是,我又继续查找 Android外接键盘 ,通过这篇文章的关键字“Android没法通过外接键盘中文输入原因”我又查找很多相关资料,确实也证明了Android5.0以前版本(我用的是小米2S真机测试的MIUI8系统,基于5.0.2版本)系统均不支持系统键盘和外接键盘并存!
其他的更高版本暂时还不清楚,有兴趣的朋友可以自行脑补。从中,我主要获取了几点信息:底层架构frameworks/base/services/Java/com/android/server中的WindowManagerService.java和InputMethodService.java定义了系统输入法和外接输入法的判断,而且可以得知一重要消息当外接输入设备存在时,系统输入法将被隐藏!且系统会通知Configure.java这个类中的两个常量的转变:外接输入设备时,转变为Configuration.HARDKEYBOARDHIDDEN_YES,且config.keyboard==Configuration.KEYBOARD_QWERTY的状态,反之,系统键盘时Configuration.HARDKEYBOARDHIDDEN_NO,且config.keyboard==Configuration.KEYBOARD_NOKEYS的状态。
注意:这两个均为系统常量,仅受 InputMethodService.java这个类的影响,虽然你主观上可以通过updateResources()这个方法可以改变它们的状态,

public void updateResources() {  
        Configuration config = new Configuration(getResources().getConfiguration());  
        //修改Configuration,让输入法认为系统中没有外接键盘  
        config.keyboard = Configuration.KEYBOARD_NOKEYS;
        config.keyboardHidden = Configuration.HARDKEYBOARDHIDDEN_YES  
        getResources().updateConfiguration(config, getResources().getDisplayMetrics());  
    } 

但是很可惜的告诉你,它压根不能影响大局(也就是说,即使你在外接设备存在的条件下,强制将Configuration改变为Configuration.KEYBOARD_NOKEYS和Configuration.HARDKEYBOARDHIDDEN_YES,却依然不能影响外接设备存在的事实。这样做是不能在外接键盘存在的条件下调出系统键盘的,换言之,系统并不支持并存!)

3.以上的路堵死了,所以我只能退而求其次,看看能不能通过其他方法搞定了。于是,在同事的帮助下,我了解了蓝牙扫描的几种协议,当然,本文只提及SPP协议,因为HID协议即模拟外接输入设备协议,现在的扫描枪一般都是这个协议的,少数兼容SPP协议。SPP协议即串口协议,别问我什么是串口协议,因为我也不懂…但是我就是听说spp协议支持低功耗蓝牙BLE通讯哦,当然,由于我们设备需求就是要求蓝牙必须是4.0以上的,不是经典蓝牙通讯,所以我还是主要关注一下BLE通讯吧。
参考了很多代码,结果感觉还是不如看看Android源生代码的例子,于是我找到了(X:\AndroidSDK\samples\android-18\legacy\BluetoothChat)目录下的源码例子,自己观察了起来,结果发现,网上写的跟这个大同小异啊…于是干脆就到网上下了几个BLE串口调试工具(对了,调试助手–图标是一只猫的这个软件挺强大的,还挺好用的)过来试一试,结果不尽如人意啊,只是因为我买了一把比较便宜的扫描枪吗?(小编我快疯了,这什么扫描枪?!连不上?说明书什么的都没有?各种奇葩问题&*¥%&@##¥)…

弄了好久,发现还是没有解决问题,就在我感觉快放弃的时候,一个无奈的举动改变了我所有成果–打日志(log.e()),嗯,没错,只是出于无聊,于是,从清单配置的android:configChanges=”“

<activity
     android:name=".MainActivity"
            android:configChanges="keyboardHidden|orientation|navigation|screenSize"
            android:screenOrientation="landscape"
            android:theme="@android:style/Theme.Holo.Light.NoActionBar.Fullscreen" />

到生命周期的各个方法

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.e("text", "onCreate")
    }

再到最重要的onConfigurationChanged这个方法

@Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        Configuration configuration = getResources().getConfiguration();

        Log.e("text", "onConfigurationChanged configuration.keyboard ==" +configuration.keyboard+ " " +
                "configuration.keyboardHidden ==" + configuration.keyboardHidden);
    }

我意外发现了一个重要的问题:
如果配置清单中android:configChanges=”keyboard”没有写,onConfigurationChanged这个方法根本不会走!于是我立马查了android:configChanges这个东西果不其然,”keyboard” 键盘发生了改变—-例如用户用了外部的键盘,天啊!原来自始至终,我开发的app中,配置清单中竟然少了android:configChanges=”keyboard”这个重要的东西!就是因为这个东西没写,导致外接设备(HID协议)接入时,系统无法识别或其他原因,于是造成了系统崩溃!
兴奋之余,我赶紧在我的app中加入了android:configChanges=”keyboard|….”这东西,结果,如愿以偿onConfigurationChanged这个方法走了,程序不再崩溃了…

至此,感谢收看,虽然讲得杂七杂八,但是链接网址希望能帮到大家,如有错误或意见,请指出,谢谢!

你可能感兴趣的:(移动开发,Android)