編輯:關於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();
Android 設計隨便說說之簡單實踐(合理組合),android隨便說說
Android 設計隨便說說之簡單實踐(合理組合),android隨便說說上一篇(Android 設計隨便說說之簡單實踐(模塊劃分))例舉了應用商店設計來說明怎麼做模塊劃
Stack Overflow 排錯翻譯,stackoverflow
Stack Overflow 排錯翻譯,stackoverflowStack Overflow 排錯翻譯 - Closing AlertDialog.Buil
unity的 斷言 Unity 5.1 Assertion Library
unity的 斷言 Unity 5.1 Assertion Library 當你建立Unity 的手機游戲你最可能渴望設置Script Call Optimization
Android帶頭像的用戶注冊頁面,android用戶注冊
Android帶頭像的用戶注冊頁面,android用戶注冊詳細的圖文可以到我的百度經驗去查看:http://jingyan.baidu.com/article/cd4c2