Android TV Overscan
本文来自网易云社区
作者:孙有军
开发的TV应用发现在部分电视上可以显示完整,而其他部分电视显示不全,周围都会遮挡了。
原因
这是因为部分老的电视有一个overscan的概览,什么叫overscan呐?官方解释如下:
During the evolution of TV technology, overscan originally described an area of TV content outside of a safe zone that most TVs could reliably display. Even on some of today’s HDTV flat screens, areas outside that zone may not be visible.
整个展示的界面是外面整个矩形框,而可见区域是内部的矩形框,因此如果你布局的内容紧邻边界,就会导致部分电视不能完整显示整个内容。
解决方案
上面的问题,我们怎么解决呐?这里给出两种解决方案。
设置调整
虽然老的电视有overscan的概念,内容显示不全,但是电视可以设置他的显示内容距离电视边框的距离,这里主要依靠人为的手动设置,方式如下:
一般都是选择遥控板的设置,进入设置界面,选择显示,边距调整
经过上述方式的调整,可以设置内容与边框有一定的距离,这样可以让所有的内容都显示出来。
难点:该方式必须要用户手动调整,如果不调整则显示内容被遮挡体验效果比较差
UI调整
既然让大家都采用手动调整是比较困难的,那有没有从应用层面来解决该问题的方法,有,肯定有,官方的文档也给出了解决方案:
Build a 5% margin into your TV screen designs to account for overscan area the TV may not display correctly. On a 1920 x 1080 screen, this margin should be a minimum of 27 pixels from the top and bottom edges and a minimum of 48 pixels from the right and left edges of the picture.
上面的意思是,在设计界面的时候,就空出四周的overscan距离,以1920*1080为例上下27px,左右48px,让显示的内容完全处于安全区域,周围都是无关内容区域。
缺点:如果设计的内容需要靠近边界,比如说底部有一个导航条,可以显示与影藏,这种时候就需要贴近边界进行设计。如果再设计的时候空出一部分,那在overscan的电视上展示较好,无overscan的电视展示就比较差,如果不空,这效果相反
自适应?
既然上面的两种方案都是有缺点的
全部让用户手动设置不显示
空出部分内容,在有的时候会显示效果比较差
那有没有一种方法来解决上面面临的问题?能够根据电视状况自动缩放内容,在有overscan的电视上,拿到overscan的值,设置显示内容与边界为overscan的值,在没有overscan的电视上保持内容不调整。
方案探索
首先我们看代码,看看代码中是否有overscan的值,经过一番查找,在Android中有一个Display类,他包含了很多显示信息,其中有一个字段为DisplayInfo,DisplayInfo包含了其他的一些显示信息。其中有四个字段如下:
/*** Describes the characteristics of a particular logical display.* @hide*/public final class DisplayInfo implements Parcelable {.... /*** @hide* Number of overscan pixels on the left side of the display.*/public int overscanLeft; /*** @hide* Number of overscan pixels on the top side of the display.*/public int overscanTop; /*** @hide* Number of overscan pixels on the right side of the display.*/public int overscanRight; /*** @hide* Number of overscan pixels on the bottom side of the display.*/public int overscanBottom; public DisplayInfo() {}.... }
这里我们省略了其他的代码,可以看到包含有overscanLeft, overscanTop,overscanRight,overscanBottom,这就是Overscan的值,到这里感觉有希望。既然有这四个值,那我们获取到这四个值再设置会界面应该就能达到我们想要的效果。
读取overscan
从上面的代码中我们可以看到DisplayInfo是被hide掉的,四个值也是被hide掉的,说明从正常的先拿到Display,再拿到DisplayInfo,之后再获取四个值是不行的了,那我们反射来获取该值,代码如下:
public static Rect getOverScan() { if (overScan == null) {overScan = new Rect(); try {WindowManager manager = (WindowManager) AppProfile.getContext().getSystemService(Context.WINDOW_SERVICE);Display display = manager.getDefaultDisplay();Class clazz = Display.class;Field mDisplayInfo = clazz.getDeclaredField("mDisplayInfo");mDisplayInfo.setAccessible(true);Object displayInfo = mDisplayInfo.get(display);Class displayInfoClazz = Class.forName("android.view.DisplayInfo");Field overscanLeft = displayInfoClazz.getDeclaredField("overscanLeft");overScan.left = overscanLeft.getInt(displayInfo);Field overscanTop = displayInfoClazz.getDeclaredField("overscanTop");overScan.top = overscanTop.getInt(displayInfo);Field overscanRight = displayInfoClazz.getDeclaredField("overscanRight");overScan.right = overscanRight.getInt(displayInfo);Field overscanBottom = displayInfoClazz.getDeclaredField("overscanBottom");overScan.bottom = overscanBottom.getInt(displayInfo);} catch (Exception e) {}} return overScan; }
首先获取到Display,之后在反射获取DisplayInfo,最后在读取四个值。
也可以直接反射获取Display下的getOverscanInsets函数, getOverscanInsets函数如下:
/*** @hide* Return a rectangle defining the insets of the overscan region of the display.* Each field of the rectangle is the number of pixels the overscan area extends* into the display on that side.*/public void getOverscanInsets(Rect outRect) {synchronized (this) {updateDisplayInfoLocked();outRect.set(mDisplayInfo.overscanLeft, mDisplayInfo.overscanTop,mDisplayInfo.overscanRight, mDisplayInfo.overscanBottom);} }
反射获取方式如下:
public static Rect getOverScan1() {Rect overScan = new Rect(); try {WindowManager manager = (WindowManager) AppProfile.getContext().getSystemService(Context.WINDOW_SERVICE);Display display = manager.getDefaultDisplay();Class clazz = Display.class;Method getOverscanInsets = clazz.getMethod("getOverscanInsets", Rect.class);getOverscanInsets.invoke(display, overScan);LogUtil.free(overScan.toString());} catch (Exception e) {} return overScan; }
我们采用上面方法在debug状态下读取了一下DisplayInfo的内容:
Display id 0: DisplayInfo{"内置屏幕", app 1280 x 720, real 1280 x 720, largest app 1280 x 1255, smallest app 720 x 695, 50.0 fps, rotation0, density 160 (160.0 x 160.0) dpi, layerStack 0, type BUILT_IN, FLAG_SECURE, FLAG_SUPPORTS_PROTECTED_BUFFERS}, DisplayMetrics{density=1.0, width=1280, height=720, scaledDensity=1.0, xdpi=160.0, ydpi=160.0}, isValid=true
反射后获取,发现并没有overscan的值,很遗憾四个值都是0。可是我测试的电视是有overscan的。代码写错了?
我采用命令来设置overscan的内容:
adb shell wm overscan 10,20,30,40
分别设置overscan的值为10, 20, 30, 40,之后我再一次获取DisplayInfo的值,内容如下:
Display id 0: DisplayInfo{"内置屏幕", app 1280 x 720, real 1280 x 720, overscan (10,20,30,40), largest app 1280 x 1255, smallest app 720 x 695, 50.0 fps, rotation0, density 160 (160.0 x 160.0) dpi, layerStack 0, type BUILT_IN, FLAG_SECURE, FLAG_SUPPORTS_PROTECTED_BUFFERS}, DisplayMetrics{density=1.0, width=1280, height=720, scaledDensity=1.0, xdpi=160.0, ydpi=160.0}, isValid=true
这里可以看到明确有overscan的内容,并且就是我们命令设置的值,这就尴尬了,系统默认值获取不到,手动设置可以获取。希望之路破灭。
总结
如果有人实现了自适应的方式,麻烦请告知一下。目前只能采取UI界面调整的方式来避免该问题。
网易云免费体验馆,0成本体验20+款云产品!
更多网易研发、产品、运营经验分享请访问网易云社区
相关文章:
【推荐】 消息推送平台高可用实践(下)
【推荐】 【你离硅谷只差一步】网易中国创业家大赛项目火热征集中
【推荐】 解读滑块验证码(滑动验证码)与图形验证码的破解难度
转载于:https://www.cnblogs.com/163yun/p/9711834.html
Android TV Overscan相关推荐
- android+tv+社区,Android TV Overscan
本文来自网易云社区 作者:孙有军 开发的TV应用发现在部分电视上可以显示完整,而其他部分电视显示不全,周围都会遮挡了. 原因 这是因为部分老的电视有一个overscan的概览,什么叫overscan呐 ...
- 【Android】android TV开发
google翻译[https://www.jianshu.com/p/c216849986ed] Ⅰ.开始使用电视应用 为了使您的应用在电视设备上获得成功,您必须设计出可以在10英尺远的地方轻松理解的 ...
- Android TV开发总结(三)构建一个TV app的焦点控制及遇到的坑
原文:Android TV开发总结(三)构建一个TV app的焦点控制及遇到的坑 版权声明:我已委托"维权骑士"(rightknights.com)为我的文章进行维权行动.转载务必 ...
- 针对Android Tv的自定义RecyclerView2 0横竖向连动
版权声明:本文为博主原创文章,转载请注明出处. 推荐: 欢迎关注我创建的Android TV 简书专题,会定期给大家分享一些AndroidTv相关的内容: www.jianshu.com/c/37ef ...
- 【Android TV 开发】焦点处理 ( 父容器与子组件焦点获取关系处理 | 不同电视设备上的兼容问题 | 触摸获取焦点 | 按键获取焦点 )
Android TV 开发系列文章目录 [Android TV 开发]安卓电视调试 ( 开启网络远程调试 ) [Android TV 开发]焦点处理 ( 父容器与子组件焦点获取关系处理 | 不同电视设 ...
- 如何在Android TV上自定义推荐行
When you fire up Android TV, the first thing you see is a list of movies and shows the system thinks ...
- android 设备名称_如何更改您的Android TV的设备名称
android 设备名称 Android TV is Google's attempt at taking over the living room, and with some units bein ...
- Android插u盘自动执行,android tv box ---- 插入u盘直接播放指定文件夹中的视频
android tv box ---- 插入u盘直接播放指定文件夹中的视频思路: 1.监听u盘插入广播 2.遍历指定目录下的所有文件,找到视频文件 3.将符合条件的文件加入播放集合中 4.循环播放 n ...
- 谷歌宣布关闭Google TV,由Android TV接任
早在2013年就有相关的报道称随着Android生态系统的不断完善谷歌将逐渐淘汰"Google TV"品牌,转而使用更受消费者认可的"Android TV"品牌 ...
最新文章
- wegame饥荒一直连接中_23万人捧场热血传奇怀旧版,WeGame拯救计划,前景如何?...
- Linux Redis 重启数据丢失解决方案,Linux重启后Redis数据丢失解决方
- 文件系统损坏导致虚拟机无法正常启动的问题及解决方法
- php 实时监测网站是否异常_网站监控劫持问题,怎么通过网站监控解决劫持问题...
- 安卓安卓移动操作系统优缺点
- laravel-admin集成ueditor编辑器
- UE4 Packaging and Cooking Games
- 12-31--MAGENTO---强大的配置功能挖掘!!
- DRBD安装编译后: modprobe drdb FATAL: Module drdb not found
- wps2005插件开发之旅
- selenium: 网页打开最大化
- 哈霍兰服务器修改WCL记录,魔兽世界:怀旧服哈霍兰服务器再创纪录,最强“刷子”六天刷出420万荣誉...
- 统计系统技术方案-clickhouse
- wps在线浏览 java_java实现word转pdf在线预览(前端使用PDF.js;后端使用openoffice、aspose)...
- 悦读(小程序)~~~~~~青龙脚本
- 【翻译】乔尔测试:改进代码的12步
- 互联网日报 | QQ正式上线QID功能;高通骁龙888处理器正式发布;嫦娥五号成功落月...
- 深圳市租房提取住房公积金攻略
- 北京大学软微第二学位可能被取消!高校第二学士学位将成历史!
- 2020年度总结——魔幻的一年,魔幻的我
热门文章
- java获取子路径_Java中路径的获取
- Maven学习(六)————企业Maven项目最佳实践
- 数据列表的分页实现————分页敏捷开发
- 接上一篇--最小生成树之Prim算法(根据点来实现最小生成树)
- rabbitmq+topic+java_译:5.RabbitMQ Java Client 之 Topics (主题)
- 画出微型计算机结构图,中级工792、画出计算机环形网络模式图.doc
- 二进制法生成1-n的子集
- lisp scheme 果壳_走出Lisp(Scheme)困境
- bloomberg用法 固定收益_干货 | 日语高考高频考点:助词を的用法
- 基础练习 FJ的字符串 递推 C++