Android电视机(机顶盒)初次开发的一些经验分享
从之前的web后台开发转到Android应用开发,做的第一个正式项目就是公司一个App的电视机(机顶盒)版本Demo开发。经过四个人近两周加班加点的开发和测试,总算按时交付了任务。在后续开发还没有开始之前,决定把这次开发当中学习到的一些知识和遇到的一些问题和大家的一起分享一下,由于也是刚开始做Android开发,并且是初次做电视机(机顶盒)上的开发,有什么不正确的地方,欢迎大家批评指正。另外,这也是我本人的第一篇原创博客,希望以后能坚持写下去!好,废话不多说,我们进入正题。
一、运行和调试
在做手机版Android开发时,要运行我们的程序,可以选择使用模拟器或者USB连接手机来运行。但是在做电视机(机顶盒)版本开发时,由于现在电视机(机顶盒)普遍的输出分辨率都在720P以上,用模拟器模拟并不是很方便,而采用数据线连接的方式,同样也不方便,客观上受到数据线长度和电视机(机顶盒)上接口的限制,而且这次在我们的开发之前进行调研的时候,发现使用数据线连接无法识别设备(也许和驱动有关)。总的来说,之前在手机上开发所用的方法,在电视(机顶盒)上并不好用。那该如何调试运行呢,总不能每次运行都打包,再通过其它方式把安装包装上去吧?答案当然是:no。
这里就要为大家介绍几个在电视机(机顶盒)我在本次开发中发现非常实用的几个adb 命令了:
1.adb connect [ip]
使用这个命令,可以连接指定ip的设备。有了这个命令,之前讲的问题就迎刃而解了,只要将我们的电脑和电视机(机顶盒)连入同一个局域网,就可以连接到相应的设备了,然后就可以在eclipse里直接运行或调试程序了。相应的有
adb disconnect [ip]
功能相信大家都懂得,就不解释了。
2.adb uninstall [package]
看名字相信大家也知道,这个命令可以用来卸载应用。在电视机(机顶盒)上卸载应用并不如我们在手机上方便,全部都要用遥控器来操作,使用这个命令就方便多了。而且这次开发过程中,由于我们设备有限,几个人使用一台电视机,经常需要卸载别人安装的不同签名的程序,这个命令省去了我们不少时间。
3.adb shell input text ****
这个命令的功能看字面儿相信也能猜得出来,就是用来输入文字的。我们在调试程序的时候,很多情况下要键入文字,这在手机上可能并不是个问题,可到了电视上,用遥控器按键盘真的会让你崩溃的,这个命令简直就是福音!
上面三个就是我在这次开发中使用最频繁的三个命令,其中第二和第三个的使用,都必须在使用第一个进行connect之后才有意义。当然,adb的命令还有很多,这里就不详细介绍了,有兴趣的话大家可以自行搜索。
二、焦点控制
关于焦点,在手机开发中,我们可能更多关心的是某个控件在焦点变化时的逻辑处理。而在电视机(机顶盒)上做开发时,每个控件只有获得了焦点,才能对其进行操作,因此,确保需要操作的控件能够获得焦点、控制焦点的前后顺序是一个非常重要的问题。例如,在一个布局中有多个控件,在点击遥控器的上下左右方向键时,焦点会移到哪一个控件,哪些控件仅仅做显示,但不需要获得焦点等等问题。
为了确保上述问题的可控性,我们可以通过以下方式来实现:
1.控制控件是否可获得焦点
![](https://code.csdn.net/assets/CODE_ico.png)
- android:focusable="true/false"
当这个属性置为true时,表示当前控件可以获得焦点,false则表示不可获得焦点。相应的,我们也可以在程序中通过以下代码来设置:
![](https://code.csdn.net/assets/CODE_ico.png)
- v.setFocusable(true/false);
2.控制按遥控器上下左右时下一个获得焦点的控件
![](https://code.csdn.net/assets/CODE_ico.png)
- android:nextFocusUp="@+id/..."
- android:nextFocusDown="@+id/..."
- android:nextFocusLeft="@+id/..."
- android:nextFocusRight="@+id/..."
这个相信不用多做解释,从字面意思就能很清楚的明白这四个属性的含义。相应的,在代码中也可以实现:
![](https://code.csdn.net/assets/CODE_ico.png)
- v.setNextFocusUp(id);
- v.setNextFocusDown(id);
- v.setNextFocusLeft(id);
- v.setNextFocusRight(id);
三、UI适配
UI适配在Android开发中是一件既麻烦又无法避免的事情,在本次开发中同样也碰到了这方面的问题。我们这次开发,主要适配1080p和720p两种分辨率。最开始的想法是,既然适配这两种分辨率,就指定这两种分辨率的资源,即
drawable-1920×1080
drawable-1280×720
相应地,提供对应分辨率下的尺寸:
values-1920×1080
values-1280×720
我们开发的时候,有一台42寸的电视盒两个机顶盒,电视最高支持4k分辨率,盒子只能输出720p分辨率。按照我们的适配策略,在电视和机顶盒上测试,都证明是正确的。然而,开发结束,送到测试那边时,他们使用的是32寸的1080p电视,就出现问题了,程序直接崩溃,无法运行,通过查看日志,发现是OOM问题。经过同事的分析,觉得是因为测试的电视虽然是1080p,但尺寸小,dpi高,是的所有图片都会被压缩,导致OOM。最后,更改了适配策略,采用了
drawable-sw1080dp
drawable-sw720dp
相应地,提供对应分辨率下的尺寸:
values-sw1080dp
values-sw720dp
解决了程序崩溃的问题。
虽然问题解决了,但我觉得原因其实是我们之前虽然采用了分辨率来适配,但是在values文件里,使用的却是dp单位,只是当时开发用的电视,恰好dpi是160,才使得UI显示正常。所以,采用最初的适配方案,将values中尺寸的单位改为px,应该也是可以的,当然这个还没有验证过,后面我会验证一下。
四、阴影的程序实现
为了界面的美观与动感,在电视APP设计中,往往会用到倒影和阴影的效果,我们这次的demo设计也不例外。开发中,我负责模块需要实现倒影和阴影,本来是想让美工来切图,但是美工不愿意,让我们用程序来实现,交涉许久无果之下,只得自己来了。倒影的生成,由另外一个同事写了一个公用方法实现了,这里就不和大家分享了,其原理基本上就是将原图倒置,画在画布上,然后加上一个半透明的蒙版,就搞定了。
阴影效果是我自己实现的,其实网上有很多讲阴影实现的教程,但是对我这个都不太适用,我需要的是在一个圆角矩形的图片四周加上阴影效果。经过很长时间的考虑,最后的办法是在原图四边加上矩形的阴影,然后在四个圆角的地方画扇形阴影来实现。不多说,直接上代码:
![](https://code.csdn.net/assets/CODE_ico.png)
- /**
- * @author: sunnybaby
- * @Title: createShadowBitmap
- * @Description: 生成带阴影图片
- * @param orignalBitmap:原图
- * @param shadowMargin:阴影边宽
- * @param iconCornerRadius:原图圆角半径
- * @return :生成的带阴影图片
- */
- public static Bitmap createShadowBitmap(Bitmap orignalBitmap,
- int shadowMargin, int iconCornerRadius) {
- int w = orignalBitmap.getWidth();
- int h = orignalBitmap.getHeight();
- Bitmap shadowBitmap = Bitmap.createBitmap(w + shadowMargin * 2, h
- + shadowMargin * 2, Config.ARGB_8888);
- int width = shadowBitmap.getWidth();
- int height = shadowBitmap.getHeight();
- Canvas canvas = new Canvas(shadowBitmap);
- canvas.drawBitmap(orignalBitmap, shadowMargin, shadowMargin, null);
- Paint paint = new Paint();
- paint.setXfermode(new PorterDuffXfermode(Mode.DST_OVER));
- int radius = shadowMargin + iconCornerRadius;
- // 四个边的阴影效果,采用线性阴影,宽度等于阴影边距+圆角半径
- LinearGradient leftGradient = new LinearGradient(radius, 0, 0, 0,
- 0x7F000000, 0x00000000, TileMode.CLAMP);
- LinearGradient rightGradient = new LinearGradient(width - radius, 0,
- width, 0, 0x7F000000, 0x00000000, TileMode.CLAMP);
- LinearGradient topGradient = new LinearGradient(0, radius, 0, 0,
- 0x7F000000, 0x00000000, TileMode.CLAMP);
- LinearGradient bottomGradient = new LinearGradient(0, height - radius,
- 0, height, 0x7F000000, 0x00000000, TileMode.CLAMP);
- paint.setShader(leftGradient);
- canvas.drawRect(0, radius, radius, height - radius, paint);
- paint.setShader(rightGradient);
- canvas.drawRect(width - radius, radius, width, height - radius, paint);
- paint.setShader(topGradient);
- canvas.drawRect(radius, 0, width - radius, radius, paint);
- paint.setShader(bottomGradient);
- canvas.drawRect(radius, height - radius, width - radius, height, paint);
- // 四个角的阴影效果,采用圆形阴影,半径等于阴影边距+圆角半径
- RadialGradient topLeftCornerGradient = new RadialGradient(radius,
- radius, radius, 0x7F000000, 0x00000000, TileMode.CLAMP);
- RadialGradient topRightCornerGradient = new RadialGradient(width
- - radius, radius, radius, 0x7F000000, 0x00000000,
- TileMode.CLAMP);
- RadialGradient bottomLeftCornerGradient = new RadialGradient(radius,
- height - radius, radius, 0x7F000000, 0x00000000, TileMode.CLAMP);
- RadialGradient bottomRightCornerGradient = new RadialGradient(width
- - radius, height - radius, radius, 0x7F000000, 0x00000000,
- TileMode.CLAMP);
- // 画四个角,就是画四个圆心角为90度的扇形,drawArc函数第一个参数为圆弧所在圆的的外接矩形,第二个参数为起始角度,第三个参数为扇形顺时针滑过的角度,第四个参数如果为true时,在绘制圆弧时将圆心包括在内(用来画扇形),第五个参数为画笔
- paint.setShader(topLeftCornerGradient);
- canvas.drawArc(new RectF(0, 0, radius * 2, radius * 2), 180, 90, true,
- paint);
- paint.setShader(topRightCornerGradient);
- canvas.drawArc(new RectF(width - radius * 2, 0, width, radius * 2),
- 270, 90, true, paint);
- paint.setShader(bottomLeftCornerGradient);
- canvas.drawArc(new RectF(0, height - radius * 2, radius * 2, height),
- 90, 90, true, paint);
- paint.setShader(bottomRightCornerGradient);
- canvas.drawArc(new RectF(width - radius * 2, height - radius * 2,
- width, height), 0, 90, true, paint);
- return shadowBitmap;
- }
好了,以上就是这次开发中想跟大家分享的一些东西,欢迎大家的批评指正。
Android电视机(机顶盒)初次开发的一些经验分享相关推荐
- android 机顶盒 系统开发入门,读《Android电视机(机顶盒)初次开发的一些经验分享》后的笔记...
原文: http://blog.csdn.net/tanghongchang123/article/details/52982818 一.基本命令: 1.adb connect [ip] 2. adb ...
- 2019-安卓开发环境搭建-经验分享-Eclipse(主要内容)+Android Studio
2019-安卓开发环境搭建-经验分享-Eclipse(主要内容)+Android Studio 0. 引言 1. 常见问题 2. 配置安卓开发环境 2.1 准备 JDK 环境 2.1.1 下载 JDK ...
- android红米3调用相机,手机拍照经验分享:用Redmi K30拍极光!
手机拍照经验分享:用Redmi K30拍极光! 2019-12-19 16:51:29 2点赞 1收藏 1评论 样的一部手机,到底可以拍出怎样的照片,在不同人的手中有着不同的表现.比如大部分普通人,只 ...
- 太牛了!3年Android开发工程师面试经验分享,跳槽薪资翻倍
开头 眼看着金九银十就快来了,各大厂也开始了新一轮的招聘计划,尤其是腾讯前一段时间爆出了一个大消息: 将正式启动2021届秋季招聘,加大对数字经济和产业互联网人才的挖掘培养. 在本次招聘中,特别面向2 ...
- 3年Android开发工程师面试经验分享,先收藏了
前言 程序员这个行业,日新月异,技术体系更新速度快,新技术新框架层出不穷,所有的技术都像是一个无底洞,当你学得越多就会发现不懂的越多,不懂的越多,需要学习的就更多. 因此,一旦选择了这个行业,就意味着 ...
- 3年Android开发工程师面试经验分享,含泪整理面经
一.认识鸿蒙 鸿蒙 微内核是基于微内核的全场景分布式OS,可按需扩展,实现更广泛的系统安全,主要用于物联网,特点是低时延,甚至可到毫秒级乃至亚毫秒级. 鸿蒙OS实现模块化耦合,对应不同设备可弹性部署, ...
- Android 5.0 + IDA 6.8 调试经验分享
现在升级快,网上的资料只能做参考. 学到了NDK逆向这一块,昨天为了能让IDA 能动态调试SO,瞎折腾了很久,这里分享一下我的经验. 工具: IDA pro 6.8 Android 5.x ID ...
- 【Android市场】提交应用的一点经验分享
前言 如果只有一个或者少许的两三个Android市场,本文也没用存在的必要性,本文谨献给同在Android奋战的同仁. 声明 欢迎转载,但请保留文章原始出处:) 博客园:http://www.cnbl ...
- Java程序员春招三面蚂蚁金服,1-3年Java开发工程师面试经验分享
前言 为什么互联网资讯这么发达,但是没有出现技术人才井喷? 为什么会出现应届生薪资倒挂多年老员工的现象? 这个世界有太多的现象都可以用**"二八定律"**来解释. 20%拿着高工资 ...
最新文章
- c语言的编译过程,程序编译过程
- struts2 验证框架原理及实例
- 使用MarkDown标记语言发博客
- [分享]极富挑战性的大公司面试的智力题
- 本科生获42万元奖学金!培养拔尖人才,这所高校动真格!
- 冠军轮流转:Q3 季苹果超越小米,回到全球最大的可穿戴设备厂商宝座
- JAVA大数据-Week2-DAY5
- 【读书笔记】推荐系统实践-常见推荐算法及应用
- Nachos编译与使用--Nachos配置
- c语言取反运算详细步骤,C语言之位运算详解
- java小游戏_Java开发小游戏,30分钟教会你
- ppt怎么压缩,ppt压缩的技巧分享
- Python 输出100-999的水仙花数
- 基于BP神经网络的车牌识别系统的设计
- TransOMCS:从语言图提取常识知识
- 两条边延长角会有什么变化_用图中这种测量工具可以量出图中零件上ab cd这两条轮廓线的延长线所成的角你能说出其中的道理吗...
- 自有系统对接 有赞 商城 具体对接流程
- 求高手解答,如何在VM虚拟机上用u盘进入PE系统然后进行安装系统
- FastCGI的认识与使用
- 黑客与画家 Hackers and Painters: Big Ideas from the Computer Age
热门文章
- 史上最全《计算机网络 自顶向下方法》答案合集
- 罗克韦尔编程软件RSLogix5000 win7 64位那什么的方法
- Python短链接生成、长链接还原,就是这么简单!
- MATLAB的乘法函数,Matlab乘法函数
- php aes 256 加解密,PHP完整的AES加解密算法使用及例子(256位)
- 2022.11.15【bug笔记】|Error in FASTQ file at line 55: Line expected to start with ‘+‘, but found ‘G‘
- 计算机专业Java毕设怎么做
- IPv6进阶:IPv6 过渡技术之 NAT64(IPv6 节点主动访问 IPv4 节点-地址池方式)
- 用mysql查找姓王的行为轨迹_mysql查询
- JSD-2204-Vue-ElementUI-Day06