隐藏

如何从零开始学习Android TV应用

发布:2021/10/11 10:33:17作者:管理员 来源:本站 浏览次数:987

背景


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


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

① 连接开发设备


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


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


adb connect 192.168.2.17


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

② 新建TV项目


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

③ 编码


代码写起来,和移动应用开发没什么不同。但是由于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做背景。


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

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        return super.onKeyDown(keyCode, event);
    }


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

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层处理了:

    // 源码
    /** 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;


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


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

    /**
     * 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键发出的,示例代码如下:

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();
            }
        }
    }
}

④ 适配更多的分辨率


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


   布局尽量使用百分比的方式布局(ConstraintLayout非常合适)

   涉及到具体大小的地方可以多建一些典型分辨率的资源目录(values-w960dp、values-w1280dp等等),在各自的dimens.xml分别使用不同的值

   我们是针对机顶盒的分辨率做适配,而不是显示器的分辨率


总结


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