修改Android手机的Preferences配置文件

来源:互联网 发布:我叫mt3 源码 编辑:程序博客网 时间:2024/04/29 16:45

我们的目的是修改Android手机中某app下的配置文件(至于为什么要修改这个配置文件呢? 你猜呀!)

即 /data/data/{package_name}/shared_prefs/{xxx}.xml文件

附:

{package_name} 为某App的包名

{xxx}为某个配置文件


修改步骤:

1. 你得把手机root

2. 下载Root Explorer,定位到上面那个路径下修改即可。

(完了, xxx  不要打偶! T_T……)


实际上,由于手机屏幕略小,如果需要经常的修改文件,在软键盘上敲下一长串无意义的文件,非常非常滴不方便的说。

即使,像哥一样聪明的知道,通过把资料才电脑发送到手机QQ上,再复制到剪贴板,然后粘贴到Root Explorer打开的配置文件里,省去了手动敲的步骤了。

但是,但是每次用食指或大拇指小心翼翼的定位光标还是十分痛苦的说。如果在修改的部分附近,即使多删去一些字符也无妨,拷贝之后,再手动打回来,也比拼人品刚好定位到好。

另外一种同步文字到手机上的方法:浏览器打开notepad.cc/xxx, 把文字拷贝进去,然后用Android手机的浏览器访问这个路径即可。

后缀xxx自定义,尽量独特一些好记一些,毕竟这也是要手敲的。。。


第二种方法, 既然配置文件是XML文件,自己去写个App程序解析不就可以了吗。

对头,虽然Java有好几种方法解析XML文件的方法,但是哥懒呀!(别打头。。。)


第三种方法,看好,要放大招了。

因为Android SDK提供了读写自家App内置配置文件的方法,好像是getSharedPreferences({xxx}, MODE_PRIVATE),

那么可不可以利用这个方法呢??

为了安全,SDK并未提供可以直接访问其他App的配置文件的方法(CreatePackageContext 和 shareUserId 使用颇多限制),

所以我们可以这样做: 

把要修改的配置文件拷贝到咱自己写的App的配置文件目录下,修改后再拷贝回去。 :)

当然前提是必须先root,(葵花宝典里不是说,欲练此功,必先自宫……)root不是阉割,而像开启了潜能,获得了强大力量,控制不好可能会误伤而已。


但是(“但是”,就意味着有问题呀)

其1,注意修改的时候最好把原App先退出,不然可能不会成功的。

举个例子:

假如App启动的时候调用了getSharedPreferences方法读取了配置文件,然后咱用Root Explorer去手动修改了这个配置文件的内容,如果App之后有写入配置文件的操作,会覆盖咱修改的内容的。

原因是SharedPreferences第一次读配置文件的时候,有个缓存在内存中,之后不会再去读这个配置文件的内容了,即使手动修改文件内容也不会反应到内存中。(纯属个人推测)


但是其2 注意文件权限,特别是所有者权限,读写执行权限倒无所谓。

不同的App安装时获得临时的不同的userId,如果拷贝之后,不是当前用户的所有者,用getSharedPreferences方法保存之后实际会生成一个新的文件,并不包含原来拷贝过来的文件的内容。

所以,实际步骤是:

拷贝原文件过来,然后修改目标文件的所有者为目标userId,修改内容,完毕后,再将文件拷贝回去,同样要把权限修改回去。

操作是用Java调用系统(Linux)命令来实现的。


关键代码如下:

拷贝文件的方法:

cp -f src srcBak   先拷贝一个临时文件

chown  destUid:destUid srcBak 修改临时文件的所有者为目标文件的所有者, uid和gid默认是一样的

cp -pf  srcBak dest  直接覆盖目标文件

至于uid的获取:使用Utils.getFileUid(),将配置文件所在的目录(/data/data/{package_name}/shared_prefs)传进去就可以获得了。

    private boolean copy(String src, String dest, String destUid) {        if(!new File(src).exists()){            return false;        }        String srcBak = src + "_bak";        List<String> cmdList = new ArrayList<>();        cmdList.add("cp -f " + src + " " + srcBak);        cmdList.add("chown " + destUid +":" + destUid +" " + srcBak);        cmdList.add("cp -pf " + srcBak + " " + dest);        if(Utils.runSu(cmdList, null)){            return true;        }        return false;    }


