標籤:shell 指令碼 android root
最近做android的一個功能就是調用shell命令來進行一些系統層級的操作,比如說是關機開機之類的,現在總結一下具體的用法以及遇到的坑(基於我所用到的,沒用到的我就不說了)
(1)
Runtime.getRuntime().exec("ls");
這是最簡單的一種,你輸入後就能就會執行ls命令,如果要獲得輸出的話可以這樣寫
Process p = Runtime.getRuntime().exec("ls"); String data = null; BufferedReader ie = new BufferedReader(new InputStreamReader(p.getErrorStream())); BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream())); String error = null; while ((error = ie.readLine()) != null && !error.equals("null")) { data += error + "\n"; } String line = null; while ((line = in.readLine()) != null && !line.equals("null")) { data += line + "\n"; } Log.v("ls", data);
(2)
但是我所要寫的需要通過root許可權來執行,比如說重啟的reboot命令,執行這個的話用普通的身份去執行的話是不會成功的,會報permission denyed,那我們如何才能執行呢,大家都知道adb shell吧,一般root過的機子都能夠通過su來獲得管理員權限,但是沒root過的話就不能了,這就需要把機子進行root了。
root後執行如下命令
Process proc = Runtime.getRuntime().exec(new String[]{"su", reboot});
但是!!!!這個命令貌似不是所有的機子都可以用的,反正我就是遇到這樣的坑,從報錯資訊中可以看到,su和reboot是連起來執行的,所以會解析成su reboot,這樣的話會產生一個問題,su 加上 reboot後reboot會被解析成su的命令參數,我們打一下su -help可以看到su的所有參數,明顯可以看出reboot不能直接跟在su後面,所以後來我發現一種可以啟動並執行命令如下:
Process proc = Runtime.getRuntime().exec(su -c reboot);
這樣機子就能通過root許可權執行重啟命令了。
(3)
但當我們遇到這樣的需求呢!要求啟動並執行shell命令如下
<pre name="code" class="java">Process proc = Runtime.getRuntime().exec(su -c "ls /data");
經過測試,雖然這段代碼中的命令在adb shell中能夠完美運行,但是放到android的java程式中就跪了。。。在android程式中貌似會把/data"當做su的一段參數導致命令一直執行錯誤,無奈,搞了好久能沒能搞出來,於是就改變了實現方法,用第四種方法去實現了。
(4)
第四種方法也是無奈之舉,大家誰有更好的建議歡迎提出。
這種方法就是將所要執行的命令寫成一個shell指令碼,然後,在程式中調用這個shell指令碼,
我把命令寫成shell指令碼放在了手機的目錄中,然後按如下方式調用就成功了。
Process proc = Runtime.getRuntime().exec("su -s sh -c /data/initcommand.sh");
注意,這裡面有和上面相同的問題,如果不加裡面的-c參數的話還是會把後面的檔案當做su的參數,當然-c也可以改成-s,這樣就能執行initcommand.sh指令碼了,如果不行試試將指令碼改成777許可權。
在android程式中調用shell命令與指令碼