android代码执行adb shell终端命令(linux命令)并返回执行结果

本文介绍了一种在未Root的Android设备上运行Adb命令的方法,并提供了一个名为RootCmd的工具类,用于执行Linux命令,包括修改文件权限等。此外,还探讨了一些命令无法执行的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2020年6月2日17:37:27更新:

这篇博文还是有挺多人看的,但之前写的方法其实比较早还是有点问题的,后面我又优化了下工具类。
后来我无意间看到一个之前看到非Root运行Adb的技巧,算是黑科技吧,亲测可用,放到了另一篇博文。转发的,大家可以研究研究。
非root直接在手机端运行adb命令:地址:https://miqt.github.io/2020/06/02/高级权限命令,例如修改手机设置等(转)/


在做Android开发板相关的开发需求的时候,我们有的时候需要去到Android系统的一个linux终端(adbshell)里面来执行一些命令,以便于查看部分文件内容或者修改部分文件权限等需求,通常我们可以使用Android studio自带的terminal工具运行先adb shell 命令来进行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SK34yrQy-1592041774421)(\blogimgs\terminal.png)]

这样不好的就是我们可能有的操作就要每次设备重启的时候都要手动的敲一遍这样的代码,十分麻烦。那么怎么才能让app启动的时候自己来运行这些命令呢?
一番查资料,终于找到了,主要是使用到了_java.lang.Process_这个类,通过使用Runtime.getRuntime().exec(“su”);这个方法,我们就能获得Process的一个实例,通过这个Process的实例,我们就可以获取命令终端的输入输出流来提交命令和获取命令执行结果啦。

RootCmd工具类

注意:

Runtime.getRuntime().exec("su");

这行代码只能在已经root的设备上才能运行,没有root的设备运行会抛出异常。

下面来看它的具体实现代码吧,我把它封装成了一个工具类:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import android.util.Log;

/**
 * Android运行linux命令
 */
public final class RootCmd {
    private static final String TAG = "RootCmd";
    private static boolean mHaveRoot = false;
    /**
     *   判断机器Android是否已经root,即是否获取root权限
     */
    public static boolean haveRoot() {
        if (!mHaveRoot) {
            int ret = execRootCmdSilent("echo test"); // 通过执行测试命令来检测
            if (ret != -1) {
                Log.i(TAG, "have root!");
                mHaveRoot = true;
            } else {
                Log.i(TAG, "not root!");
            }
        } else {
            Log.i(TAG, "mHaveRoot = true, have root!");
        }
        return mHaveRoot;
    }

    /**
		 * 执行命令并且输出结果
		 */
    public static String execRootCmd(String cmd) {
        String result = "";
        DataOutputStream dos = null;
        DataInputStream dis = null;

        try {
            Process p = Runtime.getRuntime().exec("su");// 经过Root处理的android系统即有su命令
            dos = new DataOutputStream(p.getOutputStream());
            dis = new DataInputStream(p.getInputStream());

            Log.i(TAG, cmd);
            dos.writeBytes(cmd + "\n");
            dos.flush();
            dos.writeBytes("exit\n");
            dos.flush();
            String line = null;
            while ((line = dis.readLine()) != null) {
                Log.d("result", line);
                result += line;
            }
            p.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (dos != null) {
                try {
                    dos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (dis != null) {
                try {
                    dis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    /**
		 * 执行命令但不关注结果输出
		 */
    public static int execRootCmdSilent(String cmd) {
        int result = -1;
        DataOutputStream dos = null;

        try {
            Process p = Runtime.getRuntime().exec("su");
            dos = new DataOutputStream(p.getOutputStream());

            Log.i(TAG, cmd);
            dos.writeBytes(cmd + "\n");
            dos.flush();
            dos.writeBytes("exit\n");
            dos.flush();
            p.waitFor();
            result = p.exitValue();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (dos != null) {
                try {
                    dos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }
}

使用

在app启动的onCreate()方法中,来执行linux命令,注意命令的结尾要加\n才表示执行。

class App : Application() {

    override fun onCreate() {
        super.onCreate()
				//修改/dev/bus/usb/文件夹的权限,注意添加\n
        val commend = "chmod 777 /dev/bus/usb/ -R \n"
        val result = RootCmd.execRootCmd(commend)
    }
}  

结束

亲测以上内容linux的大部分的命令都可以执行,但有一部分命令却执行不了,例如给一块硬盘分区:

运行
127|rk3399_firefly_box:/ # fdisk /dev/sda
输出
sh: fdisk: not found

不知道这是为什么,使用android studio terminal工具也是同样的结果。有知道的也请麻烦解答。

本文出自:http://imaster.top
转载请注明出处

评论 45
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

痕迹丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值