文章目录

  • 1 TV项目开发步骤
    • 1.1 普通apk开发流程
    • 1.2 系统apk开发流程
  • 2 焦点处理
    • 2.1 TV开发中常见的遥控器事件KeyEvent
    • 2.2 使用adb命令模拟遥控器按键调试TV模拟器
    • 2.3 焦点拦截事件分发
      • 2.3.1 事件传递说明
      • 2.3.2 常见的焦点处理方式
      • 2.3.3 View的焦点处理
      • 2.3.4 遥控器长按事件监听
      • 2.3.5 焦点丢失问题
  • 3 adb参考
    • 3.1 adb命令大全
    • 3.2 apk正式签名步骤
    • 3.3 使用adb命令将apk写入机顶盒相关命令

1 TV项目开发步骤

1.1 普通apk开发流程

  • 连接机顶盒
// 10.118.4.144为机顶盒的ip,默认为5555端口
// 机顶盒ip一般在电视中的Network Setting中查看
// 使用adb需要连接网线通过网口连接
>>adb connect 10.118.3.56.5555
  • 将apk写入机顶盒
// 使用adb install将写入data/data目录
>>adb install D:\android\test.apk// 强制覆盖安装apk,两种安装apk方式都是写入data/data目录,不适用于系统apk
>>adb install -r D:\android\test.apk // 当连接多台机顶盒时,将apk写入指定ip的机顶盒
>>adb -s 10.118.3.56:5555 install D:\android\test.apk
  • 卸载apk
// 通过指定包名卸载apk
>>adb uninstall com.example.test
  • 查看打印日志
// 查看输出为TAG关键字的log,这里的TAG相当于Log.i(TAG, "xxx")中的TAG
>>logcat -s TAG// 查看输出为TAG关键字的log,附带上时间
>>logcat -v time -s TAG// 查看输出为TAG关键字的log,这里的TAG可以为任意值
>>logcat | grep TAG

1.2 系统apk开发流程

/system分区默认挂载为只读,但有些操作比如给Android系统添加命令、删除自带应用等需要对/system进行写操作,所以需要重新挂载它为可读写。

写入的apk需要使用系统签名文件进行签名。

  • 申请root权限
>>adb root
>>su
  • 进入shell
>>adb shell
  • 关闭内核打印
echo 0 > /proc/sys/kernel/printk
  • 重新挂载
// mount命令是进入shell才可以使用
// 重新挂载vendor目录为可读写
>>mount -o rw,remount /vendor;
// 重新挂载system目录为可读写
>>mount -o rw,remount /system;// 如果上面的方式不能成功挂载,退出shell,通过adb remount挂载
>>exit
>>adb remount// 挂载对应的设备
>>adb -s 10.118.3.41:5555 remount
  • 将apk push到系统目录下
// adb push可以替换原来的apk或者写入新的apk
>>adb push D:\android\demo\test.apk /system/app/test.apk
  • 重启让apk生效
>>adb shell reboot>>adb -s 10.118.3.41:5555 shell reboot
  • 测试应用
// 启动包名com.example.test下的MainActivity
>>adb shell am start -n com.example.test/.MainActivity// 主动发送广播
>>adb shell am broadcast -a android.intent.action.xxxx

2 焦点处理

2.1 TV开发中常见的遥控器事件KeyEvent

KeyEvent.KEYCODE_DPAD_UP:遥控器上键
KeyEvent.KEYCODE_DPAD_DOWN:遥控器下键
keyEvent.KEYCODE_DPAD_LEFT:遥控器左键
keyEvent.KEYCODE_DPAD_RIGHT:遥控器右键
keyEvent.KEYCODE_DPAD_CENTER:遥控器ok确认键
keyEvent.KEYCODE_DPAD_x:x表示数字0-9,遥控器数字键
KeyEvent.KEYCODE_BACK:遥控器返回键
KeyEvent.KEYCODE_HOME:遥控器主页键
KeyEvent.KEYCODE_x:x表示字母A-Z,遥控器字母键
KeyEvent.KEYCODE_MENU:遥控器菜单键

