范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

基于AccessibilityService的Android扫码适配实践

  使用无障碍服务
  无障碍服务即AccessibilityService,是一种,可提供界面增强功能,来协助残障用户或可能暂时无法与设备进行全面互动的用户完成操作的应用。
  Google是这样描述的:无障碍服务是一种应用,可提供界面增强功能,来协助残障用户或可能暂时无法与设备进行全面互动的用户完成操作。
  从 Android 1.6(API 级别 4)开始,您就可以构建和部署无障碍服务,并且这些服务在 Android 4.0(API 级别 14)中得到了显著改进。Android 支持库也随着 Android 4.0 的发布得到更新,为这些增强的无障碍功能(自 Android 1.6 起)提供支持。如果开发者的目标是打造广泛兼容的无障碍服务,建议他们使用该支持库,并让开发的应用支持 Android 4.0 中引入的更高级的无障碍功能。class ScannerService : AccessibilityService() {     override fun onAccessibilityEvent(p0: AccessibilityEvent) {     }      override fun onInterrupt() {     }      override fun onKeyEvent(event: KeyEvent): Boolean {         LogUtils.d(event)         if (Scanner.dispatchKeyEvent(event)) {             return true         }         return super.onKeyEvent(event)     } }
  AndroidManifest.xml文件中注册ScannerService                                                                   
  keyservice_config.xml这个文件用来声明无障碍服务,最终最后系统设置页面的【无障碍】设置页面中看到相关的开关。  <?xml version="1.0" encoding="utf-8"?>
  KeyEvent处理
  这里我通过Scanner工具类来处理捕获的KeyEvent,并且在识别到KeyEvent.ACTION_DOWN按键之后将识别内容抛给注册进来的回调函数。最终由回调函数得到了识别到的扫描内容。
  另外这里KeyEvent到扫描内容的转换,使用了TextKeyListener。避免了,手动的字符转换,也尽量避免一些兼容性的问题(例如回车换行的识别等)
  参考实现如下(主要代码): object Scanner : IScanner {     //扫描结果回调     private val callbacks = Stack()     private var isStart = false      //整体扫描结果     private var mScanResultList: ArrayList = ArrayList()     private var handler: Handler? = null     private val tkl: KeyListener =         TextKeyListener.getInstance(false, TextKeyListener.Capitalize.NONE)     private val et = Editable.Factory.getInstance().newEditable("")     private val key = View.OnKeyListener { v, keyCode, event ->         var returnResult = false         if (event.action == KeyEvent.ACTION_DOWN) {             val callback = callbacks.peek()             if (mScanResultList.size == 0 && callback != null && !isStart) {                 isStart = true                 et.clear()                 callback.scanStart()             }             returnResult = tkl.onKeyDown(null, et, keyCode, event)         } else if (event.action == KeyEvent.ACTION_UP) {             LogUtils.d(                 "Scanner onKeyUp keyCode=${keyCode} UnicodeChar= ${event.unicodeChar}"             )             val isEnter = event.keyCode == KeyEvent.KEYCODE_ENTER             if (isEnter) {                 LogUtils.d("Scanner newapi:$et")                 val mScanResult = et.toString()                 et.clear()                 mScanResultList.add(mScanResult)                 handler?.let {                     it.removeCallbacks(resultRunnable)                     it.postDelayed(resultRunnable, 300)                 }             } else {                 handler?.let {                     it.removeCallbacks(resultRunnable)                 }             }             returnResult = tkl.onKeyUp(null, et, keyCode, event)         } else {             returnResult = tkl.onKeyOther(                 null,                 et,                 event             ) //NOTE: My devices never used KeyEvent.ACTION_MULTIPLE so I don"t know if it should get fired here or with the key down event.         }         returnResult     }      override fun initScanner(mContext: Context) {         LogUtils.d("initScanner")         if (handler == null) {             handler = Handler()         }     }      override fun dispatchKeyEvent(event: KeyEvent): Boolean {         return key.onKey(null, event.keyCode, event)     }      override fun registerScanCallback(callback: IScanCallback) {         callbacks.add(callback)     }      override fun unregisterScanCallback(callback: IScanCallback) {         callbacks.remove(callback)     }      override fun destroyScanner() {         handler?.let {             it.removeCallbacks(resultRunnable)         }         mScanResultList?.clear()         callbacks.clear()     }      private val resultRunnable = Runnable {         val callback = callbacks.peek()         if (callback != null) {             val result: List = ArrayList(mScanResultList)             LogUtils.d("Scan result=${GsonUtils.toJson(result)}")             if (result.isNotEmpty()) {                 callback.scanSuccess(result[0])             }             callback.scanSuccess(result)             mScanResultList.clear()             isStart = false         }     } }扫码回调处理
  通过监听页面的生命周期,自动的将实现过IScanCallback的页面注册到Scanner工具类中,并且在页面销毁的时候自助注销监听,从而实现了监听扫描结果的自动管理。
  参考实现如下(主要代码):class AppLifecycleHandler : Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {     override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {         val isAccessibilitySettingsOn = isAccessibilitySettingsOn(activity.applicationContext)         LogUtils.d("AppLifecycleHandler isAccessibilitySettingsOn=$isAccessibilitySettingsOn")         if (!isAccessibilitySettingsOn) {             Toast.makeText(                 activity.applicationContext,                 "请在系统【设置】中【无障碍】页面开启的demo【识别扫码输入】开关",                 Toast.LENGTH_LONG             ).show()             openAccessibilitySetting(activity.applicationContext)         }         if (activity is IScanCallback) {             LogUtils.d("AppLifecycleHandler onActivityCreated 扫描监听注册 $activity")             registerScanCallback((activity as IScanCallback))         }     }      override fun onActivityDestroyed(activity: Activity) {         if (activity is IScanCallback) {             LogUtils.d("AppLifecycleHandler onActivityDestroyed 注销扫描监听注册 $activity")             unregisterScanCallback((activity as IScanCallback))         }     }  }总结
  通过android.accessibilityservice.AccessibilityService的onKeyEvent捕获扫码输入,将KeyEvent传递给Scanner处理,Scanner将KeyEvent传递给android.text.method.TextKeyListener,捕获回车按键(或者其他自定义按键的时候)将识别结果抛到回调中,由扫码回调处理扫码结果。

季后赛表现出现下滑的几位球员,是什么原因导致的呢?联赛已经正式进入休赛期了,球员们难得的可以享受下属于自己的假期,那么在季后赛的舞台上,有哪几位球员的表现出现了一定的下滑呢?是什么原因导致的呢?首先是辽宁队的大韩,常规赛可以贡献1汪明荃罗家英结婚13周年,患癌历生死这辈子最大成就是爱她一生汪明荃与罗家英的结婚13周年纪念,他们相约好友一同庆祝,现年74岁的汪明荃与75岁的罗家英于1988年合演穆桂英大战洪州时相遇并相恋,两人相爱多年罗家英曾多次求婚也遭汪明荃拒绝,到秦海璐14年豪迈感情史,如今被王新军宠成公主!她确实值得媳妇的浪漫时光5开播,秦海璐和她老公王新军,塞给了观众第一把狗粮。看了他们两个的相处模式,朋友们才晓得,本来中年人的恋爱也能够这么甜。而以往在荧幕上脾气火爆的秦海璐,在王新军眼前,伊能静恋爱23年不被婆家接受,再婚嫁小10岁丈夫,48岁生二胎1997年,庾澄庆为伊能静写了一首只有为你,歌词里写道,我愿变成影子跟随着你,我的心变成一座城堡,一生一世只属于你。那时,两人已经相恋11年,还没有结婚的打算,从歌词中就能感受到浓瘟神温兆伦三婚两离,曾与郭羡妮恋爱,却向前任追讨青春费你见过分手后找女方要青春费的男人吗?从当红小生到万人唾弃的渣男,温兆伦只用了短短一年的时间。温兆伦情场浪子温兆伦,帅得彻底,渣得也彻底温兆伦出生于香港,受舅父的影响,他从小就对唱歌赵本山前妻葛淑珍打零工将女儿抚养成人,靠魄力成就一番事业提起葛淑珍这个名字,恐怕大多数人都是陌生的。但如果说她是赵本山的前妻,可能你则会不约而同说出噢,原来是她啊。他们共苦,可惜未能同甘。在赵本山一穷二白时结发,而在赵本山名声大噪提出离518正式迎娶爱人,CBA总决赛MVP的神仙爱情拿下职业生涯第二个CBA总冠军首个总决赛MVP一周后,辽宁男篮后卫赵继伟即将开启新的人生巅峰。5月18日,赵继伟就将和他的妻子王君瑞在海南三亚举办婚礼。婚礼请帖一经曝光,赵继伟顿时原神逃逸电子成就获得攻略2022原神逃逸电子成就获得方法2022,原神游戏中有很多的玩法,其中很多人在游戏中不知道逃逸电子成就应该怎么去获得,下面跟着小编一起来看看吧,希望此文章能帮到你。原神逃逸电子成就获得攻略饰品DTC品牌如何在一年内将GMV提升158?从春节到情人节,VANA很好地把握住了节日营销的机会,利用智能落地页和营销日历为店铺打造情人节气氛。添加满减满折倒计时动态购物车按钮营造促销氛围,刺激消费者下单。整个春节到情人节期国羽奥运冠军全家出游!吐槽老公虚有其表,世界冠军感慨带娃不易正值五一假期,国羽奥运冠军赵芸蕾与老公洪炜带着宝贝女儿出游,他们与友人一起,搭帐篷尝美食,享受好春光。不过,作为爸爸的洪炜却感慨,带娃不易,赵芸蕾也毫不留情地吐槽老公。赵芸蕾是国羽象棋小知识大师和特级大师晋升规则棋友们好,我们总听到象棋这个大师那个大师,其实呢,大师一般是用作对学者或者专家的尊称,就是给人一种很厉害的感觉。在我们象棋界,大师有一个更加专业的技术等级称号,叫做运动健将,特级大
因严重违反审慎经营规则,招商银行济南分行平安银行济南银行纷纷被罚2月21日,中国银保监会山东监管局发布的行政处罚信息公开表显示,招商银行有限公司济南分行存在以下违法违规行为流动资金贷款资金管理不尽职对个人经营贷款管理不尽职对房地产开发贷款资金使筑起制度的笼子头条创作挑战赛前几天,小区门口公路中间安上了护栏,乱停车的老大难问题瞬间迎刃而解。在这之前,乱停车现象严重,影响了正常通行,小区业主们苦不堪言,常常产生冲突,小区保安力不从心。交警真兰仪表深交所上市市值超百亿募资近20亿雷递网雷建平2月20日上海真兰仪表科技股份有限公司(简称真兰仪表,证券代码301303)今日在深交所创业板上市。真兰仪表本次公开发行股票7,300万股,发行价为26。8元,募资19学习机劝退贴小度学习机Z20Plus这是一篇劝退贴,欢迎来杠。最近各大教育母婴公众号,都在推的火的不得了的小度光学护眼学习平板Z20Plus,对,我买了高配版本。原打算靠这个开启测评博主的生涯,选题和提纲都搞好了da尽快取消不合理的股息红利差别税制度2015年版股息红利差别税制度实施已经七八年了。很多学者提出要全面取消股息红利税,主要的理由是重复收税。笔者认为,个人所得缴纳所得税理所当然,但对股息红利按持股时间长短实行差别化征张星星爸爸和老婆聊天记录,原来私底下也这么调皮,网友笑出鹅叫家长百问百答现在的家长每天都在想着怎么给学生更好的生活,尤其是学生教育问题,父母双方都有自己的看法。教育始终很复杂,不是一两句话能说明白的,尤其是现在家长的教育意识都提上来了,彼此国乒直通赛单打4强全部诞生!7大主力晋级,樊振东直接入围决赛北京时间2月21日上午,国乒2023年直通赛单打四强全部诞生!国乒十大主力中的王艺迪林高远爆冷输球,惨遭淘汰王曼昱虽然在小组赛全胜,但因为发烧退赛王楚钦虽然出线但也因为发烧退赛樊振A股,3300点上方犹如泰山压顶,接下来的行情会这样走中午收盘!果不其然,昨日大盘透支了上涨的动能之后,今天明显身心俱疲了,好不容易站上了3300点,一个跳水就打回了原形。个人认为,3300点上方的压力非常大,这里一步突破上去,并不是小米推出USB3。2Gen2x2高速移动固态硬盘,读写速率2000MBs手机电脑等设备的数据拷贝携带你是选择U盘还是移动硬盘?U盘速度不快,移动硬盘体积大,于是一种采用固态硬盘方案的移动固态硬盘开始兴起。近日,小米众筹上架了一款小米移动固态硬盘,1TB支付宝蚂蚁庄园2月20日答案哪种动作会让膝盖承受的压力更大?小鸡宝宝考考你!2023年2月20日支付宝蚂蚁庄园小课堂今日问题是1古语云春时宜食粥想要熬出黏稠的小米粥可以?2哪种动作会让膝盖承受的压力更大?答对即可获得小鸡饲料,下面我们一起来中国遭劳伦斯奖打压?谷爱凌落选最佳女运动员,跳水队奖杯被偷走近日,2023年劳伦斯世界体育奖公布了各个奖项的候选名单。其中,中国体育只有谷爱凌一人入围,而且她进入的只是最佳极限运动员提名,并非最佳女运动员。除了谷爱凌外,争议最大的显然是中国