zoukankan      html  css  js  c++  java
  • 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("
    ");
                os.flush();
    
                os.writeBytes("exit
    ");
                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 += "
    ";
                                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 += "
    ";
                                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();
  • 相关阅读:
    封装成帧、帧定界、帧同步、透明传输(字符计数法、字符串的首尾填充法、零比特填充的首尾标志法、违规编码法)
    计算机网络之数据链路层的基本概念和功能概述
    物理层设备(中继器、集线器)
    计算机网络之传输介质(双绞线、同轴电缆、光纤、无线电缆、微波、激光、红外线)
    计算机网络之编码与调制
    0953. Verifying an Alien Dictionary (E)
    1704. Determine if String Halves Are Alike (E)
    1551. Minimum Operations to Make Array Equal (M)
    0775. Global and Local Inversions (M)
    0622. Design Circular Queue (M)
  • 原文地址:https://www.cnblogs.com/lipeineng/p/6078859.html
Copyright © 2011-2022 走看看