最近按项目要求,需要做一个车机Android在线升级操作,但是cache内存太小了,最后只能寄存希望在 data/文件夹下,但是data/目录在6.0之后禁止recovery读取data文件.最后的解决方案是在/data/文件下创建一个系统app能够操作的文件夹,进行升级操作.
1、升级流程
Android自带升级流程 API RecoverySystem.java (framework/base/core/java/android/os/RecoverySystem.java)
调用如下代码就可以进行升级操作,对你没看错,就是一句代码,将你下载好的压缩包路径传过去就行.

   private void excuteUpdateZip(String local_path) {// TODO Auto-generated method stubtry {RecoverySystem.installPackage(this, new File(local_path));//RecoverySystem.installPackage(this, new File(local_path));} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}

但是 事情永远是比想象的麻烦, 因为我们的车机要求的是将压缩包放到 /data/目录下. 那放就放吧 先编译好一个全包 使用命令

adb root
adb remount
adb push  updata.zip /data/

使用模拟升级命令进行升级操作

adb shell "echo --update_package=/data/update.zip > /cache/recovery/command"adb shell syncadb reboot recovery

就这样成功进行了升级,what?完成了? 这么简单,原来这才是跳坑的开始,看到生面测试成功了之后,迫不及待的在自己的程序中将路径填写成 /data/update.zip ,开始了升级操作,结果失败了.开始检查原因
是不是AndroidManifest.xml中没有添加 如下权限
android:sharedUserId=“android.uid.system”
查看添加了,是不是没有对自己的apk进行系统签名?发现也签名了(如何给APK系统签名),没有放到system/app/文件夹下?也放了,.那原因出在哪里那?不想了,先去看看log

Android机器中 /cache/recovery/的目录结构如下:

cache/
└── recovery      ├── last_install├── last_kmsg  #系统升级的时候的全log. 如果有last_kmsg.1 #那last_kmsg 永远是最后一次升级的log,所以每#次只查看last_kmsg就行├── last_locale└── last_log   #升级过程中的简log,能看到为何升级失败

在log中查看到的是 --update_package=@/cache/recovery/block.map 看到这个结果的时候,第一感觉就是apk没有安装成功,于是加了log 发现加的log 成功打印,吓了一跳,自己撞见鬼了?

抱着程序员不明原因不放弃的心态,看了一下RecoverySystem.java 中的 installPackage 方法,原来是 installpackage在代码中做了限制, 要是设置的路径是以 /data/ 开头强制更改@/cache/recovery/block.map

  @SystemApipublic static void installPackage(Context context, File packageFile, boolean processed)throws IOException {//省略代码......if (filename.startsWith("/data/")) {if (processed) {//省略代码......} else {//省略代码......}//TODO 重点就是这句话,将路径强制求改filename = "@/cache/recovery/block.map";} final String filenameArg = "--update_package=" + filename + "\n";final String localeArg = "--locale=" + Locale.getDefault().toString() + "\n";final String securityArg = "--security\n";String command = filenameArg + localeArg;//省略代码......}}

看到这,挡了我的路,必定铲除,将代码很愉快的注掉了,重新编译进行测试.
激动的等待中…
又失败了?难道还有拦路虎? 我的心要崩溃了,为什么还是失败,还是查看log发现 --update_package=data/update.zip . 这么看来已经能写到重启文件中了.

查看log提示是 --update_package=data/update.zip Permission Denied 看来是datarecover没有权限读取/data目录啊
快速验证 是不是selinux问题 可以修改 BoardConfig.mk 添加如下代码 编译boot文件测试,如下代码是禁用selinux代码
BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive
2.selinux权限问题
经过一番调查 发现 data的 type属于 system_data_file类型的
在file_contexts中可以查看到
/data(/.*)? u:object_r:system_data_file:s0
在recovery.te中发现了如下代码

neverallow recovery data_file_type:file { no_w_file_perms no_x_file_perms };
neverallow recovery data_file_type:dir no_w_dir_perms;

也就是说明 recover.te何时都不能读取和操作/data/目录,那怎么办?当然是有办法的,我们可以新建一个文件夹 和自定义文件类型啊
首先是开机的时候要有一个文件夹
我们可以在init.rc 或者 init.qcom.rc中创建一个文件夹

#Create directory for download
mkdir /data/download 0771
chown system system /data/download

这样的话 我们已经创建了 文件夹,并且system app级别的应用可以读取.

那既然存储好了之后是不是下面需要 recovery可以读取到文件那?系统不允许读取 recovery.te /data/路径.那我们就自己创建一个文件类型,在file_contexts 增加类型

/data/download(/.*)?           u:object_r:download_data_file:s0

然后在file.te中定义download_data_file类型, 注意是只属于file_type类型的。
type download_data_file, file_type;
然后在recovery.te中增加对download_data_file的权限

allow recovery download_data_file:dir { write search remove_name };
allow recovery download_data_file:file { read getattr open unlink };

因为data目录有可能需要进行加密处理,我们还需要在uncrypt.te中增加如下。

allow uncrypt download_data_file:dir { search getattr };
allow uncrypt download_data_file:file { getattr read open };

以上就是完成了添加,我本地全编译,测试成功.
最后升级的过程中可能会看到Permission Denied 最后可以cat last_kmsg 查看 最后一样都会输出失败的权限原因
比如 :

avc:  denied  { open } for  pid=381 comm="recovery"
path="/data/download/update.zip" dev="mmcblk0p51" ino=513074
scontext=u:r:recovery:s0 tcontext=u:object_r:download_data_file:s0
tclass=file permissive=0

这种权限只能报错什么权限添加什么权限,我们可以遵循这个方法,从头开始寻找关键对象,然后调整一下顺序,生成一条语句,最后将该语句填写到.te中即可。
denied { open } scontext=u:r:recovery:s0 tcontext=u:object_r:download_data_file:s0 tclass=file

         A                                    B                                                             C                                                  DB                                    C                                                             D                                                   A

allow recovery download_data_file:tclass open;
如果升级没有错误,APP操作文件夹中的文件无效时,可以在操作的时候执行如下命令,如果报了相关权限问题,加上即可,
adb shell dmesg | grep denied

其它版本的系统升级,升级包存储在/data/分区的情况可以参考这篇文章,大同小异的。

Android 7.1 车机 Android 系统 在线升级,将安装到下载到/data/目录下面相关推荐

  1. 22款逸动plus车机解锁权限实现升级高德安装软件

    厂家出于性能考虑,对车机做了封闭处理,用户无法安装第三方软件以及更多个性化修改 工具箱在不影响质保的前提下,免root不刷机无损解锁厂家的限制,自定义自己喜欢的车机 ※准备工作※ 1.一条双公头USB ...

  2. android framework实战车机手机系统开发环境相关问题补充

    android源码不建议用virtualbox进行编译,如果要也建议vmware Please ensure KVM is properly installed and usable 这个属于kvm虚 ...

  3. Android 7.1 车机 下载 Android 系统 在线升级,将安装包放到/data/下进行升级

    最近按项目要求,需要做一个车机Android在线升级操作,但是cache内存太小了,最后只能寄存希望在 data/文件夹下,但是data/目录在6.0之后禁止recovery读取data文件.最后的解 ...

  4. 嘴哥有料系列-can教程3:车机娱乐系统在整车CAN网络的位置与作用

    原文章:https://mp.weixin.qq.com/s/Lwerwb1BGRe2I7gIwMdR3g 在过去的8年内,智能手机领域,尤其是Android/IOS等操作系统的发展, 智能手机已经发 ...

  5. 车载人机交互语音android,手机与车机如何实现语音智能交互?

    上一代系统使用汽车内置功能来提供娱乐与信息系统,而下一代汽车信息娱乐系统的功能将源于驾车者的移动设备,如iPhone.iPad和其它智能手机及平板电脑.这是一个巨大的变化.信息时代,屏幕已成为信息输出 ...

  6. android升级刷机,安卓系统怎么升级 怎么刷机安卓系统

    您可能感兴趣的话题: 安卓系统怎么升级 核心提示:其实安卓系统升级的方法有很多,以下小编就来与大家介绍下吧. 安卓系统怎么升级 怎么刷机安卓系统 最近有网友问小编"安卓系统怎么升级?&quo ...

  7. 海美迪盒子android升级包,海美迪TT盒子系统升级教程 在线升级超便捷

    原标题:海美迪TT盒子系统升级教程 在线升级超便捷 海美迪TT盒子支持本地升级与在线升级两种方式,在线升级对于用户来说很是便捷,系统将会自动提示有新系统版本,用户仅需根据提供操作即可,升级系统后,海美 ...

  8. android版本如何升级包,安卓手机系统怎么升级?安卓手机系统升级教程

    安卓手机系统怎么升级 随着系统的更新换代,相信不少网友对安卓系统的升级都很感兴趣,而这里指的一般都是通过刷机来升级,好像不刷就浑身不舒服一样.安卓系统升级可以在电脑上面下载官方的升级包,或者像小米系统 ...

  9. 电子狗服务器登记到本机信息,电子狗在线升级 车友在线全智能化操作

    据相关资料统计,消费者在选购GPS导航仪的时候,有15%的因素是考虑有无电子狗功能,以及电子狗功能设计是否人性化.电子狗已经是GPS导航仪最重要的卖点之一.但我们也不得不面对目前电子狗升级太麻烦的问题 ...

最新文章

  1. 一个没有意义的宇宙我们很难想象
  2. 关于Laravel中使用response()方法调用json()返回数据unicode编码转换的问题解决
  3. 深度学习的batch_size
  4. 如何在10亿数中找出前1000大的数
  5. boost::contract模块实现check的测试程序
  6. 经典C语言程序100例之二七
  7. retrofit 上传、下载文件
  8. 最常见的读入数据方法集锦
  9. 数据库知识:SQLServer变量相关知识介绍
  10. RabbitMQ教程C#版 “Hello World”
  11. ServerSocketChannel API用法
  12. 查看linux cpu负载均衡,关于linux内核cpu进程的负载均衡
  13. linux 内核 锐龙,AMDGPU内核驱动程序在Linux 5.0上运行良好
  14. ccpcfinal总结
  15. c语言怎么设计程序框图,C语言课程设计————写下流程图! 谢谢
  16. Windows小技巧 -- Win+R提高Windows使用效率
  17. Android得到位图方式
  18. 获取全国行政区域划分数据
  19. CC2640R2F UART
  20. python练习——恺撒密码 I

热门文章

  1. Contrastive Learning(对比学习,MoCo,SimCLR,BYOL,SimSiam,SimCSE)
  2. QQ小程序支付 QQ钱包支付 微信支付
  3. 广东迅视资管 中国移动物联网连接数超10.8亿
  4. 阿里技术员:DDD兴起的原因以及与微服务的关系
  5. Linux c fopen() 与fclose() 使用
  6. SQL 获取 weekday
  7. WEEKDAY函数:
  8. 论文笔记 计算机模型的贝叶斯校准 Bayesian calibration of computer models
  9. 七大实例巧解主板常见故障
  10. 一个例题:浮动引起元素变成行内块元素-display:inline-block