Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Android 在Android代碼中執行命令行,android命令行

Android 在Android代碼中執行命令行,android命令行

編輯:關於android開發

Android 在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();

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved