最近RK3326项目上遇到个问题,OTA升级完重启后需要去/cache/recovery目录下读取一个文件,last_flag,读取过程中报错,提示没有权限,很奇怪,我的明明是系统应用,也加了权限还是报错,所以写个脚本在读取文件之前先设置一下文件的权限,这样就能读取到文件里面的内容。

首先建立一个脚本 rp_update_file.sh ,内容很简单,就是修改下文件权限如下

#!/system/bin/sh

su

chmod 777 /cache/recovery/last_flag

文件放在device/rockchip/rk3326目录下,然后在init.rk3326.rc中添加一个服务,

#for rp file update

service rp_update_file /system/bin/sh /system/etc/rp_update_file.sh

class main

user root

group root

disabled

oneshot

seclabel u:r:shell:s0

再增加一个变量来控制这个服务

on property:persist.rpfileupdate.enable=1

start rp_update_file

on property:persist.rpfileupdate.enable=0

stop rp_update_file

设置一个property,当persist.rpfileupdate.enable=1 时就会去执行这个脚本。

当然还需要给这个脚本添加权限,在system/core/libcutilsfs_config.cpp 目录中增加

diff --git a/core/libcutils/fs_config.cpp b/core/libcutils/fs_config.cpp

old mode 100644

new mode 100755

index cc96ff8..9399694

--- a/core/libcutils/fs_config.cpp

+++ b/core/libcutils/fs_config.cpp

@@ -162,6 +162,8 @@ static const struct fs_path_config android_files[] = {

{ 00600, AID_ROOT, AID_ROOT, 0, "vendor/default.prop" },

{ 00444, AID_ROOT, AID_ROOT, 0, ven_conf_dir + 1 },

{ 00444, AID_ROOT, AID_ROOT, 0, ven_conf_file + 1 },

+

+ { 00755, AID_ROOT, AID_ROOT, 0, "system/etc/rp_update_file.sh" },

// the following two files are INTENTIONALLY set-uid, but they

// are NOT included on user builds.

OK这样脚本就加好了,然后在android代码中读取文件之前设置一下property,代码如下

package com.rp.rpreceiver;

import android.app.AlertDialog;

import android.content.BroadcastReceiver;

import android.content.ComponentName;

import android.content.Context;

import android.content.Intent;

import android.os.Handler;

import android.os.Message;

import android.os.RecoverySystem;

import android.os.storage.StorageManager;

import android.provider.Settings;

import android.util.Log;

import android.view.WindowManager;

import android.widget.Toast;

import java.io.File;

import java.io.FileReader;

import java.io.IOException;

import java.lang.reflect.Field;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.security.GeneralSecurityException;

import java.util.List;

public class UsbReceiver extends BroadcastReceiver {

private static Boolean isBootComplete = false;

private Handler handler=new Handler(){

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

}

};

private static File RECOVERY_DIR = new File("/cache/recovery");

private static File UPDATE_FLAG_FILE = new File(RECOVERY_DIR, "last_flag");

private final String SUCCESS="success";

private final String FAILED="fail";

@Override

public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

Log.i("gyx", "UsbReceiver action=" + action);

Log.i("gyx","isBootComplete="+isBootComplete);

if (action.equals("android.intent.action.BOOT_COMPLETED")) {

setProperty("persist.rpfileupdate.enable","1");

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

int start_ota_upgrade = Settings.System.getInt(context.getContentResolver(), "start_ota_upgrade", 0);

Log.i("gyx","start_ota_upgrade="+start_ota_upgrade);

String command = readFlagCommand();

if(start_ota_upgrade==1){

Settings.System.putInt(context.getContentResolver(),"start_ota_upgrade",0);

if(command!=null ){

if (command.startsWith("success")) {

Log.i("gyx","update success");

} else if (command.startsWith("updating")) {

Log.i("gyx","update failed");

}

}else {

Log.i("gyx","command =null update failed");

}

}

setProperty("persist.rpfileupdate.enable","0");

isBootComplete = true;

}else if (action.equals("android.intent.action.MEDIA_MOUNTED") && isBootComplete) {

String sdCardPath = getSdCardPath(context);

String path = FindFileOnUSB("update.zip");

if (path.equals("")) {

Log.i("gyx","update.zip not found");

} else {

Log.i("gyx","update system");

systemUpdate(context, sdCardPath + "/update.zip");

}

}

}

