读取/data/data/下文件或者数据库

学习目标:

学习目标:读取/data/data/下文件或者数据库,Android 11读写权限动态申请


前言

当开发一款新的app时需要另一款app数据相互依赖就需要去读数据但Android 11 上面变成了特殊权限需要


一、特殊权限是什么?

首先 Android 的权限大致分为三种:
1.普通权限:只需要在清单文件中注册即可
2.危险权限:需要在代码中动态申请,以弹系统 Dialog 的形式进行请求
3.特殊权限:需要在代码中动态申请,以跳系统 Activity 的形式进行请求
在 Android 6.0 之后就变成了危险权限,而到了 Android 11 上面变成了特殊权限,而最明显的区别是一个是通过 Dialog 展示给用户看,另外一个是通过 Activity 展现给用户看。

二、读取步骤

1.动静结合

静 代码如下(示例):

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
    在AndroidManifest.xml文件中application节点中加上android:requestLegacyExternalStorage="true"属性
    就可以了,如下:
   <application
    android:requestLegacyExternalStorage="true"
    

    

动 代码如下(示例):

private fun requestPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            // 先判断有没有权限
            if (Environment.isExternalStorageManager()) {
                writeFile()

            } else {
                startActivityForResult(
                    Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION),
                    REQUEST_CODE
                )
            }
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // 先判断有没有权限
            if (ActivityCompat.checkSelfPermission(
                    this,
                    Manifest.permission.READ_EXTERNAL_STORAGE
                ) == PackageManager.PERMISSION_GRANTED &&
                ContextCompat.checkSelfPermission(
                    this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE
                ) == PackageManager.PERMISSION_GRANTED
            ) {

                writeFile()
            } else {
                ActivityCompat.requestPermissions(
                    this,
                    arrayOf(
                        Manifest.permission.READ_EXTERNAL_STORAGE,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE
                    ),
                    REQUEST_CODE
                )
            }
        } else {
            writeFile()
        }
    }
   /**
     * In this method, you can write the business logic related to reading and writing
     */
 private fun writeFile() {
 ......
 }   
 

2.读入数据

数据权限已经申请了原本以为万事俱备只欠东风了可惜…读取的是另一个app的/data/data/这些显然不够,当然如果那么容易咱们的手机信息安全是个大问题呢 。当咱们是开发者只要咱们出发点是正义的为全人类制造福利的,正义无敌嘛哈哈。这个时候我想到了雷震子拿起了家伙事一顿操作猛似虎
1.下载模拟器
.在这里插入图片描述
2.开启root权限在这里插入图片描述
3.我们不能直接访问/data/data/下路径怎么搞呢?既然不能直接搞那我们间接的搞吧,打开命令框输入adb shell ,mkdir test 新建文件,cat /data/data/com.whatsapp/shared_prefs/keystore.xml > /sdcard/test/keystore.xml 复制 文件到指定文件对啊我们可以复制到可以访问的目录下载访问啊。可是咱们的这些都需要代码执行怎么搞呢…妈的坑真多哈哈其实这才是开始。咱们有root权限这玩意相当于你有上帝视角这他妈可不是开玩笑的,可以直接代码执行shell命令。shell的运行原理(shell是什么)Linux严格意义上是一个操作系统,我们称为核心,但我们一般的用户是不能直接使用核心的,而是通过外壳程序。也就是shell,对比Windows,图形界面就是外壳程序。shell的简单定义就是命令行解释器,功能是将使用者的命令翻译给核心处理,同时将核心处理的结果翻译给使用者。可以看出shell主要是对我们的指令进行解析,解析指令给Linux内核。反馈结果在通过内核运行出结果,通过shell解析给用户。
在这里插入图片描述
这是我们就可以理解为什么说外壳程序包裹着我们的操作系统,外壳程序仅仅对我们的指令进行解析,解析指令给Linux内核。反馈结果在通过内核运行出结果,通过shell解析给用户。

    下面我们来接着了解shell。shell在解释命令的时候并不是自己亲自执行,而是派生子进程让子进程去完成这项工作,这样的好处是把风险交给别人,当指令的执行出现问题时不会影响到shell(影响到其他指令的执行)。shell不可以挂,shell 一旦挂就没有什么可以解释命令了。对我们而言shell为了保证自己风险最低,通过创建子进程进行命令行的解释工作。而shell自己只要去等就可以了。

     可到底什么是shell呢?shell 是一个外壳程序统称,如Windows的图形界面(GUI),Linux下我们使用的bash就是具体的一种shell。 .

