博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 在Android代码中执行命令行
阅读量:6975 次
发布时间:2019-06-27

本文共 8413 字,大约阅读时间需要 28 分钟。

1.路径最好不要是自己拼写的路径/mnt/shell/emulated/0/wifidog.conf

最好是通过方法获取的路径,不然可能导致命令无效  (挂载点的原因)

public static final String SDCARD_ROOT=Environment.getExternalStorageDirectory().getAbsolutePath(); 

public static final String AAA_PATH=SDCARD_ROOT+"/wifidog.conf";

 

package com.example.videotest.utils;import android.os.Environment;import android.util.Log;import java.io.BufferedReader;import java.io.DataOutputStream;import java.io.InputStreamReader;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock;import static java.lang.Runtime.getRuntime;/** * 执行命令的类 * Created by Kappa */public class ExeCommand {    //shell进程    private Process process;    //对应进程的3个流    private BufferedReader successResult;    private BufferedReader errorResult;    private DataOutputStream os;    //是否同步,true:run会一直阻塞至完成或超时。false:run会立刻返回    private boolean bSynchronous;    //表示shell进程是否还在运行    private boolean bRunning = false;    //同步锁    ReadWriteLock lock = new ReentrantReadWriteLock();    //保存执行结果    private StringBuffer result = new StringBuffer();    /**     * 构造函数     *     * @param synchronous true:同步,false:异步     */    public ExeCommand(boolean synchronous) {        bSynchronous = synchronous;    }    /**     * 默认构造函数,默认是同步执行     */    public ExeCommand() {        bSynchronous = true;    }    /**     * 还没开始执行,和已经执行完成 这两种情况都返回false     *     * @return 是否正在执行     */    public boolean isRunning() {        return bRunning;    }    /**     * @return 返回执行结果     */    public String getResult() {        Lock readLock = lock.readLock();        readLock.lock();        try {            Log.i("auto", "getResult");            return new String(result);        } finally {            readLock.unlock();        }    }    /**     * 执行命令     *     * @param command eg: cat /sdcard/test.txt      * 路径最好不要是自己拼写的路径,最好是通过方法获取的路径      * example:Environment.getExternalStorageDirectory()     * @param maxTime 最大等待时间 (ms)     * @return this     */    public ExeCommand run(String command, final int maxTime) {        Log.i("auto", "run command:" + command + ",maxtime:" + maxTime);        if (command == null || command.length() == 0) {            return this;        }        try {            process = getRuntime().exec("sh");//看情况可能是su        } catch (Exception e) {            return this;        }        bRunning = true;        successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));        errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));        os = new DataOutputStream(process.getOutputStream());        try {            //向sh写入要执行的命令            os.write(command.getBytes());            os.writeBytes("\n");            os.flush();            os.writeBytes("exit\n");            os.flush();            os.close();            //如果等待时间设置为非正,就不开启超时关闭功能            if (maxTime > 0) {                //超时就关闭进程                new Thread(new Runnable() {                    @Override                    public void run() {                        try {                            Thread.sleep(maxTime);                        } catch (Exception e) {                        }                        try {                            int ret = process.exitValue();                            Log.i("auto", "exitValue Stream over"+ret);                        } catch (IllegalThreadStateException e) {                            Log.i("auto", "take maxTime,forced to destroy process");                            process.destroy();                        }                     }                }).start();            }            //开一个线程来处理input流            final Thread t1 = new Thread(new Runnable() {                @Override                public void run() {                    String line;                    Lock writeLock = lock.writeLock();                    try {                        while ((line = successResult.readLine()) != null) {                            line += "\n";                            writeLock.lock();                            result.append(line);                            writeLock.unlock();                        }                    } catch (Exception e) {                        Log.i("auto", "read InputStream exception:" + e.toString());                    } finally {                        try {                            successResult.close();                            Log.i("auto", "read InputStream over");                        } catch (Exception e) {                            Log.i("auto", "close InputStream exception:" + e.toString());                        }                    }                }            });            t1.start();            //开一个线程来处理error流            final Thread t2 = new Thread(new Runnable() {                @Override                public void run() {                    String line;                    Lock writeLock = lock.writeLock();                    try {                        while ((line = errorResult.readLine()) != null) {                            line += "\n";                            writeLock.lock();                            result.append(line);                            writeLock.unlock();                        }                    } catch (Exception e) {                        Log.i("auto", "read ErrorStream exception:" + e.toString());                    } finally {                        try {                            errorResult.close();                            Log.i("auto", "read ErrorStream over");                        } catch (Exception e) {                            Log.i("auto", "read ErrorStream exception:" + e.toString());                        }                    }                }            });            t2.start();            Thread t3 = new Thread(new Runnable() {                @Override                public void run() {                    try {                        //等待执行完毕                        t1.join();                        t2.join();                        process.waitFor();                    } catch (Exception e) {                    } finally {                        bRunning = false;                        Log.i("auto", "run command process end");                    }                }            });            t3.start();            if (bSynchronous) {                Log.i("auto", "run is go to end");                t3.join();                Log.i("auto", "run is end");            }        } catch (Exception e) {            Log.i("auto", "run command process exception:" + e.toString());        }        return this;    }}

讲解一下关键点,首先是启动一个sh进程,当然如果你用的是root的设备,可以使用su。

这个进程包含 input、output、error 三个流,这三个流要处理好,否则可能不能正常结束进程,

另外也存在执行的命令已经结束,但是依然还有input流的情况,也需要处理。

其他请参考代码

 

使用方式为2种。首先是阻塞方式,这种调用方式会一直阻塞至命令执行完成,返回命令行的输出结果

public static final String SDCARD_ROOT=Environment.getExternalStorageDirectory().getAbsolutePath();                     public static final String AAA_PATH=SDCARD_ROOT+"/wifidog.conf";//读取目标文件(绝对路径)指定内容“#TrustedMACList ”的那一行String cmd3="sed -n '/#TrustedMACList /,//p' "+AAA_PATH;String str3 = new ExeCommand().run(cmd3, 10000).getResult();Log.i("auto", str3+"button3");Toast.makeText(MainActivity.this, str3,Toast.LENGTH_SHORT).show();

LOG   程序执行的顺序

I/auto    ( 5542): run command:sed -n '/#TrustedMACList /,//p' /storage/emulated/0/wifidog.conf,maxtime:10000I/auto    ( 5542): run is go to endI/auto    ( 5542): read ErrorStream overI/auto    ( 5542): read InputStream overI/auto    ( 5542): run command process endI/auto    ( 5542): run is end I/auto ( 5542): getResult I/auto ( 5542): #TrustedMACList 00:00:C0:1D:F0:0D,00:00:C0:1D:F0:0D,00:00:C0:1D:F0:0D,00:00:C0:1D:F0:0D,00:00:C0:1D:F0:0D,00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D I/auto ( 5542): I/auto ( 5542): button3

 

 

 

还有一种是异步方式,这种调用方式会直接返回,之后可以使用 getResult() 获取结果,使用 isRunning() 来判断是否完成,比如

ExeCommand cmd = new ExeCommand(false).run("your cmd", 60000);    while(cmd.isRunning())    {        try {            sleep(1000);        } catch (Exception e) {        }        String buf = cmd.getResult();        //do something    }

 

 

 

 

 

 

 

//修改目标文件指定内容“#TrustedMACList ” String cmd="sed -i 's/#TrustedMACList /#TrustedMACList 00:00:C0:1D:F0:0D,/g' "+AAA_PATH;String str = new ExeCommand().run(cmd, 10000).getResult();Log.i("auto", str+"button4");Toast.makeText(MainActivity.this, str,Toast.LENGTH_SHORT).show();

 

转载于:https://www.cnblogs.com/lipeineng/p/6078859.html

你可能感兴趣的文章
5.24
查看>>
DateUtil(2)
查看>>
文件的读取和写出
查看>>
Objective-C Runtime 运行时之三:方法与消息
查看>>
Vijos P1304 回文数【回文+进制】
查看>>
POJ NOI MATH-7826 分苹果
查看>>
内存可见性和原子性:Synchronized和Volatile的比较
查看>>
BAT三家互联网公司哪家更注重用户体验?
查看>>
php-fpm重启失败报错
查看>>
【深入篇】Andorid中常用的控件及属性
查看>>
面向对象的三大特性之二:多态、多态性
查看>>
web缓存概述
查看>>
二、安装桌面——Linux学习笔记
查看>>
GCD XOR uvalive6657
查看>>
几个月前关于AI整理的一张思维导图
查看>>
springboot学习
查看>>
POJ 3974 Palindrome(最长回文子串)
查看>>
as3 区别中文 英文 数字
查看>>
留言本,keyCode
查看>>
链表常用操作
查看>>