Android TIF(Android TV input Framework)是Google向电视制造商提供了一套标准的API,用于创建Input模块来控制Android电视。这套API的底层实现的原理是aidl和provider,从而进行了跨进程通信。系统或第三方的应用可以通过TIF获得所有输入(input)的信源(输入的模块包括:搜台模块,MDMI模块,网络模块等),然后通过AIDL切台输出到屏幕上。

Android TV框架TIF

  • 电视相关知识
  • TIF的组成部分
  • TIF的整理使用流程
  • 启动流程
  • 接口介绍
    • ``TvView``
    • ``TvInputService``
    • ``TvInputService.Sssion``
    • ``TvContract``
    • ``TvInputManager``
    • ``TvInputInfo``
    • ``TvInputCallback``
  • 使用注意事项
    • 通过uri解析id
    • 状态的回传
      • loading状态的回传
      • buffer状态的回传
      • 自定义的状态
    • Program表清空问题修复

电视相关知识

在介绍这套框架之前,先复习一下电视相关的专业术语

  • HDMI:高清晰度多媒体接口(英文:High Definition Multimedia Interface,HDMI)是一种数字化视频/音频接口技术,是适合影像传输的专用型数字化接口

  • IPTV:网络电视,也叫VOD电视,三方比如说某某视频公司提供的视频资源在电视上播放

  • DTV:数字电视

  • ATV:模拟电视

TIF的组成部分

  • TV Provider (com.android.providers.tv.TvProvider):一个包含频道、节目和相关权限的数据库

  • TV App (com.android.tv.TvActivity):一个和用户交互的系统应用

  • TV Input Manager (android.media.tv.TvInputManager):一个中间接口层,能够让TV Inputs和TV App进行通讯

  • TV Input:可以看做是一个代表物理或者虚拟的电视接收器或者输入端口的应用。Input在TIF中可以看做是一个输入源

  • TV Input HAL (tv_input module):TV Input的硬件抽象层,可以让系统的TV inputs访问TV特有硬件

  • Parental Control:儿童锁,一种可以锁住某些频道和节目的技术

  • HDMI-CEC:一种可以通过HDMI在多种设备上进行远程控制的技术

  • CEC(Consumer Electronics Control):消费电子控制

TIF的整理使用流程


如上图所示,LiveTV App通过turning调用TV Input Manager获得一个session,session里面放的是一路信源的状态。TvInput将获得的Channel和Programs信息写入到/data/data/com.android.providers.tv/databases/tv.db数据库中。LiveTV App通过session以aidl的方式调用TVinputService获得相关的频道和具体的节目信息进行播放。

启动流程

SystemServer -> TvInputManagerService <-> TvInputHardwareManager <-> TvInputHal->JNI <-> HAL

接口介绍

TvView

负责显示播放的内容。它是一个ViewGroup的子类,它是切台的入口,内置surface用于显示视频播放的内容和通过控制session可以控制音量的大小等

TvInputService

这是一个重要的类,继承它并实现一些规范就可以实现一路Input信源供其它应用使用。

在该Service中要实现onCreatSession()方法,该方法会返回一个TvInputService.Session对象。

这里的Service在Manifest中定义时要注意要添加permission和action,添加完之后,系统的TvInputManager可以检测到该Service是一个TvInputService,也就是一路信源。

<uses-permission android:name=“android.permission.TV_INPUT_HARDWARE” />

TvInputService.Sssion

该session类TvView通过Tune方法会指定相应的inputId(往往是该service对应的“包名/.类名”)和uri,uri中包含对应的节目id,该tune方法会调用Session的Onturn方法中,在这个方法中解析传过来的id,根据id利用TvProvider去查询数据库的数据,设置给player,这里使用onSetSurface()方法将TvView创建的surface设置给player,然后player就在该surface上显示内容。

TvContract

介于TvProvider和TvApp之间的一层封装,它里面封装了一些uri。有两个内部类是两个JavaBean,他们分别是TvContract.channels(频道表),TvContract.Programs(频道里面的节目单)。

TvInputManager

这个是TIF的核心类,它是系统的类,可以监测到在系统的Service中注册android.media.tv.action.QUERY_CONTENT_RATING_SYSTEMSaction的类,并将其设为一路信源。它来管理一些回调,比如video是否可用,video的大小尺寸是否变换。

通过下面的代码可以获得一个TvInputManager:

TvInputManager tvInputManager =(TvInputManager) getSystemService(Context.TV_INPUT_SERVICE);