在这里插入图片描述
举个例子:shell是媒婆,那么bash就是王婆。shell是外壳程序的统称,bash 是具体的一种shell。
以上就是我们对shell初步的理解。

执行shell命令需要的工具类 代码如下(示例):

public final class ShellUtils {

    private static final String LINE_SEP = System.getProperty("line.separator");

    private ShellUtils() {
        throw new UnsupportedOperationException("u can't instantiate me...");
    }

    /**
     * Execute the command asynchronously.
     *
     * @param command  The command.
     * @param isRooted True to use root, false otherwise.
     * @param consumer The consumer.
     * @return the task
     */
    public static Utils.Task<CommandResult> execCmdAsync(final String command,
                                                         final boolean isRooted,
                                                         final Utils.Consumer<CommandResult> consumer) {
        return execCmdAsync(new String[]{command}, isRooted, true, consumer);
    }

    /**
     * Execute the command asynchronously.
     *
     * @param commands The commands.
     * @param isRooted True to use root, false otherwise.
     * @param consumer The consumer.
     * @return the task
     */
    public static Utils.Task<CommandResult> execCmdAsync(final List<String> commands,
                                                         final boolean isRooted,
                                                         final Utils.Consumer<CommandResult> consumer) {
        return execCmdAsync(commands == null ? null : commands.toArray(new String[]{}), isRooted, true, consumer);
    }

    /**
     * Execute the command asynchronously.
     *
     * @param commands The commands.
     * @param isRooted True to use root, false otherwise.
     * @param consumer The consumer.
     * @return the task
     */
    public static Utils.Task<CommandResult> execCmdAsync(final String[] commands,
                                                         final boolean isRooted,
                                                         final Utils.Consumer<CommandResult> consumer) {
        return execCmdAsync(commands, isRooted, true, consumer);
    }

    /**
     * Execute the command asynchronously.
     *
     * @param command         The command.
     * @param isRooted        True to use root, false otherwise.
     * @param isNeedResultMsg True to return the message of result, false otherwise.
     * @param consumer        The consumer.
     * @return the task
     */
    public static Utils.Task<CommandResult> execCmdAsync(final String command,
                                                         final boolean isRooted,
                                                         final boolean isNeedResultMsg,
                                                         final Utils.Consumer<CommandResult> consumer) {
        return execCmdAsync(new String[]{command}, isRooted, isNeedResultMsg, consumer);
    }

    /**
     * Execute the command asynchronously.
     *
     * @param commands        The commands.
     * @param isRooted        True to use root, false otherwise.
     * @param isNeedResultMsg True to return the message of result, false otherwise.
     * @param consumer        The consumer.
     * @return the task
     */
    public static Utils.Task<CommandResult> execCmdAsync(final List<String> commands,
                                                         final boolean isRooted,
                                                         final boolean isNeedResultMsg,
                                                         final Utils.Consumer<CommandResult> consumer) {
        return execCmdAsync(commands == null ? null : commands.toArray(new String[]{}),
                isRooted,
                isNeedResultMsg,
                consumer);
    }

    /**
     * Execute the command asynchronously.
     *
     * @param commands        The commands.
     * @param isRooted        True to use root, false otherwise.
     * @param isNeedResultMsg True to return the message of result, false otherwise.
     * @param consumer        The consumer.
     * @return the task
     */
    public static Utils.Task<CommandResult> execCmdAsync(final String[] commands,
                                                         final boolean isRooted,
                                                         final boolean isNeedResultMsg,
                                                         @NonNull final Utils.Consumer<CommandResult> consumer) {
        return UtilsBridge.doAsync(new Utils.Task<CommandResult>(consumer) {
            @Override
            public CommandResult doInBackground() {
                return execCmd(commands, isRooted, isNeedResultMsg);
            }
        });
    }

    /**
     * Execute the command.
     *
     * @param command  The command.
     * @param isRooted True to use root, false otherwise.
     * @return the single {@link CommandResult} instance
     */
    public static CommandResult execCmd(final String command, final boolean isRooted) {
        return execCmd(new String[]{command}, isRooted, true);
    }

