使用无障碍服务 无障碍服务即AccessibilityService,是一种,可提供界面增强功能,来协助残障用户或可能暂时无法与设备进行全面互动的用户完成操作的应用。 Google是这样描述的:无障碍服务是一种应用,可提供界面增强功能,来协助残障用户或可能暂时无法与设备进行全面互动的用户完成操作。 从Android1。6(API级别4)开始,您就可以构建和部署无障碍服务,并且这些服务在Android4。0(API级别14)中得到了显著改进。Android支持库也随着Android4。0的发布得到更新,为这些增强的无障碍功能(自Android1。6起)提供支持。如果开发者的目标是打造广泛兼容的无障碍服务,建议他们使用该支持库,并让开发的应用支持Android4。0中引入的更高级的无障碍功能。classScannerService:AccessibilityService(){overridefunonAccessibilityEvent(p0:AccessibilityEvent){}overridefunonInterrupt(){}overridefunonKeyEvent(event:KeyEvent):Boolean{LogUtils。d(event)if(Scanner。dispatchKeyEvent(event)){returntrue}returnsuper。onKeyEvent(event)}} AndroidManifest。xml文件中注册ScannerServiceserviceandroid:name。ScannerServiceandroid:enabledtrueandroid:exportedtrueandroid:permissionandroid。permission。BINDACCESSIBILITYSERVICEintentfilterintentfiltermetadataandroid:nameandroid。accessibilityserviceandroid:resourcexmlkeyserviceconfigservice keyserviceconfig。xml这个文件用来声明无障碍服务,最终最后系统设置页面的【无障碍】设置页面中看到相关的开关。?xmlversion1。0encodingutf8? KeyEvent处理 这里我通过Scanner工具类来处理捕获的KeyEvent,并且在识别到KeyEvent。ACTIONDOWN按键之后将识别内容抛给注册进来的回调函数。最终由回调函数得到了识别到的扫描内容。 另外这里KeyEvent到扫描内容的转换,使用了TextKeyListener。避免了,手动的字符转换,也尽量避免一些兼容性的问题(例如回车换行的识别等) 参考实现如下(主要代码):objectScanner:IScanner{扫描结果回调privatevalcallbacksStackIScanCallback()privatevarisStartfalse整体扫描结果privatevarmScanResultList:ArrayListStringArrayList()privatevarhandler:Handler?nullprivatevaltkl:KeyListenerTextKeyListener。getInstance(false,TextKeyListener。Capitalize。NONE)privatevaletEditable。Factory。getInstance()。newEditable()privatevalkeyView。OnKeyListener{v,keyCode,eventvarreturnResultfalseif(event。actionKeyEvent。ACTIONDOWN){valcallbackcallbacks。peek()if(mScanResultList。size0callback!null!isStart){isStarttrueet。clear()callback。scanStart()}returnResulttkl。onKeyDown(null,et,keyCode,event)}elseif(event。actionKeyEvent。ACTIONUP){LogUtils。d(ScanneronKeyUpkeyCode{keyCode}UnicodeChar{event。unicodeChar})valisEnterevent。keyCodeKeyEvent。KEYCODEENTERif(isEnter){LogUtils。d(Scannernewapi:et)valmScanResultet。toString()et。clear()mScanResultList。add(mScanResult)handler?。let{it。removeCallbacks(resultRunnable)it。postDelayed(resultRunnable,300)}}else{handler?。let{it。removeCallbacks(resultRunnable)}}returnResulttkl。onKeyUp(null,et,keyCode,event)}else{returnResulttkl。onKeyOther(null,et,event)NOTE:MydevicesneverusedKeyEvent。ACTIONMULTIPLEsoIdontknowifitshouldgetfiredhereorwiththekeydownevent。}returnResult}overridefuninitScanner(mContext:Context){LogUtils。d(initScanner)if(handlernull){handlerHandler()}}overridefundispatchKeyEvent(event:KeyEvent):Boolean{returnkey。onKey(null,event。keyCode,event)}overridefunregisterScanCallback(callback:IScanCallback){callbacks。add(callback)}overridefununregisterScanCallback(callback:IScanCallback){callbacks。remove(callback)}overridefundestroyScanner(){handler?。let{it。removeCallbacks(resultRunnable)}mScanResultList?。clear()callbacks。clear()}privatevalresultRunnableRunnable{valcallbackcallbacks。peek()if(callback!null){valresult:ListStringArrayList(mScanResultList)LogUtils。d(Scanresult{GsonUtils。toJson(result)})if(result。isNotEmpty()){callback。scanSuccess(result〔0〕)}callback。scanSuccess(result)mScanResultList。clear()isStartfalse}}}扫码回调处理 通过监听页面的生命周期,自动的将实现过IScanCallback的页面注册到Scanner工具类中,并且在页面销毁的时候自助注销监听,从而实现了监听扫描结果的自动管理。 参考实现如下(主要代码):classAppLifecycleHandler:Application。ActivityLifecycleCallbacks,ComponentCallbacks2{overridefunonActivityCreated(activity:Activity,savedInstanceState:Bundle?){valisAccessibilitySettingsOnisAccessibilitySettingsOn(activity。applicationContext)LogUtils。d(AppLifecycleHandlerisAccessibilitySettingsOnisAccessibilitySettingsOn)if(!isAccessibilitySettingsOn){Toast。makeText(activity。applicationContext,请在系统【设置】中【无障碍】页面开启的demo【识别扫码输入】开关,Toast。LENGTHLONG)。show()openAccessibilitySetting(activity。applicationContext)}if(activityisIScanCallback){LogUtils。d(AppLifecycleHandleronActivityCreated扫描监听注册activity)registerScanCallback((activityasIScanCallback))}}overridefunonActivityDestroyed(activity:Activity){if(activityisIScanCallback){LogUtils。d(AppLifecycleHandleronActivityDestroyed注销扫描监听注册activity)unregisterScanCallback((activityasIScanCallback))}}}总结 通过android。accessibilityservice。AccessibilityService的onKeyEvent捕获扫码输入,将KeyEvent传递给Scanner处理,Scanner将KeyEvent传递给android。text。method。TextKeyListener,捕获回车按键(或者其他自定义按键的时候)将识别结果抛到回调中,由扫码回调处理扫码结果。