基于Android的屏幕死区生成器的应用
2020-06-10张启贤成丽君王堃
张启贤 成丽君 王堃
(山西农业大学 山西省晋中市 030801)
1 研究背景
当今社会,手机已经成为了人们生活中不可或缺的一部分,其强大的功能给我们带来了极大的便利。从第一台触屏手机问世到现在已经过去了许多年,移动互联产业也发展得越来越成熟,手机经历了一代代技术革新,设计外观和功能与以往相比有了很大不同,这其中必然会带来许多新的问题待我们去解决,例如全面屏手机所带来的问题。
随着屏幕封装技术的发展,特别是“COF”(Chip On Film)又称覆晶薄膜封装技术的发展,越来越多的手机开始走高屏占比路线。高屏占比极大地提升了手机的外观以及显示面积,且受到大多数消费者的青睐,目前各大厂商都尝到了甜头,纷纷顺应趋势发展,有些厂商甚至推出了“折叠屏”以及“曲面屏”产品。而“全面屏”是一种新兴的手机设计理念,主要表现为手机正面的触摸屏面积占比尽可能的大,达到近似于“手机正面全是屏幕”的效果。不同于以往手机正面顶部以及底部所拥有的硕大的非触控面板,全面屏手机正面的可触控区域非常大,用户用手握持手机时,难免会无意间触碰到屏幕部分,俗称“误触”。误触的原因有很多,例如屏幕大、手势丰富、反馈感不强等,但据相关研究显示,屏幕大以及拇指活动范围正是是造成误触的关键因素,尤其对于一些以娱乐、游戏为主要目的用户来说,屏幕误触会严重影响到其操作的准确性以及触摸的灵敏性,引起拖动失效等,造成交互问题。
目前,根据极光(Aurora Mobile,NASDAQ:JG)发布《2019年手机游戏行业研究报告》来看,我国手游用户规模极大。据统计,中国手游用户 MAU ( monthly active users,指在线软件的一个用户数量统计名词。)达8.25亿,安装渗透率达73.6%,人均每月游戏时长879分钟[1]。据亚洲游戏市场数据分析机构Niko Partners统计,国内手游产业发展迅速,PC网游的表现较2017年略有下降,不过手游方面的营业额则比之前上涨了28.9%,达到了1057亿元人民,Niko预测,到2023年,中国的手游营业额将达到1725亿元人民币[2]。而据调查显示,玩家群体中,95%的玩家会去玩手机游戏,仅有5%的玩家选择不接触手游。如图1、图2所示。
图1:移动游戏市场预期|数据来源:Niko Partners
图2:游戏玩家中接触手游人数占比|数据来源:Niko Partners
图3:全面屏手机误触图示
可以看出,在游戏玩家群体中,有大约95%的人选择使用手机玩游戏,且这一群体的规模以及投入还在逐渐增加。随着5G的逐渐成熟,全面屏手机也会进一步占据市场份额。可以预见,将会有更多的人利用全面屏或者曲面屏智能手机玩游戏。同时,越来越多的人在游戏娱乐时会发生屏幕误触问题,这会导致大批人拥有极差的手机游戏体验,甚至影响手游产业以及手机口碑。因此,解决屏幕误触这一问题便显得非常有实际意义。用户握持全面屏手机时,拇指活动范围内难免会触碰到屏幕边缘造成误触,示意图如图3所示,其中红色区域为误触区域。
图4:方案开启屏幕死区流程图
2 屏幕死区的研究及方案的提出
为解决误触问题,那么我们可否尝试把这一块误触区域“废掉”呢?我们来引入“屏幕死区”这一概念。
在以往看来,“死区”算是一种电子产品的硬件故障或者问题,在手机业界有定义:虽然手机屏幕的部分区域虽然可以正常显示,但是触摸却没反应,此部分区域便是屏幕死区。在平板电脑领域也有一些关于“死区”的说法,如果使用手写笔在平板电脑屏幕上绘画,手掌根部难免会压在屏幕上,手指也可能参与绘画,而无源手写笔的笔头为1到2mm,如果用户手写绘画时能把手搁在屏幕上,同时又保持足够的速度和准确度,确保接触点刚好就是“墨水”的“着墨之处”,这样才可以说满足用户使用需求。可是有时对于一块屏幕来说,手写笔在屏幕传感器中心位置的微小移动很难被检测到,对于传感器而言,输入通常被量化到元件的中心,因此,当手写笔尖的移动仅位于单个传感器元件微小的范围内时,会被报告为处于固定位置,这块区域这就是所谓的“死区”(DeadZone),即使输入刺激转移到新位置时报告信号电平也不发生改变的区域[3]。虽说能识别手指触摸,但是无法识别细微的笔尖移动,或者反之,能利用手写笔绘画,但手指无法与平板电脑交互,都会使产品达不到预想的功能要求。因此,该类设备还需要非常复杂的算法来识别不同的触控事件。
但是“死区”对我们并不是百害而无一利,目前一些厂商针对全面屏手机误触问题所提出的解决方案正是巧妙利用“死区”这一概念。设置屏幕死区其实相当于把屏幕一部分“废掉”,使其不具备交互功能。例如,针对一些曲面屏手机,将手机侧面屏幕部分设置成死区,即禁用该区域的触摸事件,系统不对其作出反应;部分品牌手机的游戏中心自带的屏幕死区功能,主要是通过设置触控IC的参数来防止屏幕误触的;而我们接打电话时的“防误触模式”相当于把整块屏幕设置成了屏幕死区,只不过是通过把整块屏幕关掉来实现的。一些方案大多实现成本较高,设计参数设置复杂、灵活性较差、不方便随时切换屏幕工作状态、功能易受品牌限制。
表1:测试用例
本文将提出一种基于Android的屏幕死区生成方案,其创建流程如图4所示。
3 屏幕死区软件的实现与关键算法
本方案主要利用了Android系统服务生成悬浮窗原理来生成悬浮区域——“屏幕死区”。软件操作界面如图5所示。
悬浮窗是电脑或手机的系统工具,在其他应用的表面悬浮、可移动的窗口,可以覆盖于其他程序界面上层,不对其他正在运行的程序造成一定影响,而且开启灵活。对于Android操作系统来说,界面绘制主要是通过WindowManager(app与window通信的一种接口)的服务所实现的。它可以悬浮在已打开的手机应用界面上,不挤占本来就不大的手机屏幕空间,能够让用户在使用一个应用程序同时完成其他工作。实现悬浮窗,我们就要利用WindowManager来“做手脚”。而创造一种独立于其他应用界面的屏幕死区,则要在悬浮窗上“做手脚”。
WindowManager实现了ViewManager接口,可以通过获取WINDOW_SERVICE系统服务得到[4]。而ViewManager接口有addView方法,我们就是通过这个方法将悬浮窗控件加入到屏幕中去,实现绘制。由于本方案具体实现方法主要在一个Service中,系统开启本Service后,相当于宣告屏幕死区的绘制完成,所以在最初,我们还应判断软件是否开启了绘制悬浮区域所需的系统权限,并根据系统版本进行放权。
创建悬浮窗后,接下来我们要把悬浮窗变成屏幕死区,是本方案的核心。首先获取一个WindowManager服务对象,之后创建一个LayoutParams对象,这是一个参数包对象,绘制屏幕死区的所需参数都打包在这个对象中。由于本方案计划支持数据读写功能,方便用户快速开启所需的屏幕死区,所以软件应设有数据库系统。用户可以将自定义的一组屏幕死区高度以及宽度数据存储到数据库中,每一组数据都拥有自身的id,在下次使用时,可根据id轻易读出。而为了实现屏幕死区的核心特性——隔离用户触摸、不遮挡其他应用程序,我们仅需对悬浮区域的布局参数做以下手脚:设置flags(FLAG_NOT_FOCUSABLE;)实现该区域不可聚焦,弹窗以外部分可以触摸,设置params.format属性为透明。LayoutParams参数包对象极大地方便了屏幕死区的参数设置,它原本是Android系统绘制悬浮区域的“助手”,却帮助了我们对悬浮窗“改造”。我们可以将上述的死区大小参数以及用来设置屏幕死区特性的参数一并打包,在绘制悬浮区域的时候加进去。
图5:软件操作界面
如何自定义大小,仅有参数的设置是不够的,为绘制屏幕死区,方案软件主界面采用了谷歌现阶段建议使用的ConstraintLayout布局方式,这种布局方式灵活,可以有效地解决布局嵌套过多的问题,相对位置度量清晰,我们可以将设置死区大小的控件、按钮等在这个框架下嵌套、排版,实际运行界面良好。
每一个Android工程创建都会默认创建一个Activity(Activity是一个应用程序组件,提供一个屏幕,用户可以用来交互、完成某项任务),在该组件上引入设计好相关布局文件。其中该界面上该有有相应的按钮用于开启Android Service并传输数据给Service,并绑定startService方法来开启所创建的Service。Activity相当于一个“启动器”,而悬浮区域(屏幕死区)拥有独立的布局,并拥有单独的关闭按钮或者调节控件, 在其他程序中运行时也可快捷方便地关闭、设置,与“启动器”分开,不受其他布局影响。这样,我们才可以实现屏幕死区在其他应用程序界面之上也能够顺利地工作。
上述实现主要过程封装在一个自定义方法——createtoucher方法中,其主要代码如下所示:
输入:
数据库中存储的屏幕死区数据id;
图6:游戏软件应用测试图
图7:视频类软件应用测试图
对应id的屏幕死区高度和宽度(ai,bj);
数据库控制类Controller;
获取屏幕长宽数据的方法getResources().getDisplayMetrics();
屏幕死区自身xml布局toucherlayout.
过程:
1:final Controller controller=new Controller(MyService.this);
2:定义查询集final Cursor cursor=controller.query("0");
3:获取一个WindowManager服务对象:windowManager = (WindowManager)getApplication().getSystemService(Context.WINDOW_SERVICE);
4:params = new WindowManager.LayoutParams();
5:IF (Build.VERSION.SDK_INT>=Build.VERSION_CODES.0_MR1)
6: params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
7:ELSE params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
8: params.format = PixelFormat.RGBA_8888;
9: params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
10:DisplayMetrics dm = getResources().getDisplayMetrics();
11:h1= dm.heightPixels,w1 = dm.widthPixels;
12:params.x = w1,params.y = h1;
13:WHILE cursor.moveToNext() DO
14: height1=cursor.getInt(ai);
15: width1=cursor.getInt(4);
16:params.width =width1;
17:params.height = height1;
18:获取死区窗口xml布局;
输出:windowManager.addView(toucherLayout, params);
4 “屏幕死区”软件的测试与应用
4.1 软件测试
测试方案主要测试了在屏幕底部左右生成的两个屏幕死区。经测试,所开启的屏幕死区有效防止了握持时用户手掌以及手指根部贴近屏幕边缘所引起的误操作。本方案设置死区关闭方式为双击绿色按钮区域关闭,有效防止了用户在其他应用中操作时意外关闭已生成的屏幕死区,经测试,软件逻辑设计效果良好。
测试项如表1所示。
4.2 软件应用
本方案屏幕死区生成软件可以应用于各种场景,例如玩游戏时,在手机屏幕边缘生成自定义大小的屏幕死区,经验证可以有效防止误触屏幕边缘造成游戏内误操作,而且不遮挡游戏界面。还可以在用户握持手机观看视频时,防止边缘误触所导致的进度条意外拖动或者拖动失败,不遮挡视频内容,优化全面屏手机用户的视频体验。应用示意图如图6、图7所示。
5 结语
本文提出了基于Android悬浮窗创建可自定义区域大小的屏幕死区生成方案,通过详尽的测试用例验证了方案的可行性,能够解决手游用户屏幕误触问题。该软件不会对其他应用程序造成影响,属性设置简单,开启方便,占用内存小。随着5G的成熟应用,高屏占比的手机市场的进一步扩大,该方案能够为更多使用全面屏手机的用户处理屏幕误触方面提供实际帮助。但是,该软件还需要在诸如适配性、界面美化、更自定义化等方面进一步完善。