    /**
     * Execute the command.
     *
     * @param command  The command.
     * @param envp     The environment variable settings.
     * @param isRooted True to use root, false otherwise.
     * @return the single {@link CommandResult} instance
     */
    public static CommandResult execCmd(final String command, final List<String> envp, final boolean isRooted) {
        return execCmd(new String[]{command},
                envp == null ? null : envp.toArray(new String[]{}),
                isRooted,
                true);
    }

    /**
     * Execute the command.
     *
     * @param commands The commands.
     * @param isRooted True to use root, false otherwise.
     * @return the single {@link CommandResult} instance
     */
    public static CommandResult execCmd(final List<String> commands, final boolean isRooted) {
        return execCmd(commands == null ? null : commands.toArray(new String[]{}), isRooted, true);
    }

    /**
     * Execute the command.
     *
     * @param commands The commands.
     * @param envp     The environment variable settings.
     * @param isRooted True to use root, false otherwise.
     * @return the single {@link CommandResult} instance
     */
    public static CommandResult execCmd(final List<String> commands,
                                        final List<String> envp,
                                        final boolean isRooted) {
        return execCmd(commands == null ? null : commands.toArray(new String[]{}),
                envp == null ? null : envp.toArray(new String[]{}),
                isRooted,
                true);
    }

    /**
     * Execute the command.
     *
     * @param commands The commands.
     * @param isRooted True to use root, false otherwise.
     * @return the single {@link CommandResult} instance
     */
    public static CommandResult execCmd(final String[] commands, final boolean isRooted) {
        return execCmd(commands, isRooted, true);
    }

    /**
     * Execute the command.
     *
     * @param command         The command.
     * @param isRooted        True to use root, false otherwise.
     * @param isNeedResultMsg True to return the message of result, false otherwise.
     * @return the single {@link CommandResult} instance
     */
    public static CommandResult execCmd(final String command,
                                        final boolean isRooted,
                                        final boolean isNeedResultMsg) {
        return execCmd(new String[]{command}, isRooted, isNeedResultMsg);
    }

    /**
     * Execute the command.
     *
     * @param command         The command.
     * @param envp            The environment variable settings.
     * @param isRooted        True to use root, false otherwise.
     * @param isNeedResultMsg True to return the message of result, false otherwise.
     * @return the single {@link CommandResult} instance
     */
    public static CommandResult execCmd(final String command,
                                        final List<String> envp,
                                        final boolean isRooted,
                                        final boolean isNeedResultMsg) {
        return execCmd(new String[]{command}, envp == null ? null : envp.toArray(new String[]{}),
                isRooted,
                isNeedResultMsg);
    }

    /**
     * Execute the command.
     *
     * @param command         The command.
     * @param envp            The environment variable settings array.
     * @param isRooted        True to use root, false otherwise.
     * @param isNeedResultMsg True to return the message of result, false otherwise.
     * @return the single {@link CommandResult} instance
     */
    public static CommandResult execCmd(final String command,
                                        final String[] envp,
                                        final boolean isRooted,
                                        final boolean isNeedResultMsg) {
        return execCmd(new String[]{command}, envp, isRooted, isNeedResultMsg);
    }

    /**
     * Execute the command.
     *
     * @param commands        The commands.
     * @param isRooted        True to use root, false otherwise.
     * @param isNeedResultMsg True to return the message of result, false otherwise.
     * @return the single {@link CommandResult} instance
     */
    public static CommandResult execCmd(final List<String> commands,
                                        final boolean isRooted,
                                        final boolean isNeedResultMsg) {
        return execCmd(commands == null ? null : commands.toArray(new String[]{}),
                isRooted,
                isNeedResultMsg);
    }

    /**
     * Execute the command.
     *
     * @param commands        The commands.
     * @param isRooted        True to use root, false otherwise.
     * @param isNeedResultMsg True to return the message of result, false otherwise.
     * @return the single {@link CommandResult} instance
     */
    public static CommandResult execCmd(final String[] commands,
                                        final boolean isRooted,
                                        final boolean isNeedResultMsg) {
        return execCmd(commands, null, isRooted, isNeedResultMsg);
    }

