EntryNavi : « インストール済みのアプリ(apkファイル)の一覧を取得する方法 | メイン | ApkListUpperをインテントで呼び出す »

CategoryNavi : メイン -> コンピューター -> 開発 -> Java(Android)

自分のアプリをroot権限でコマンドを実行する方法

やっぱこれも今更かもしれませんがメモです。
気にしないでください。

注意(一応ね)
この記事のコードに起因して発生しうるすべての事象に当方は責任を取れません。
すべて自己責任でお願いします。
例えばデバッグ端末が文鎮になったからといって僕はどうにもしてあげられません。


当たり前ですが、ROMはrootになれるようになっててsuコマンドをちゃんとインストール済みな事が前提です。

su使ってrootになった後にどうやったらいいかわからなくていろいろ調べた結果としてそれなりーに簡単に使えるようにしたクラスです。
ただ、suの実装に依存する部分がinitにあるのでどうなんでしょうね。
サンプル
package jp.xii.relog.customlibrary;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.apache.http.protocol.HTTP;

public class DoSuCommand {

	Process _process = null;				//suプロセス
	DataOutputStream _outputStream = null;	//出力ストリーム
	DataInputStream _inputStream = null;	//入力ストリーム
	
	
	public boolean init(){
		boolean ret = false;
		
		try {
			//su実行
			_process = Runtime.getRuntime().exec("su");
			
			//入出力ストリーム取得
			_outputStream = new DataOutputStream(_process.getOutputStream());
			_inputStream = new DataInputStream(_process.getInputStream());
			
			//バージョンを取得する
			if(!write("su -v\n")){
			}else{
				String[] results = read().split("\n");
				for (String line : results) {
					if(line.length() > 0){
						//バージョンがとれたので成功
						ret = true;
					}
				}
			}
		} catch (IOException e) {
		}
		
		return ret;
	}
	
	public void deinit(){
		if(_inputStream != null){
			try {
				_inputStream.close();
			} catch (IOException e) {
			}
		}
		if(_outputStream != null){
			try {
				if(_process != null){
					//プロセスと出力ストリームがある場合は
					//シェルを終了する
					_outputStream.writeBytes("exit\n");
					_outputStream.flush();
					try {
						//シェルの終了を待つ
						_process.waitFor();
					} catch (InterruptedException e) {
					}
				}
				_outputStream.close();
			} catch (IOException e) {
			}
		}
		
		if(_process != null){
			_process.destroy();
		}
		
		_outputStream = null;
		_inputStream = null;
		_process = null;
	}
	
	/**
	 * コマンドをsuシェルへ投げる
	 * 最後に\nを付けるまで実行されない
	 * @param command
	 */
	public boolean write(String command){
		boolean ret = false;
		if(_outputStream == null){
		}else{
			try {
				_outputStream.writeBytes(command);
				_outputStream.flush();
				ret = true;
			} catch (IOException e) {
			}
		}
		return ret;
	}
	
	/**
	 * suシェルの出力を文字列にする
	 * かならず結果が戻ってくる時に使う
	 * それ以外で使うともどってこなくなるので注意
	 * もちろん結果は標準出力でエラー出力はダメ
	 * コマンドの結果が複数行になる場合は
	 * splitなどを使ってバラして使う
	 * @return
	 */
	public String read(){
		String ret = "";
		
		if(_inputStream == null){
		}else{
			int size = 0;
			byte[] buffer = new byte[1024];
			
			try {
				do {
					size = _inputStream.read(buffer);
					if(size > 0){
						ret += new String(buffer, 0, size, HTTP.UTF_8);
					}
				}while(_inputStream.available() > 0);
			} catch (IOException e) {
			}
		}

		return ret;
	}
}


単発コマンドでよければこの方法でもいいのですがSuperuserってアプリには履歴としてコマンドがもろ視えるのでどうなんでしょうね。
	String[] command = {"su", "-c", "hogehoge command"};
	Process p = Runtime.getRuntime().exec(command);
	p.waitFor();



<Category : Java(Android)>

検索

Google

サイドフィード

track feed 理ろぐ
人気ブログランキング - 理ろぐ
Powered by
Movable Type 3.34