Android 在Android代码中执行命令行

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";

Android 命令行执行工具类

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:10000
I/auto    ( 5542): run is go to end
I/auto    ( 5542): read ErrorStream over
I/auto    ( 5542): read InputStream over
I/auto    ( 5542): run command process end
I/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();
时间: 2024-08-14 09:59:26

Android 在Android代码中执行命令行的相关文章

python中执行命令行read结果

import os r = os.popen('python -V').read() print(type(r)) print(r) # os.system('python -V') # os.system('tree') 退出进程 size_str = os.popen('adb shell wm size').read() if not size_str: print('请安装 ADB 及驱动并配置环境变量') sys.exit() 原文地址:https://www.cnblogs.com/

[Java][Android][Process] 暴力的服务可以解决一切,暴力的方式执行命令行语句

无论是在Java或者Android中执行命令行语句殊途同归都是创建一个子进程执行调用可执行文件执行命令,类似于Windows中的CMD一样. 此时你有两种方式执行:ProcessBuilder与Runtime:两种创建方式各有千秋,至于区别详见:[Java][Android][Process] ProcessBuilder与Runtime区别 在Android中创建子进程执行命令的时候有着一定的限制: 1.JVM提供的内存有限. 2.底层缓冲区间大小有限. 3.在高并发情况下容易造成阻塞. 基于

[Android] [Java] 分享 Process 执行命令行封装类

在上一篇文章中提到,利用Java创建进程执行命令行语句创建过多后会出现无法创建进程的问题. [Android] ProcessBuilder与Runtime.getRuntime().exec分别创建进程的区别 进行多次测试后发现是因为没有正常退出进程,以及完全读取掉流数据,和关闭流导致的问题. 在多次优化后,建立如下封装类: ProcessModel.java import java.io.BufferedReader; import java.io.IOException; import j

Android中利用命令行进行截屏并导出到电脑上

声明:本博客为原创博客,未经允许,不得转载!原文链接为http://blog.csdn.net/bettarwang/article/details/27819525 大多数人最常用的截屏方法可能就是利用手机的快捷按键了,但是那样如果要导入到电脑中效率会比较低.实际上有更好的截屏方式,最简单的当然就是利用Eclipse中的DDMS进行截屏了,点击"Screen Capture"按钮后等待10多秒,然后就可直接利用Save按钮保存到电脑中. 显然,由于要进行图片显示的原因,在DDMS中会

[转]Windows中的命令行提示符里的Start命令执行路径包含空格时的问题

转自:http://www.x2009.net/articles/windows-command-line-prompt-start-path-space.html 当使用Windows 中的命令行提示符执行这段指令时(测试Start命令执行带空格的路径的程序或文件问题),第一行Start会成功执行,跳出记事本程序,而第二行,会 Start跳出一个新的命令提示符,标题上写着路径,但是不会执行任何命令,第三行Start命令行提示符会提示C:\Program文件不存在,提示无 法执行. start

python系统管理第1章,python中执行命令,python函数,面向对像编程,通过import语句实现代码复用

1.Python中执行命令 例子1: [[email protected] opt]# cat pyls.py  #!/usr/bin/env python #python wrapper for the ls command import subprocess     subprocess.call(["ls","-l"]) 例子2: [[email protected] opt]# cat pysysinfo.py  #!/usr/bin/env python

Android基础:代码中实现界面动态布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView

如何在代码中执行apk安装

import java.io.File; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends Activity { /** Called when th

HDFS中的命令行

HDFS中的命令行 本文介绍了HDFS以命令行执行的时候.几个经常使用的命令行的作用和怎样使用~ 1. fs fs是启动命令行动作,该命令用于提供一系列子命令. 使用形式为hadoop fs –cmd <args> 当中,cmd是子命令,args是详细的命令操作. 比如hadoop fs –help 或者说fs是其余子命令的父亲.其余都是在"-cmd"的模式下的! 2. –cat 输出 hadoop fs –cat URI 将路径指定的文件输出到屏幕 3. –copyFro