    /**
     * Execute the command.
     *
     * @param commands        The commands.
     * @param envp            Array of strings, each element of which
     *                        has environment variable settings in the format
     *                        <i>name</i>=<i>value</i>, or
     *                        <tt>null</tt> if the subprocess should inherit
     *                        the environment of the current process.
     * @param isRooted        True to use root, false otherwise.
     * @param isNeedResultMsg True to return the message of result, false otherwise.
     * @return the single {@link CommandResult} instance
     */
    public static CommandResult execCmd(final String[] commands,
                                        final String[] envp,
                                        final boolean isRooted,
                                        final boolean isNeedResultMsg) {
        int result = -1;
        if (commands == null || commands.length == 0) {
            return new CommandResult(result, "", "");
        }
        Process process = null;
        BufferedReader successResult = null;
        BufferedReader errorResult = null;
        StringBuilder successMsg = null;
        StringBuilder errorMsg = null;
        DataOutputStream os = null;
        try {
            process = Runtime.getRuntime().exec(isRooted ? "su" : "sh", envp, null);
            os = new DataOutputStream(process.getOutputStream());
            for (String command : commands) {
                if (command == null) continue;
                os.write(command.getBytes());
                os.writeBytes(LINE_SEP);
                os.flush();
            }
            os.writeBytes("exit" + LINE_SEP);
            os.flush();
            result = process.waitFor();
            if (isNeedResultMsg) {
                successMsg = new StringBuilder();
                errorMsg = new StringBuilder();
                successResult = new BufferedReader(
                        new InputStreamReader(process.getInputStream(), "UTF-8")
                );
                errorResult = new BufferedReader(
                        new InputStreamReader(process.getErrorStream(), "UTF-8")
                );
                String line;
                if ((line = successResult.readLine()) != null) {
                    successMsg.append(line);
                    while ((line = successResult.readLine()) != null) {
                        successMsg.append(LINE_SEP).append(line);
                    }
                }
                if ((line = errorResult.readLine()) != null) {
                    errorMsg.append(line);
                    while ((line = errorResult.readLine()) != null) {
                        errorMsg.append(LINE_SEP).append(line);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (successResult != null) {
                    successResult.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (errorResult != null) {
                    errorResult.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (process != null) {
                process.destroy();
            }
        }
        return new CommandResult(
                result,
                successMsg == null ? "" : successMsg.toString(),
                errorMsg == null ? "" : errorMsg.toString()
        );
    }

    /**
     * The result of command.
     */
    public static class CommandResult {
        public int    result;
        public String successMsg;
        public String errorMsg;

        public CommandResult(final int result, final String successMsg, final String errorMsg) {
            this.result = result;
            this.successMsg = successMsg;
            this.errorMsg = errorMsg;
        }

        @Override
        public String toString() {
            return "result: " + result + "\n" +
                    "successMsg: " + successMsg + "\n" +
                    "errorMsg: " + errorMsg;
        }
    }
}

/*
* 调用execCmd里面两个参数一个是shell命令,第二个是是否开启root返回的是return execCmd(new String[]{command}, isRooted, true)下面有调用实例successMsg
*/
  val execCmd = ShellUtils.execCmd("写shell命令", true)
                    LogUtil.logGGQ("task", "输出结果-->${execCmd.successMsg}")
                    LogUtil.logGGQ("task", "输出结果-->${execCmd.errorMsg}")
                    LogUtil.logGGQ("task", "输出结果-->${execCmd.result}")    
 导入库                                   
implementation 'com.blankj:utilcodex:1.30.6'
访问拷贝后的文件地址
val readFile2String = FileIOUtils.readFile2String("sdcard/android/axolotl.db")
        LogUtil.logGGQ("task", "stringToBase64----->$readFile2String")
插入一个小知识点把String的转换成base64码
 /**
     * 把String的转换成base64码
     */
    public static String stringToBase64(String ss) {
        String encode="";
        try{
            byte[] bytes = ss.getBytes();
             encode = Base64Util.encode(bytes);
//            return encode;
        }catch (Exception e){
           LogUtil.logGGQ("task",e.getMessage());
        }

        return encode;
    }
val stringToBase64 = Base64Object.stringToBase64(readFile2String)
        LogUtil.logGGQ("task", "stringToBase64----->$stringToBase64")
        放文件到这就结束了

数据库文件查看

复制和上面一样代码执行shell

/*
*数据库打开文件路径
*/

 val database: SQLiteDatabase = SQLiteDatabase.openOrCreateDatabase(
            "sdcard/android/axolotl.db", null
        )



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值