1.需求
1.由于我们的产品是运行在机顶盒上使用的,并且是可以插入鼠标操作的。 由于鼠标指针太小,用户使用又是依靠投影设备当作屏幕使用,
所以这个时候机顶盒显示出来的鼠标旧显得比较小,而且还有其他一些系统因素,比如背景纯黑色,鼠标指针也是默认黑色的,这样就更不容易
看清屏幕上的鼠标指针在哪里了。
2.解决方案
1.不予解决,一开始我是拒绝的。鼠标指针是跟随系统的,也改变不了系统的资源啊。驳回诉求吧。
2.慢慢想办法解决
3.开始解决
3.0 写在前面
1.风险点:操作不当有可能一直卡在开机界面哦,我不负责哈
2.设备必须要root
3.1资料查找
经不住客户的压力,还是需要去慢慢尝试看能不能解决。然后也各种查找资料,终于有点眉目。
1.修改方式一:在出厂的时候修改,重新打包签名安装到系统里面。(pass)
2.修改方式二:1. SRO–Static resource overly(静态替换) RRO–Runtime resource overlay (运行时替换) ,
貌似也是源码级修改大家可以自行了解下(pass)
3.修改方式三:各种通过adbtools工具反编译,替换资源,然后重新签名打包。(pass)
经过了上面的资料查找,又了解到
1.知道了系统的资源文件都是存放在framework-res.apk中的,具体目录是 /system/framework/ 目录下。
2.可以参考别的app修改主题的方式,去替换鼠标资源文件。
3.鼠标资源文件名为:pointer_arrow.png
所有就大胆的尝试。
3.2 step1
导出framework-res.apk文件,然后通过压缩软件打开这个apk文件,找到pointer_arrow.png文件。
3.2 step2
然后我们准备一张鼠标的图片
然后我们替换一下图标
就这样,我们就替换好了图片,然后我们在放回原来的位置。可以通过Android studio 直接upload,也可以直接 通过adb命令
push 进去。这里我们假设push到的目录是sdcard的根目录,然后执行以下命令
adb push /mnt/sdcard/framework-res.apk /system/framework/ //把sdcard中的apk push到system/framework目录下覆盖原来的文件。
如果上面的命令不成功,则选择手动upload进去把,也可以通过其他方式比如,第三方的资源文件管理器拷贝过去。
3.2 step3
拷贝完成以后,重启设备,重启设备,重启设备
4.看效果
原始的图标样式
替换后的图标样式
ok,效果看到了吧,直接替换资源文件确实能够修改鼠标资源样式。也不需要重新签名打包,即可完成对鼠标资源样式的替换。
5 继续
既然现在知道了修改framework-res.apk里面的鼠标指针资源文件能够有效的替换,接下来我们开始第二步操作。
5.1 如何给客户替换?
因为目前机顶盒在我们开发手上,所以我们可以很方便的通过adb push 或者第三方的资源文件管理器很快的执行替换,拷贝操作。但是,客户手上的盒子怎么给他改造呢?这是个问题。
所以这个时候要求解了
1.已知机顶盒是拥有root权限
2.已知可以用代码执行adb命令。
3.已知机顶盒型号大都固定,只有一两款。
根据上面的已知参数,然后继续尝试。
5.2 准备工作
准备工作,逻辑梳理
1.需要提前准备好已经处理过的framework-res.apk文件。
2.需要判断是否有root权限。
3.执行替换的命令
5.3 开始替换
1.判断是否有权限(kotlin)
/***
* 检查su权限
*/
fun checkSuPermission(): Boolean {
val binaryName: String?="su"
var found = false
if (!found) {
val places = arrayOf(
"/sbin/",
"/system/bin/",
"/system/xbin/",
"/data/local/xbin/",
"/data/local/bin/",
"/system/sd/xbin/",
"/system/bin/failsafe/",
"/data/local/"
)
for (where in places) {
if (File(where + binaryName).exists()) {
println("where + binaryName = ${where + binaryName}")
found = true
break
}
}
}
return found
}
2.执行adb命令的方法(kotlin)
fun execCmd(cmd:String):String{
var result = ""
var dis:DataInputStream?=null
var dos:DataOutputStream?= null
try {
val exec = Runtime.getRuntime().exec("su")
dis =DataInputStream(exec.inputStream)
dos = DataOutputStream(exec.outputStream)
dos.writeBytes(cmd)
dos.writeBytes("\n")
dos.flush()
var line: String? = dis.readLine()
while (line!= null) {
Log.d("=====", line);
result += line
line=dis.readLine()
}
exec.waitFor()
}catch (e:Exception){
e.printStackTrace()
}finally {
dos?.let {
it.close()
}
dis?.let {
it.close()
}
}
return result
}
Tips: 执行adb命令的方法也可以用来检查是否有root权限,输入 “echo test” 如果返回也是test 那么说明有root权限。
3.替换命令执行调用
execCmd("dd if=/mnt/sdcard/framework-res.apk of=/system/framework/framework-res.apk"+ "\n"+"reboot")
解析:
dd linux 命令,文件拷贝操作(自己可以查查更多用法,因为Android也是基于linux 所以linux命令也适用,应该是这样,哈哈)
if = input File
of = output File
\n 换号,表示执行上一条命令
reboot 重启设备。
5.4 亲测有效。
如果不小心开不了机了,联系厂商提供如何恢复的方法,一般都留有重置按钮的操作,只是比较隐藏,有的在av插孔里面。
6.结束
你以为这就完了吗?
上面的命令是能够替换了,但是你如何放到客户的机顶盒里面? 让客户手动导入吗?
那么继续解决问题。。 具体代码后面补充
1.方案一: 通过网络下载对应型号的framework-res.apk到机顶盒中。
2.方案二:提取机顶盒里面的framework-res.apk 到外部存储目录,然后通过解压替换文件,重新压缩打包(待尝试)
所以,要走的路还没完。~~~~~~~~~~~~~~~~~~~~~~