2.2 使用adb命令模拟遥控器按键调试TV模拟器

https://blog.csdn.net/u013347784/article/details/78329221

adb shellinput keyevent 1  // 遥控器menu键
input keyevent 3  // 遥控器Home键
input keyevent 4  // 遥控器Back键
input keyevent 19 // 遥控器上键
input keyevent 20 // 遥控器下键
input keyevent 21 // 遥控器左键
input keyevent 22 // 遥控器右键
input keyevent 23 // 遥控器ok确认键

2.3 焦点拦截事件分发

https://blog.csdn.net/jun5753/article/details/78684049

TV端是通过遥控器按键控制焦点事件,与手机端有所不同,所以在事件拦截处理上也不同。

手机端拦截事件分发:

  • dispatchTouchEvent()

  • onInterceptTouchEvent()

  • onTouchEvent()

TV端拦截事件分发:

  • dispatchKeyEvent()

  • onKeyDown()/onKeyUp()

  • onKeyListener()

2.3.1 事件传递说明

(PhoneWindow)$DecorView.dispatchKeyEvent()->Activity.dispatchKeyEvent()->View.dispatchKeyEvent()->// setonKeyListener != null则回调监听器
View.setOnKeyListener.onKey()->// setOnKeyListener == null或onKey()返回false则回调onKeyDown()/onKeyUp()
View.onKeyDown()/onKeyUp()->// setOnClickListener != null && 遥控器ok按键的ACTION_UP则回调监听器
View.setOnClickListener.onClick()->// View.setOnClickListener == null则返回到Activity回调onKeyDown()/onKeyUp()
Activity.OnKeyDown()/OnKeyUp()

KeyEvent的事件处理只有两个地方,一个是Activity,一个是具体的View,ViewGroup只负责分发事件给子View不消耗事件。其实Activity和具体View的事件处理都是交由DecorView处理。

2.3.2 常见的焦点处理方式

  • 在Activity重写dispatchKeyEvent()
// 遥控器按下和松开会分别调用两次dispatchKeyEvent(),dispatchKeyEvent->onKeyDown->dispatchKeyEvent->onKeyUp
// 返回true或false都会拦截事件,即子View将不会接收到分发事件,Activity的onKeyDown()/onKeyUp()也不会接收到
// return true:拦截事件,不让焦点再移动
// return false:拦截事件,焦点会移动
// return super.dispatchKeyEvent:往下分发事件不拦截
@Override
public boolean dispatchKeyEvent(KeyEvent event) {int keyCode = event.getKeyCode();int action = event.getAction();switch(keyCode) {case KeyEvent.KEYCODE_DPAD_DOWN:if (action == KeyEvent.ACTION_DOWN) {Log.i(TAG, "dispatchKeyEvent-ACTION_DOWN");} else if (action == KeyEvent.ACTION_UP) {Log.i(TAG, "dispatchKeyEvent-ACTION_UP");}return true;case KeyEvent.KEYCODE_DPAD_UP:if (action == KeyEvent.ACTION_DOWN) {Log.i(TAG, "dispatchKeyEvent-ACTION_DOWN");} else if (action == KeyEvent.ACTION_UP) {Log.i(TAG, "dispatchKeyEvent-ACTION_UP");}return false;}return super.dispatchKeyEvent(event);
}
  • 在Activity重写onKeyDown()/onKeyUp()

事件走到这两个回调表示子View没有消耗事件抛回给上层,在这里做最后的事件处理。

  • 具体View实现setOnKeyListener()

一般实现onKeyListener对具体的遥控器事件做特殊处理

  • 具体View实现OnClickListener()

一般实现onClickListener都是响应遥控器的ok确认键