public static void setProperty(String key, String value) {

try {

Class> c = Class.forName("android.os.SystemProperties");

Method set = c.getMethod("set", String.class, String.class);

set.invoke(c, key, value);

} catch (Exception e) {

e.printStackTrace();

}

}

public String getSdCardPath(Context context) {

int TYPE_PUBLIC = 0;

File file = null;

String path = null;

StorageManager mStorageManager = context.getSystemService(StorageManager.class);

Class> mVolumeInfo = null;

try {

mVolumeInfo = Class.forName("android.os.storage.VolumeInfo");

Method getVolumes = mStorageManager.getClass().getMethod(

"getVolumes");

Method volType = mVolumeInfo.getMethod("getType");

Method isMount = mVolumeInfo.getMethod("isMountedReadable");

Method getPath = mVolumeInfo.getMethod("getPath");

Field internalPath = mVolumeInfo.getDeclaredField("internalPath");

List mListVolumeinfo = (List) getVolumes

.invoke(mStorageManager);

Log.d("getSdCardPath", "mListVolumeinfo.size=" + mListVolumeinfo.size());

for (int i = 0; i < mListVolumeinfo.size(); i++) {

int mType = (Integer) volType.invoke(mListVolumeinfo.get(i));

Log.d("getSdCardPath", "mType=" + mType);

if (mType == TYPE_PUBLIC) {

boolean misMount = (Boolean) isMount.invoke(mListVolumeinfo.get(i));

Log.d("getSdCardPath", "misMount=" + misMount);

if (misMount) {

file = (File) getPath.invoke(mListVolumeinfo.get(i));

if (file != null) {

// path = file.getAbsolutePath();

path = (String) internalPath.get(mListVolumeinfo.get(i));

Log.d("getSdCardPath", "path=" + path);

return path;

}

}

}

}

} catch (ClassNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (NoSuchMethodException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IllegalAccessException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IllegalArgumentException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (InvocationTargetException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (NoSuchFieldException e) {

e.printStackTrace();

}

return "";

}

public void systemUpdate(final Context context, String filepath) {

File updaterFile = new File(filepath);

try {

//升级

RecoverySystem.installPackage(context, updaterFile);

} catch (IOException e) {

e.printStackTrace();

}

}

public static String readFlagCommand() {

if (!UPDATE_FLAG_FILE.exists()) {

return null;

}

Log.d("RKRecoverySystem", "UPDATE_FLAG_FILE is exists");

char[] buf = new char[128];

int readCount = 0;

try {

readCount = new FileReader(UPDATE_FLAG_FILE).read(buf, 0, buf.length);

Log.d("RKRecoverySystem", "readCount = " + readCount + " buf.length = " + buf.length);

} catch (IOException e) {

Log.i("gyx","",e);

Log.e("RKRecoverySystem", "can not read /cache/recovery/last_flag!");

} finally {

UPDATE_FLAG_FILE.delete();

}

StringBuilder sBuilder = new StringBuilder();

int i = 0;

while (i < readCount && buf[i] != '\u0000') {

sBuilder.append(buf[i]);

i++;

}

return sBuilder.toString();

}

}

这样就大功告成了

rk android8.1加密,Android 8.1RK平台增加自定义脚本,修改文件权限相关推荐

  1. 【Android 安装包优化】WebP 应用 ( libwebp 源码下载 | Android.mk 和 Application.mk 构建脚本修改 | libwebp 函数库编译 )

    文章目录 一. libwebp 源码下载 二. libwebp 源码编译脚本修改 三. libwebp 函数库编译 四.参考资料 一. libwebp 源码下载 Google 提供了一系列的 WebP ...

  2. Android - Audio - Qcom平台 - QM215耳机常见修改和粗略识别流程

    背景 耳机的分类 调试Qcom耳机功能时常用修改 (1)qcom,msm-mbhc-hphl-swh = <1>; (2)qcom,msm-hs-micbias-type="in ...

  3. android 如何去掉自定义标签页,Android中为TextView增加自定义的HTML标签

    Android中的TextView,本身就支持部分的Html格式标签.这其中包括常用的字体大小颜色设置,文本链接等.使用起来也比较方便,只需要使用Html类转换一下即可.比如: textView.se ...

  4. Android中为TextView增加自定义的HTML标签

    为什么80%的码农都做不了架构师?>>>    Android中的TextView,本身就支持部分的Html格式标签.这其中包括常用的字体大小颜色设置,文本链接等.使用起来也比较方便 ...

  5. pdf加密?教您一招免费去掉PDF文件权限

    您有遇到这样的问题吗?好不容易从别处弄来一个PDF,用的时候发现这文件只能查看,不能打印,想修改居然还提示加密了,这种情况该怎么解决呢.今天给大家推荐一款免费且可以批量的进行PDF解密的工具. 首先, ...

  6. android非root状态,修改文件权限,非Root权限的Android上运行可执行文件

    使用 NDK 编译可执行文件,即 Android.mk 文件应该是编译 target 应该是 BUILD_EXECUTABLE include $(BUILD_EXECUTABLE) 假设,编出的目标 ...

  7. 【Android Framework】开机执行自定义脚本之Init.rc文件的妙用与如何编写开机脚本?

    Init.rc妙用及语法说明 参考:system\core\init\readme.txt 案例1 当开机启动完毕,写mpp2的寄存器,使其设置为PWM模式. #add by eliot shao 2 ...

  8. Android m 自定义下拉菜单,Android实现动画效果的自定义下拉菜单功能

    我们在购物APP里面设置收货地址时,都会有让我们选择省份及城市的下拉菜单项.今天我将使用Android原生的 Spinner 控件来实现一个自定义的下拉菜单功能,并配上一个透明渐变动画效果. 要实现的 ...

  9. 修改Android中的文件权限

    在Android中有一个精简版的linux系统,因为是linux系统,那么有时候在写Android应用程序的时候会遇到权限问题.我们都知道在shell中可以通过chmod命令来修改权限,所以就希望通过 ...

最新文章

  1. 南京晓庄学院大一第二学期计算机数据结构期末考试试卷及答案,南京晓庄学院数据结构题库参考答案.docx...
  2. PHP扩展开发-01:第一个扩展
  3. 判断程序是否运行在虚拟机中的代码
  4. 201904快速阅读术
  5. 51CTO‘s Bug?
  6. oracle学习笔记 学习前奏
  7. win10桌面null图标删除
  8. python分词原理_结巴分词原理
  9. ZBlogPHP评论验证码无法显示
  10. 笔记本双显卡 EFI 启动安装 ArchLinux
  11. ie不能加载flash html,ie浏览器flash无法加载怎么修复_win7系统ie浏览器flash加载不了如何解决-系统城...
  12. mac虚拟摄像头插件_VCam虚拟摄像头(电脑虚拟摄像头视频软件)V5.4.2 官方最新版...
  13. 计算机英语说明文,英语说明文作文
  14. ZigBee传感数据采集实验
  15. 2010上海各区排行按繁华程度
  16. 赛码网: 小明很喜欢打字,今天小红给了小明一个字符串。
  17. 求生之路2联机服务器没有响应,求生之路2进不了服务器
  18. R语言Bioconductor安装全流程
  19. 软工网络15个人阅读作业2(201521123007谭燕)
  20. 手摸手教学 - Docker(五) 超级爽!持久化数据库-bind mounts!

热门文章

  1. 对于刷oj时因为scanf()出现wa而cin却AC的详解 【scanf() 和 cin 详解】
  2. 2.4.3 死锁的处理策略-避免死锁
  3. docker之数据卷管理
  4. selenium2与python自动化2-元素定位
  5. DOS命令查看网络信息
  6. 如何保护 SpringBoot 配置文件中的敏感信息
  7. Java多线程面试准备:聊聊Executor框架
  8. String s=new String(abc)创建了2个对象的原因
  9. jsp中c:forEach的应用
  10. Xmanager连接Linux桌面异常解决方案