前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从门外汉到开发出TV应用,我只用了三天

从门外汉到开发出TV应用,我只用了三天

作者头像
吴延宝
发布2019-07-24 15:43:28
3.5K0
发布2019-07-24 15:43:28
举报
文章被收录于专栏:中国Android研究院

IT烂笔头

互联网/移动开发/创业/职场

1

背景

在这之前,本人一直从事Android手机应用层的开发。从没有接触过Android TV端的开发工作。当领导问能否在一周内做出一个TV端Demo时,自己心里还很是比较虚的。但是实际上,从开始调研到动手做到最后将Demo给领导演示出来,花了不超过3天的时间。当然这三天,每天都是做到晚上11点以后的(大部分时间是解决一些细节问题)。功能相当于是KEEP训练跟练的TV版,业务交互还是有一些难点的。当领导对你的Demo表示认可后,接下来等产品和设计师完整的出了TV端产品的整个UI和设计,我们就开始正式的进入TV端产品的搭建过程。

Android TV当然也是Android的系统,所以尽管我们没有任何开发TV的经验,我们仍然能够凭借开发手机应用的经验在开发TV应用时也能得心应手。但是,在TV端开发和手机也是不同的,下面就把我的一点小经验分享给大家。

2

连接开发设备

开发TV的项目,最好使用机顶盒或者智能电视,当然也可以使用模拟器(推荐:网易MuMu)。当你使用盒子(机顶盒以下均称盒子)作为开发设备时,你需要将你的开发电脑与盒子进行连接。一般来说,不同的盒子的连接方式不一样。以乐视和天猫的盒子为例,我们需要将盒子和开发设备连在同一局域网中,并查看盒子的IP地址(假如为192.168.2.17)。

接下来你可以使用下面的adb命令连接盒子:

java adb connect 192.168.2.17

这个命令相当于我们开发手机应用时连接手机的过程,如果连接失败,你可以检查一下是否在同一个局域网,IP地址是否正确,端口号是否正确。注意,有些盒子在连接的时候需要加上端口号的,有些不用指定端口号,因为默认使用的是5555。如果是小米的盒子可以直接用USB线连接盒子和电脑就可以了,当然盒子也是有开发者模式的,在我们安装我们的APP之前,先要允许通过adb安装APK。

3

新建TV项目

使用AndroidStudio新建一个TV Project,或者如果是基于你们公司移动产品做一个TV版,你完全可以将一些公共组件抽取出来,对于TV新建一个Module依赖于这些基础组件,这样会为TV项目节省很多成本。开发TV应用的时候,可以借助谷歌的一个库:Leanback。谷歌官方也提供非常丰富的Demo页面,当然你的产品设计可能没法完全使用谷歌提供的demo页面,但是Leanback中也提供了一些好用的控件:HorizontalGridViewVerticalGridView等等。

4

编码

代码写起来,和移动应用开发没什么不同。但是由于TV端的操作不是触屏的,是由遥控器来操作的。所以,在TV中,能够被遥控器选中的View需要设置focusable=true,即需要View能够获取焦点。当我们操作遥控器的上下左右键的时候,Android默认会寻找当前焦点View的上下左右最近的可获得焦点的View作为焦点移动的方向。

这样就有一个问题,有时候默认的移动方向并不是按照我们所预期的。还有的时候,我们布局中有嵌套好几层的View,外部View获取焦点和内部View获取焦点的策略我们怎么去控制?与我们在触屏中的Touch事件的分发,在TV中大多需要考虑的便是焦点事件的分发。Android也为我们配置了简单的API去定义焦点的移动。例如,我们可以在代码中或者布局中指定某一个View的上(nextFocusUp)下(nextFocusDown)左(nextFocusLeft)右(nextFocusRight)键该移动到哪个View。

还有一些需要焦点记忆功能,你需要自己重写焦点的分发。