2.3.3 View的焦点处理

  • requestFocus():强制获取焦点

  • android:focusable:设置一个控件是否能获取焦点

  • android:nextFocusUp/view.setNextFocusUpId(id):设置遥控器按上键时哪个view会获取到焦点,提供一个id

  • android:nextFocusDown/view.setNextFocusDownId(id):设置遥控器按下键时哪个view会获取到焦点,提供一个id

  • android:nextFocusLeft/view.setNextFocusLeftId(id):设置遥控器按左键时哪个view会获取到焦点,提供一个id

  • android:nextFocusRight/view.setNextFocusRightId(id):设置遥控器按右键时哪个view会获取到焦点,提供一个id

  • view.setOnFocusChangeListener():监听view获取到焦点,一般在该方法处理view背景修改等

2.3.4 遥控器长按事件监听

private boolean isLongPress;@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {isLongPress = true;return true;}return super.onKeyLongPress(keyCode, event);
}// dispatchKeyEvent统一处理长按时按下和松开时的处理
// 或者分别在onKeyDown监听长按按下,onKeyUp监听长按松开
@Override
public boolean dispatchKeyEvent(KeyEvent event) {int keyCode = event.getKeyCode();int action = event.getAction();switch(keyCode) {case KeyEvent.KEYCODE_DPAD_DOWN:if (action == KeyEvent.ACTION_DOWN) {// 按下时会执行一次,进行event长按跟踪,不断回调dispatchKeyEvent,第二次开始会走elseif (event.getRepeatCount() == 0) {event.startTracking();isLongPress = false;} else {isLongPress = true;// 遥控器向下长按按下处理.....}} else if (action == KeyEvent.ACTION_UP) {if (isLongPress) {isLongPress = false;// 遥控器向下长按松开处理....}}return true;}return super.dispatckKeyEvent(event);
}或者@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {if (event.getAction() == KeyEvent.ACTION_DOWN) {// 按下时会执行一次,进行event长按跟踪if (event.getRepeatCount() == 0) {isLongPress = false;event.startTracking();}return true;}}return super.onKeyDown(keyCode, event);
}@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {if (isLongPress) {isLongPress = false;// 遥控器向下长按松开处理....}return true;}return super.onKeyUp(keyCode, event);
}

2.3.5 焦点丢失问题

android:descendantFocusability="afterDescendants" 在组合控件(即自定义ViewGroup inflate有多个控件的xml布局)焦点处理中,在使用ListView、GridView、RecyclerView时有时会出现焦点丢失问题,需要添加该属性

// ViewGroup会优先其子类控件而获取焦点
android:descendantsFocusability="beforeDescendants"// ViewGroup只有当其子类控件不需要获取焦点时才获取焦点
android:descendantsFocusability="afterDescendants"// ViewGroup会覆盖子类控件而直接获得焦点
android:descandantsFocusability="blockDescendants"

3 adb参考

3.1 adb命令大全

https://github.com/mzlogin/awesome-adb

3.2 apk正式签名步骤

https://jingyan.baidu.com/article/59703552aeccbf8fc1074075.html

3.3 使用adb命令将apk写入机顶盒相关命令

https://www.jianshu.com/p/225fef8c6e67

Android 机顶盒TV app开发相关推荐

  1. Android兼容性系统app开发的一些探究

    Android兼容性系统app开发的一些探究 说明 起因 软件现状 需求 实现探究 第一点:软件兼容原则 第二点:软件实现方案 具体实现 说明 说明 本文是我根据自己开发期间项目需求探究的总结,里面有 ...

  2. android电视盒子设备名字,Android电视TV盒子开发——常用ADB命令-Go语言中文社区...

    目前智能电视(TV).盒子(机顶盒)基本都是Android系统,所以开发盒子app的重任自然就会落到我们这些苦逼Android程序员身上. PS:目前盒子的Android版本绝大部分还都是在6.0以下 ...

  3. Android电视TV盒子开发——常用ADB命令

    目前智能电视(TV).盒子(机顶盒)基本都是Android系统,所以开发盒子app的重任自然就会落到我们这些苦逼Android程序员身上. PS:目前盒子的Android版本绝大部分还都是在6.0以下 ...

  4. Android入门 简单app开发:为女友实现记录月经周期的app

    前言 寒假答应给女友做一个记录月经周期的app,由于我太vegetable,写的比较辣鸡,大家凑活着看(手动笑哭) 思路: 首先要跟大家说的是, android开发 要明白开发思想:逻辑和视图是分开的 ...

  5. Android短视频app开发中如何实现上下滑动切换效果

    在大部分短视频app开发中,都会在app内增加上下滑动切换视频的功能,即下滑切换到下一条短视频,上滑切回到上一条.这种机制可以给用户带来良好的视觉体验,云豹作为优秀的app源码供应商,在该效果的实现上 ...

  6. 基于Android的理财app开发,基于Android的个人理财系统的设计与实现.doc

    毕业论文(设计)题目: 基于Android的个人理财系统 ---设计与实现 学生姓名: 学 号: 专业班级: 计算机科学与技术092班 指导教师: 职称 副教授 指导教师: 职称 起止时间: 目 录 ...

  7. Android——“i 分享”APP开发Day06

    继续上一篇的内容,写FindFragment.java文件,在上一篇的三个函数基础上基本就可以展示出热门内容了,接下来主要就是处理找人和找文按钮的事件 因为之后还需要实现找人的功能,所以要先给创建一个 ...

  8. Android 外卖订餐APP开发

    APP展示页面:                           本产品适用范围:   购买便利店系统任何版本,如需进行二次开发,需要单独联系我们队APP进行修改和调试,免收服务费用.本司接收任何 ...

  9. android 平面图app_Android App 开发技术图谱

    引言: 今天偶然看到StuQ的技术图谱, 找了找竟然没有Android开发的. 想起之前自己弄了一个, 翻出来看看并不过时, 整理下发出, 大家共同进步. 图片比较大, 加载较慢, 请等待~~ And ...

最新文章

  1. 对不起,作为导师,我让您失望了!
  2. NO_CHANGE_ALLOWED error code
  3. Spring思维导图,让Spring不再难懂(ioc篇)
  4. 测试Java EE 8规范
  5. 外键为','(逗号)拼接ID,连接查询外键表ID
  6. 35岁,搞过超高并发架构,依然没看懂字节的推荐系统!
  7. hibernate连接mysql 释放连接_SSH 占用数据库连接不释放问题
  8. 中国传媒大学计算机学院夏令营,中国传媒大学夏令营
  9. 字体设计灵感合集|字体决定了设计
  10. c语言学习-判断一个年份是否闰年
  11. Qt实现多语言切换 - Qt语言家
  12. redis集群原理及搭建
  13. 哈工大车万翔团队:口语语言理解的最新进展与前沿
  14. 红米(RedmiBook)笔记本无线网卡QCA6174在Linux下wifi异常解决方法
  15. nlp对语料进行分类_如何使用nlp对推文进行分类
  16. 手机QQ与Win8:一蠢再蠢的改版与回炉
  17. vue使用XSLX,用CDN引入后下载的excel文件无法打开的解决办法
  18. 安装包UI美化之路-nsNiuniuSkin安装包模板介绍-新模板上线啦
  19. VUE强制渲染,强制更新
  20. 谷歌的无痕模式有什么好处_为什么Google的新搜索结果设计是黑暗的模式

热门文章

  1. 【EduCoder实训答案】大数据系统及应用-HDFS实训
  2. react总结之jsx是什么,jsx语法规则
  3. Linux查看服务器配置命令
  4. 中智集团携手亚信安全 打造立体化、智能化网络防御体系
  5. 2020.8 复习 7-11 分钟秒钟的时间相减 //PTA
  6. 中国计算机大赛游戏,我校在第10届全国大学生计算机设计大赛第暨4届中国大学生动漫游戏设计大赛,“星雨杯”福建省级赛的表现优异...
  7. 面试必备:四种经典限流算法讲解
  8. 作为一个新人,怎样学习嵌入式Linux ?(韦东山)
  9. 港联证券:为什么会出现股票跌停?股票跌停应该怎么卖出?
  10. JavaScript 中 的等号(==)/不等号(!=) 和全等号(===)/非全等号(!==)