轉自:
Android應用程序如何調用shell腳本(一)
一般來說, Android 下的應用程序可以“直接”得到的最大的權限為 system ,但是如果我們需要在程序中執行某些需要 root 權限的命令,就需要 root 權限了。按照 Simon 的文章中提到的,應用程序有以下兩種辦法臨時獲得 root 權限:
1) 在 init.rc 實現一個 Service ,來幫助 Android 應用程序執行 root 權限的命令。
2) 實現一個虛擬設備,這個設備幫助 Android 應用程序執行 root 權限的命令。
第二種辦法我這里沒有嘗試過。只介紹第一種方法。
1. 編寫shell腳本或者可執行程序
下面是我的腳本cp_file.sh:
#! /system/bin/sh
cat /mnt/sdcard/launcher.db > /data/data/com.android.launcher/databases/launcher.db
chown system.system /data/ data/com.android.launcher/databases/launcher.db
chmod 600 /data/ data/com.android.launcher/databases/launcher.db
注意: 腳本的第一行必須為 # ! /system/bin/sh ,否則無法執行。
2. 在init.rc中注冊service
service file_cp /system/bin/cp_file.sh
user root
oneshot
disabled
其中, oneshot 表示程序退出后不再重新啟動, disabled 表示不在系統啟動時啟動。
Service中參數的含義參見其它文章。
3. 將應用程序的權限提升至system
1.在應用程序的AndroidManifest.xml中的manifest節點中加入android:sharedUserId="android.uid.system"這個屬性。
2.使用mm命令來編譯該應用程序,生成的apk就具有system權限了。
4. 在應用程序中添加屬性設置代碼:
A. 在應用程序中使用getruntime().exec()函數來執行shell腳本文件。參考代碼如下:
package cycle.settings.system;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import android.util.Log;
public class RuntimeExec {
private static final String TAG = "RuntimeExec";
private static final boolean DEBUG = true;//TODO: close this flag
private Process proc;
private StreamGobbler outputGobbler = null;
private StreamGobbler errorGobbler = null;
static class StreamGobbler extends Thread{
InputStream is;
String type; //輸出流的類型ERROR或OUTPUT
public StreamGobbler(InputStream is, String type) {
// TODO Auto-generated constructor stub
this.is = is;
this.type = type;
}
public void run(){
try {
if(DEBUG)Log.d(TAG, "StreamGobbler start");
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while((line = br.readLine()) != null){
System.out.println(type+">"+line);
System.out.flush();
}
if(DEBUG)Log.d(TAG, "StreamGobbler end");
} catch (IOException e) {
// TODO Auto-generated catch block
if(DEBUG)Log.d(TAG, "StreamGobbler exception");
e.printStackTrace();
}
}
}
/**
*
* @param cmd : the command
* @return success or failure
*/
public boolean runtimeExec(String cmd){
if(DEBUG)Log.d(TAG, "runtimeExec start");
boolean mboolean = false;
try {
if(DEBUG)Log.d(TAG, "runtimeExec start1");
Runtime mRuntime = Runtime.getRuntime();
proc = mRuntime.exec(cmd);
//any output message
StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(),"OUTPUT");
//any error message
StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR");
//kick them off
outputGobbler.start();
//kick them off
errorGobbler.start();
int exitVal = proc.waitFor();
if(DEBUG)Log.d(TAG, "process exitValue: "+exitVal);
mboolean = (proc.waitFor()== 0);
} catch (Throwable e) {
// TODO Auto-generated catch block
if(DEBUG)Log.d(TAG, "process exception");
e.printStackTrace();
}
return mboolean;
}
public void runtimeEND(){
if(DEBUG)Log.d(TAG, "runtimeEND start");
try {
if(proc != null){
if(DEBUG)Log.d(TAG, "runtimeEND start1");
proc.getOutputStream().close();
if(DEBUG)Log.d(TAG, "close getOutputStream finish");
proc.getErrorStream().close();
if(DEBUG)Log.d(TAG, "close getErrorStream finish");
proc.destroy();
if(DEBUG)Log.d(TAG, "proc has destory");
}
else{
if(DEBUG)Log.e(TAG, "proc is null!!!!!");
}
if(DEBUG)Log.e(TAG, "before System.exit(0);");
System.exit(0);
if(DEBUG)Log.e(TAG, "after System.exit(0);");
proc = null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
未完,待續部分參考下篇博文。
參考博文:http://blog.csdn.net/silvervi/article/details/6315888