得到TvInputManager后我们可以遍历拿到系统当前有多少个service是TV信源:

List<TvInputInfo> list = tvInputManager.getTvInputList();for(TvInputInfo info:list){Log.i(TAG, "id:" + info.getId());
}

我们可以拿到inputId,在TvView的tune方法中设置。这里的信源就是注册了服务并没有开启,在TvView的tune方法调用的时候会开启服务。

TvInputInfo

TvInput的信息,包括频道类型,图标,名称等。

TvInputCallback

这里是TvView的一个内部类,TvInputCallBack可以反馈给TvView一些信息比如连接Service是否成功,Video是否可用等:

tvView.setCallback(new TvView.TvInputCallback() {@Overridepublic void onConnectionFailed(String inputId) {super.onConnectionFailed(inputId);
LogUtil.i(this,"MainActivity.onConnectionFailed:"+inputId);
}
@Override
public void onDisconnected(String inputId) {super.onDisconnected(inputId);
LogUtil.i(this,"MainActivity.onDisconnected.");
}
@Override
public void onVideoSizeChanged(String inputId, int width, int height) {super.onVideoSizeChanged(inputId, width, height);
LogUtil.i(this,"MainActivity.onVideoSizeChanged.");
}
@Override
public void onVideoAvailable(String inputId) {super.onVideoAvailable(inputId);
LogUtil.i(this,"MainActivity.onVideoAvailable.inputId:"+inputId);
}
@Override
public void onVideoUnavailable(String inputId, int reason) {super.onVideoUnavailable(inputId, reason);
LogUtil.i(this,"MainActivity.onVideoUnavailable.");
}
......
});

使用注意事项

通过uri解析id

Long channelId = ContentUris.parseId(channelUri);

状态的回传

在TvView中我们如果想要获取一些播放器的状态,比如buffer状态,在开始播放之前有一个loading的状态,获取节目的size的变换,以及自定义的一些状态。下面依次说明:

loading状态的回传

在tune方法的时候使用mSimpleSession.notifyVideoUnavailable(TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING); 通知Video不可用,原因是tuning其他对应的状态还有:

TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN:未知原因
TvInputManager.VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL:信号弱
TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING:缓冲
TvInputManager.VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY:仅仅是音频

在视频播放的时候即在onPrepared时调用mSimpleSession.notifyVideoAvailable()

buffer状态的回传

在MediaPlayer中Buffer的两种状态,开始缓冲和结束缓冲对应的是701和702两个状态。在MediaPlayer的onInfo方法中收到了701开始调用mSimpleSession.notifyVideoUnavailable(TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING);

自定义的状态

这个使用make的方式编代码的时候才能引用,因为这个方法用@system api注解了。
可以传一个bundle对象:notifySessionEvent(@NonNull final String eventType, final Bundle eventArgs)

Program表清空问题修复

在使用TvProvider提供的Program表的时候,我这里遇到了一个问题,发现表的数据会被不定期的清空,测试那边给的也是偶现的,通过断网,切台,重启系统发现programs表总是被清空。

对于开发来说找到bug的复现步骤是最好不过的事情了。通过阅读TvProvider的源码可以看到有一个类专门负责清空Programs的数据,在EpgDataCleanupService
中会去清除当前时间以前的节目信息,在这个字段对应的时间信息COLUMN_END_TIME_UTC_MILLIS,而这个时间是以毫秒为单位的,我们服务器给的数据是以秒为单位的,所以会被清空,修改一下就可以了:

 /*** Clear program info that ended before {@code maxEndTimeMillis}.*/@VisibleForTesting
void clearOldPrograms(long maxEndTimeMillis) {int deleteCount = getContentResolver().delete(Programs.CONTENT_URI,Programs.COLUMN_END_TIME_UTC_MILLIS + "<?",new String[] { String.valueOf(maxEndTimeMillis) });if (DEBUG && deleteCount > 0) {Log.d(TAG, "Deleted " + deleteCount + " programs"+ " (reason: ended before "+ DateUtils.getRelativeTimeSpanString(this, maxEndTimeMillis) + ")");}}

