Android 8.1RK平台增加自定义脚本,修改文件权限

        最近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();
    }
}
 
  

这样就大功告成了

你可能感兴趣的:(android)