另外一个交互特点是,当我们的View获取到焦点即通过遥控器选择到View时,通常我们需要对被选择的View做特殊处理。比如背景色突出,大小放大缩小(其实就是做一个scale的动画)。如果需要选中框的效果,可以使用selector的state_focused控制使用不同的drawable做背景。

对于遥控的按键监控,可以通过重写:

代码语言:javascript
复制
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        return super.onKeyDown(keyCode, event);
    }
代码语言:javascript
复制

常用的按键如下(定义在KeyEvent中):

代码语言:javascript
复制
KEYCODE_DPAD_UP :导航键上键
KEYCODE_DPAD_DOWN:导航键下键
KEYCODE_DPAD_LEFT:导航键左键
KEYCODE_DPAD_RIGHT:导航键右键
KEYCODE_DPAD_CENTER:导航键确认键
KEYCODE_VOLUME_UP:音量增大键
KEYCODE_VOLUME_DOWN:音量减小键

这里着重讲一下Home键,一般我们电视的遥控器上都有一个主页键(Home键)。其实对于Home键的监听,我们是无法在应用层捕获的,已经被framework层处理了:

代码语言:javascript
复制
    // 源码
    /** Key code constant: Home key.
     * This key is handled by the framework and is never delivered to applications. */
    public static final int KEYCODE_HOME            = 3;

那么,如果我们需要监听用户按了遥控器的主页键该怎么办呢?

幸好,系统为我们提供了一个很有用的广播:

代码语言:javascript
复制
    /**
     * Broadcast Action: This is broadcast when a user action should request a
     * temporary system dialog to dismiss.  Some examples of temporary system
     * dialogs are the notification window-shade and the recent tasks dialog.
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_CLOSE_SYSTEM_DIALOGS = "android.intent.action.CLOSE_SYSTEM_DIALOGS";

当用户按Home键的时候,系统会发送上面的广播(当然不仅仅是Home键),所以我们需要需要注册一个这样的广播,然后判断一下广播发生的原因是否为按Home键发出的,示例代码如下:

代码语言:javascript
复制
public class HomeReceiver extends BroadcastReceiver {
    private static final String CLOSE_SYSTEM_DIALOG_REASON_KEY = "reason";
    private static final String CLOSE_SYSTEM_DISLOG_BY_HOME_KEY = "homekey";

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
            String reason = intent.getStringExtra(CLOSE_SYSTEM_DIALOG_REASON_KEY);
            // 是因为Home键发出的广播
            if (CLOSE_SYSTEM_DISLOG_BY_HOME_KEY.equals(reason)) {
                //监听到Home键直接退出整个应用
                MyApplication.getInstance().exit();
            }
        }
    }
}

5

适配更多的分辨率

到这里,完整的开发TV应用的流程基本上没问题了。但是,要想开发出通用性更高的代码。不得不考虑到TV和机顶盒的分辨率众多。如果不做适配或者布局处理不太合理。很有可能当你在开发设备上显示的很完美,换一台设备后,UI大不相同,混乱不堪。所以,我们需要注意以下几点:

  • 布局尽量使用百分比的方式布局(ConstraintLayout非常合适)
  • 涉及到具体大小的地方可以多建一些典型分辨率的资源目录(values-w960dp、values-w1280dp等等),在各自的dimens.xml分别使用不同的值
  • 我们是针对机顶盒的分辨率做适配,而不是显示器的分辨率

End

总结

TV的开发与手机开发如出一辙,大同小异。UI开发上尽量使用LeanBack提供的组件,基本满足TV端的交互要求。这里给大家提供了一部分比较有用的网站: Android TV 开源社区:https://gitee.com/kumei LeanBack使用Demo:https://github.com/googlesamples/androidtv-Leanback Leanback 库使用简介:https://www.jianshu.com/p/d575e0c7bd59

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT烂笔头 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 连接开发设备
  • 新建TV项目
  • 编码
  • 适配更多的分辨率
  • 总结
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档