Android TV框架TIF相关推荐

  1. Android TV框架 TIF(Android TV Input Framework)入门实践

    Tamic/CSDN http://blog.csdn.net/sk719887916/article/details/53645615 做TV开发一段时间了,国内目前关于这方面的资料并不多,这里我来 ...

  2. Android TV TIF源码阅读笔记

                                   Android TV TIF源码阅读笔记 1.SystemSever.java if (mPackageManager.hasSystem ...

  3. leanback android,Android TV之谷歌android leanback框架详解

    google leanback 库简介 "Leanback" 就是靠着看的意思.是指以放松的姿势倒在沙发上.谷歌推出 android.support.v17.leanback 软件 ...

  4. Android TV 上使用的RecyclerView和焦点框架,焦点框移动效果,完胜androidTvwidget的MainUpView

    android tv开发最完美的框架,支持列表加载更多,移动框效果设置,废话不多说上图 资源链接:http://download.csdn.net/download/u014764233/983929 ...

  5. FocusControl,专为Android TV应用提供的焦点控制框架

    FocusControl 焦点控制框架,用于Android TV应用的焦点控制. 在模块gradle目录下的dependencies闭包中添加如下代码即可集成焦点控制框架: implementatio ...

  6. Android TV之谷歌android leanback框架详解

    google leanback 库简介 "Leanback" 就是靠着看的意思.是指以放松的姿势倒在沙发上.谷歌推出 android.support.v17.leanback 软件 ...

  7. Android TV Input Framework(Android TV 一)

    前言 Android TV是Android 5.0新的内容,当前国内的智能电视大部分都是基于Android系统的,Android TV作为事实上的标准,它的推出必将极大的影响下一代智能电视的开发. 近 ...

  8. Android TV开发总结(三)构建一个TV app的焦点控制及遇到的坑

    原文:Android TV开发总结(三)构建一个TV app的焦点控制及遇到的坑 版权声明:我已委托"维权骑士"(rightknights.com)为我的文章进行维权行动.转载务必 ...

  9. android tv ko,Android TV 键值修改流程

    有的时候,我们需要增加一些新的按键,那么需要修改哪些地方呢? 1.Java层的修改:KeyEvent.java 修改了keyevent.java需要编译出android.policy.jar这个需要拷 ...

  10. android tv nugat,GitHub - GongXunYoung/Android-tv-widget: Android tv,盒子,投影仪 控件

    Android TV 开发框架 QQ群:522186932 Leanback 框架(类似谷歌的Leanback,更简直,更方便): 键盘框架: 菜单框架: 整体目录结构 *AndroidTvWidet ...

最新文章

  1. Swift中页面跳转与传值:
  2. Chapter 4.SQL编程
  3. scenebuilder各控件属性介绍_Flutter 全栈式——基础控件
  4. 只需五步学会Maven 3.6.1OR 3.6.3及其他版本的下载安装与配置【图文详解】
  5. mysql中的联结_MySQL的联结(Join)语法
  6. 在Linux下使用Vim编写C++
  7. Posted content length of 26789546 exceeds limit of 10485760
  8. 计算机专业基础 -- C++相关与MFC基础知识
  9. [导入]Manning.Ajax.in.Action.Oct.2005.pdf(9.26 MB)
  10. win98 支持html5,90后第一次接触Windows98,20多年了,居然还有人使用!
  11. 卸载vuecli3_针对遇到安装或卸载vue-cli失败的解决方案
  12. 【角度刁钻】如果把线程当作一个人来对待,秒懂
  13. 8086汇编段地址和偏移地址分配原则,深入理解.
  14. matlab迭代法求超越方程,matlab fsolve函数求解超越方程
  15. 中国电信翼支付网关接口接入
  16. 苹果于 2021 年 4 月 21 日凌晨发布了搭载 M1 芯片的 iPad Pro
  17. 【CSDN AI周刊】第14期 | 吴恩达离职百度 CNN之父清华演讲
  18. SSH服务端配置、优化加速、安全防护
  19. 网络安全中,计算机病毒检测方法有哪些?
  20. 张宇基础30讲 第14讲

热门文章

  1. c++ windows下读取大文件(内存映射)
  2. a 和an 的用法区别
  3. el 能否定义作用域变量_EL表达式语法简介及其使用
  4. 【转】【深度学习MobileNet】——深刻解读MobileNet网络结构
  5. 以.a(a为后缀)的文件类型是啥鸭?
  6. Qt QLabel 文字滚动 滚动字幕
  7. Microsoft SQL Server Protocols
  8. Linux kernel SMP 中断机制
  9. mac 更换默认蓝牙适配器_解决Switch最大遗憾,谷粒ROUTE Air蓝牙适配器:简单好用...
  10. mysql数据库错误调试_云函数写MySQL数据库,显示调用失败,但调试写库成功,问题大吗?...