android tv 信源不一致问题
项目中 由于用户投诉, 新增了一个需求, 用户在看tv的时候, 关机重启后 仍然希望是进入tv界面下,而我们现在是不管上次关机是在tv还是launcher下, 重启以后都是进入launcher下。 想想这个需求是很正常的, 用户买回电视主要还是看tv的, 每次重启后都是进入launcher, 每次都需要手动切换到tv下, 用户不投诉才怪。
解决办法也比较简单,
一,
在系统属性中增加了一个属性, persist.sys.bootfromui, 进入launcher的时候 将persist.sys.bootfromui 设为true, 进入tv的时候将persist.sys.bootfromui设为false。 在ActivitStack.java 增加的代码如下:
final boolean resumeTopActivityLocked(ActivityRecord prev) {
1288 // Find the first activity that is not finishing.
1289 ActivityRecord next = topRunningActivityLocked(null);
1290
1291 // Remember how we'll process this pause/resume situation, and ensure
1292 // that the state is reset however we wind up proceeding.
1293 final boolean userLeaving = mUserLeaving;
1294 mUserLeaving = false;
1295
1296 if (next == null) {
1297 // There are no more activities! Let's just start up the
1298 // Launcher...
1299 if (mMainStack) {
1300 return mService.startHomeActivityLocked();
1301 }
1302 }
1303
1304 Slog.d(TAG,"resumeTopActivty");
1305 Slog.d(TAG, "------------liuwei-----------resumeTopActivty");
1306 if(next.packageName.equals("com.tcl.tv") || next.packageName.equals("com.tcl.common.bootsetwizard")){
1307 Slog.d(TAG, "set persist.sys.bootformui false ");
1308 SystemProperties.set("persist.sys.bootfromui","false");
1309 }else{
1310 Slog.d(TAG, "set persist.sys.bootformui true ");
1311 SystemProperties.set("persist.sys.bootfromui","true");
1312 }二,每次在开机启动的时候根据 这个属性来判断是进入launcher 还是 TV, 在ActivityManagerService.java改动的代码如下Slog.d(TAG, "----------liuwei------------startHomeActivityLocked");boolean isStartUi = "true".equals(SystemProperties.get("persist.sys.bootfromui","false"));if(isStartUi)</span>{Slog.d(TAG, "----------zhuxiaolin------------isStartUi is true");Intent intent = new Intent(mTopAction,mTopData != null ? Uri.parse(mTopData) : null);intent.setComponent(mTopComponent);if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {intent.addCategory(Intent.CATEGORY_HOME);}ActivityInfo aInfo =intent.resolveActivityInfo(mContext.getPackageManager(),STOCK_PM_FLAGS);if (aInfo != null) {intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));// Don't do this if the home app is currently being// instrumented.ProcessRecord app = getProcessRecordLocked(aInfo.processName,aInfo.applicationInfo.uid);if (app == null || app.instrumentationClass == null) {intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,null, null, 0, 0, 0, false, false, null);}}}else{Slog.d(TAG, "----------liuwei------------isStartUi is false");Intent mIntent = new Intent();//mIntent.setClassName("com.tcl.cyberui","com.tcl.cyberui.MainActivity");mIntent.setClassName("com.tcl.tv","com.tcl.tv.TVActivity");mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);Slog.d(TAG, "----------zhuxiaolin------------ mContext.startActivity(mIntent)");mContext.startActivity(mIntent);}三 引起的信源不一致问题
开机记忆TV的问题解决了。但是后来测试却发现一个更严重的问题, 有时候开机前TV的信源是DTV, 开机后的信源却是ATV或其他。经过多次测试总结出了规律, 如果第一次关机前是在launcher 状态下, 第二次关机前是tv状态下,就会出现信源就会出现不一致的情况。也就是说只要连续两次关机前的状态不一致(一次是launcher, 一次是TV)就必定会出现这个问题。如果两次关机前都是在luancher下 或都是在TV下那么就不会出现信源不一致的问题。
有了这个规律,那么就大胆猜测是由于luancher启动的时候读取信源的位置和 tv启动读取信源的位置不一致。
关键就在与这个位置不知道保存在哪里, 因为底层代码是厂商的我们看不到,很可能是保存在某个数据库里的。
后来不停的测试,加打印log, 发现不管是launcher先启动,还是TV先启动, 都会调用TVCommonNative.getDefault的getService来获取TVCommonService,
static public ITVCommon getDefault(Context context) {155 if (mContext == null && context !=null) {156 mContext = context.getApplicationContext();157 }158 159 if (gDefault != null) {160 return gDefault;161 }162 IBinder b = getService(TVCOMMON); 163 if (b == null) {164 b = new TVCommonService();165 TVLog(TVCOMMON166 + "service is not exit in ServiceManager, try to add it to ServiceManager");167 addService(TVCOMMON, b);</span>168 }
看到没, 第一次肯定都是走的红色代码,因为第一次都是空,先创建TVCommonService,在addService到ServiceManager。
再看看TVCommonService的构造函数:
88 TVCommonService() {89 90 super();91 tvMgr = TVManager.getInstance(getContext());92 rawChSrv = (ChannelService) tvMgr93 .getService(ChannelService.ChannelServiceName);94 cfgSrv = (ConfigService)tvMgr95 .getService(ConfigService.ConfigServiceName);96 inputSrv = (InputService) tvMgr97 .getService(InputService.InputServiceName);98 brdcstSrv = (BroadcastService) tvMgr99 .getService(BroadcastService.BrdcstServiceName);100 101 mLooper = Looper.getMainLooper();102 mQueue = Looper.myQueue();103 104 mQueue.addIdleHandler(this);105 handler = new Handler(mLooper, this);106 <span style="color:#CC0000;"> storage = TVStorage.getInstance(getContext());</span>107 configurer = TVConfigurer.getInstance(getContext());
看到了,有个存储的东东叫TVStorage, 而且这个TVStorage是和context相关的!!!!!
也就是说, tv先启动的时候,这个TvStorage的context是tv 的, launcher先启动的时候context是launcher, 则也就导致了tv先启动和 luancher先启动 读取,存放信源的地方是不一致的。
我们来看看TVStorage的代码:
private TVStorage(Context context) {
pref = context.getSharedPreferences(TVCM_TABLE, Context.MODE_PRIVATE);
pref = tvContext.getSharedPreferences(TVCM_TABLE, Context.MODE_WORLD_WRITEABLE);
editor = pref.edit();
}
36
37 public String getString(String key, String def) {
38 return pref.getString(key, def);
39 }
40
41 public void setString(String key, String val) {
42 editor.putString(key, val);
43 editor.commit();
44
45 }
看到了吗,是放到context 的preference下, 熟悉java上层应用的人都熟悉吧。
我就是不知道preference这个东西,所以卡到context那里 不知道往下怎么跟踪了。 追到这个地方是另外一个同事发现的。
四 。 知道了原因 代码修改如下
private TVStorage(Context context) {
15 //改为指定用TV的context读写属性,所以要求第一个调用TV控制接口的应用有systemuid
16 Context tvContext;
17 try {
18 tvContext = context.createPackageContext("com.tcl.tv", Context.CONTEXT_IGNORE_SECURITY);
19 } catch (NameNotFoundException e) {
20 // TODO Auto-generated catch block
21 e.printStackTrace();
22 tvContext = context;
23 }
24 pref = tvContext.getSharedPreferences(TVCM_TABLE, Context.MODE_WORLD_WRITEABLE);
25 editor = pref.edit();
26 }
把context写死到tv context下了,即不管是tv先启动,还是launcher先启动, storage都是读取,存储到tv的preference下了。
五 。其实我对这个该法是有意见的,在TVCommonService里我们可以看到, 不仅仅是TVstorage要用到context, 其他还有地方用到context, 我们只修改了storage的context, 那么其他地方的没有改,有很大的可能会出现问题。如果都修改, 那么对代码的改动太大了, 很可能造成更多的问题。 出现这个问题的本质 是因为TVCommonService是和context相关的, 只要每次开机add service的context不固定, 就会出先问题。 我比较推荐的方法 还是 永远都是launcher先启动,永远都用launcher的context去add TVCommonService, 启动luancher后,由launcher去判断 persist.sys.bootfromui, 由launcher去决定起TV或是不起。 毕竟以前一直都是先起launcher的,而这样也最稳定, 改动也很小。 可惜launcher不是我负责的, 做luancher的不想这么改,暂时修改Storage ,写死用tv的context。在我看来,这种写法实在不好, 除了刚才我提到的原因,底层的东西怎么能写死上层的package name呢?
android tv 信源不一致问题相关推荐
- android tv 不显示不出来,android tv 信源不一致问题
项目中 由于用户投诉, 新增了一个需求, 用户在看tv的时候, 关机重启后 仍然希望是进入tv界面下,而我们现在是不管上次关机是在tv还是launcher下, 重启以后都是进入launcher下. 想 ...
- Android TV开发--HDMI播放器
最近接到一个需求:做一个HDMI播放器的Demo,具体就是做一个Demo,安装在Android TV上,安卓TV接入安卓盒子,信号源是HDMI,打开播放器的Demo可以播放盒子里面的资源.网上这方面的 ...
- Android TV框架 TIF(Android TV Input Framework)入门实践
Tamic/CSDN http://blog.csdn.net/sk719887916/article/details/53645615 做TV开发一段时间了,国内目前关于这方面的资料并不多,这里我来 ...
- Android TV开发总结(三)构建一个TV app的焦点控制及遇到的坑
原文:Android TV开发总结(三)构建一个TV app的焦点控制及遇到的坑 版权声明:我已委托"维权骑士"(rightknights.com)为我的文章进行维权行动.转载务必 ...
- 针对Android Tv的自定义RecyclerView2 0横竖向连动
版权声明:本文为博主原创文章,转载请注明出处. 推荐: 欢迎关注我创建的Android TV 简书专题,会定期给大家分享一些AndroidTv相关的内容: www.jianshu.com/c/37ef ...
- 【Android TV 开发】焦点处理 ( 父容器与子组件焦点获取关系处理 | 不同电视设备上的兼容问题 | 触摸获取焦点 | 按键获取焦点 )
Android TV 开发系列文章目录 [Android TV 开发]安卓电视调试 ( 开启网络远程调试 ) [Android TV 开发]焦点处理 ( 父容器与子组件焦点获取关系处理 | 不同电视设 ...
- 如何在Android TV上自定义推荐行
When you fire up Android TV, the first thing you see is a list of movies and shows the system thinks ...
- android 设备名称_如何更改您的Android TV的设备名称
android 设备名称 Android TV is Google's attempt at taking over the living room, and with some units bein ...
- Android插u盘自动执行,android tv box ---- 插入u盘直接播放指定文件夹中的视频
android tv box ---- 插入u盘直接播放指定文件夹中的视频思路: 1.监听u盘插入广播 2.遍历指定目录下的所有文件,找到视频文件 3.将符合条件的文件加入播放集合中 4.循环播放 n ...
最新文章
- 请问:这里的空应怎么填呀?
- python binary lib on win/各种python库的二进制包
- java一个接口执行结束释放内存_java的灵魂--JVM虚拟机
- 听说你想去大厂看学妹,带你看看作业帮产品经理岗面经
- windbg调试cpu占用率高的进程
- VMware License Server使用经验
- python 验证码_4行Python代码生成图像验证码
- java 压缩gz_如何在Java中将.zip压缩为.gz?
- 我真out了,高端人士都这样玩儿?
- css3毛玻璃效果白边问题
- MapReduce之WordCount案例
- 你遇到过最有诗意的句子是什么?
- 第三部分:Android 应用程序接口指南---第一节:应用程序组件---第一章1-1.Fragment...
- DiskGenius屏蔽硬盘坏道方法
- 基于ROS使用Arduino控制水泵
- JS·经典·炫彩菜单(动画效果) for jquery
- win7系统,打开office出现错误代码0x8007007B的解决办法
- ES 7.0.1安装head和sql插件报错处理
- CS231n 02 Loss Functions and Optimization
- memcpy内存重叠问题
热门文章
- Matlab/simulink仿真,直驱永磁风机并网低电压穿越 直驱风力发电系统MATLAB仿真模型
- 惯导偏航角误差和GPS动态精度对导航的影响
- php dropdownlist,php 下拉列表多级联动dropDownList示例代码
- java 抖音开放平台 code token等
- c++ 计算某个日期是星期几,判断某年某月一号是星期几
- 【FPGA】数码管动态显示之电子时钟
- superset 最新版 地图数据展示问题
- 奥特曼系列ol光元在哪个服务器,奥特曼系列OL无限光元版
- 使用Arduino开发板和颜色传感器TCS230实现颜色感应
- RTSP/Onvif协议EasyNVR视频平台Linux版本云端录像下载异常的修复