工具文件:


public class Utils {    private static final String TAG = "Utils";    private static Context mContext;    public static final String DEFAULT_SU = "/system/xbin/su";    public static boolean isInitialized = false;   /**     * execute a common system command     *     * @param cmd     */    public static void run(String cmd) {        Runtime runtime = Runtime.getRuntime();        Process process = null;        try {            process = runtime.exec(cmd);            process.waitFor();        } catch (IOException e) {            e.printStackTrace();        } catch (InterruptedException e) {            e.printStackTrace();        }    }    /**     * Get a result from inputstream     *     * @param in     * @return     */    private static String getResult(InputStream in) {        if (in == null) {            return "";        }        byte[] bytes = new byte[1024];        StringBuffer sb = new StringBuffer();        try {            while (in.read(bytes) != -1) {                sb.append(new String(bytes));            }            return sb.toString();        } catch (IOException e) {            e.printStackTrace();            return "";        } finally {            try {                if (in != null) {                    in.close();                }            } catch (IOException e) {                e.printStackTrace();            }        }    }    /**     * Execute a system command with root permission     *     * @param cmdList     */    public static boolean runSu(List<String> cmdList, CmdResult result) {        return runSu(cmdList, DEFAULT_SU, result);    }    public static boolean runSu(List<String> cmdList, String suPath, CmdResult result) {        File suFile = new File(suPath);        if (!suFile.exists()) {            showToast("Have your phone been rooted?\nSu not exits: " + suPath, Toast.LENGTH_LONG);            Log.w(TAG, "su not exists: " + suPath);            return false;        }        if (!suFile.canExecute()) {            Log.w(TAG, "su can not be executed: " + suPath);            return false;        }        if (cmdList == null || cmdList.size() == 0) {            return false;        }        Runtime runtime = Runtime.getRuntime();        Process process = null;        long startStamp = System.currentTimeMillis();        try {            process = runtime.exec(suPath);            DataOutputStream os = new DataOutputStream(process.getOutputStream());            for (String cmd : cmdList) {                if (!cmd.endsWith("\n")) {                    cmd += "\n";                }                os.writeBytes(cmd);                Log.d(TAG, "su cmd: " + cmd);            }            os.writeBytes("exit\n");            os.flush();            os.close();            InputStream in = process.getInputStream();            in = (in!=null) ? in : process.getErrorStream();            if (result!=null) {                result.retStr = getResult(in);                result.ret = true;                Log.d(TAG, "su result: " + result.retStr);            }            if(process.waitFor() == 0){                return true;            }else {                // cost too much time, check su                if(System.currentTimeMillis() - startStamp > 3*1000) {                    if(mContext != null) {                        Toast.makeText(mContext, "Have your phone been rooted?", Toast.LENGTH_LONG).show();                    }                }                return false;            }        } catch (IOException e) {            e.printStackTrace();        } catch (InterruptedException e) {            e.printStackTrace();        }        return false;    }    /**     * Get a file owner's id     * @param path     * @return     */    public static String getFileUid(String path) {        File file = new File(path);        if (!file.exists()) {            return "";        }        List<String> cmdList = new ArrayList<String>();        if(file.isDirectory()){            cmdList.add("ls -ld " + path);        }else {            cmdList.add("ls -l " + path);        }        CmdResult cmdResult = new CmdResult();        if( runSu(cmdList, cmdResult) ){            if (cmdResult.ret) {                String result =  cmdResult.retStr;                String[] resArr = result.split(" ");                if (resArr.length > 1 && !"".equals(resArr[1])) {                    return resArr[1];                }            }        }        return "";    }    public static void showToast(String text , int duration) {        if(mContext != null){            Toast.makeText(mContext, text, duration).show();        }    }}

public class CmdResult {    public boolean ret;    public String retStr;}


Over!



0 0