Androidアプリケーション実行shell命令(root命令の実行を含む)
14434 ワード
プロジェクトはandroidのアプリケーションで事前に携帯電話に入れたプログラムを動的に実行する必要があるため、あちこちで多くの資料を探しています.ネット上にはいろいろなものがありますが、多少は足りないと感じて、半日振り回してやっと満足して、全体の過程を記録しました.
関連クラス Process 関連ドキュメント:http://www.android-doc.com/reference/java/lang/Process.html
Runtime 関連ドキュメント:http://www.android-doc.com/reference/java/lang/Runtime.html
テストエンジニアリングコード
コード機能
su権限を取得し、コマンド「ls/data/data」を実行します(/data/dataにアクセスするにはrootが必要です)
MainActivity.java
activitymain.xml
コード解釈説明
レイアウトファイルは言うまでもなく、簡単なレイアウトです.
コアコードは
ここでは、 InputStream
public abstract InputStream getInputStream () Returns an input stream that is connected to the standard output stream (stdout) of the native process represented by this object. Returns the input stream to read from the output stream associated with the native process.
DataOutputStream
public abstract OutputStream getOutputStream () Returns an output stream that is connected to the standard input stream (stdin) of the native process represented by this object. Returns the output stream to write to the input stream associated with the native process.
率直に言えば、shellのstdinとstdoutを取得したので、私たちが直接読み書きするのはshellに関連するコマンドを入力し、対の出力結果を取得することに相当します.
いくつかの参考記事
以下は一部がネットで資料を調べたときに見たもので、記録する権利があります.http://www.android-doc.com/reference/java/lang/Process.html http://www.cnblogs.com/ycmoon/archive/2011/05/11/2042999.html?login=1 http://blog.csdn.net/y13872888163/article/details/6530430 http://www.open-open.com/lib/view/open1409190296025.html
su
命令を実行するには、携帯電話rootを要求する必要があります.関連クラス
テストエンジニアリングコード
コード機能
su権限を取得し、コマンド「ls/data/data」を実行します(/data/dataにアクセスするにはrootが必要です)
MainActivity.java
import android.app.Activity;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class MainActivity extends Activity {
private final static String[] ARGS={"ls","-l"};
private final static String TAG="com.dd.test";
Button mButton,rButton,cButton;
TextView myTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton= (Button) findViewById(R.id.myButton);
cButton = (Button) findViewById(R.id.clearB);
myTextView= (TextView) findViewById(R.id.textView);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myTextView.setText(getResult());
}
});
cButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myTextView.setText("hello world");
}
});
}
public String getResult(){
ShellExecute cmdexe=new ShellExecute();
String result="";
try{
result=cmdexe.execute(ARGS,"/data/data/");
}catch (Exception e){
Log.e(TAG,"IOEXCEPTION");
e.printStackTrace();
}
return result;
}
private class ShellExecute{
public String execute (String[] command,String directory) throws IOException{
String result="";
String[] suC={"su"};
try{
ProcessBuilder builder= new ProcessBuilder(suC);
if (directory!=null)
builder.directory(new File(directory));
builder.redirectErrorStream(true);
Process process=builder.start();
DataOutputStream os;
os=new DataOutputStream(process.getOutputStream());
InputStream is= process.getInputStream();
os.writeBytes( "ls
");
os.flush();
os.close();
byte[] buffer=new byte[1024];
while (is.read(buffer)!=-1){
result=result+new String(buffer);
}
is.close();
}catch (Exception e){
e.printStackTrace();
}
return result;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
activitymain.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="click"
android:id="@+id/myButton"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="clear"
android:id="@+id/clearB"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text..."
android:id="@+id/textView"
/>
LinearLayout>
RelativeLayout>
コード解釈説明
レイアウトファイルは言うまでもなく、簡単なレイアウトです.
コアコードは
private class ShellExecute{
public String execute (String[] command,String directory) throws IOException{
String result="";
String[] suC={"su"};
try{
ProcessBuilder builder= new ProcessBuilder(suC);
if (directory!=null)
builder.directory(new File(directory));
builder.redirectErrorStream(true);
Process process=builder.start();
DataOutputStream os;
os=new DataOutputStream(process.getOutputStream());
InputStream is= process.getInputStream();
os.writeBytes( "ls
");
os.flush();
os.close();
byte[] buffer=new byte[1024];
while (is.read(buffer)!=-1){
result=result+new String(buffer);
}
is.close();
}catch (Exception e){
e.printStackTrace();
}
return result;
}
}
ここでは、
su
という命令をパラメータとしてProcessBuilderに入力し、start()
メソッドを呼び出してprocessを取得する.ここで、adb shellでsu
の命令が実行されたことに相当する.実際のアプリケーションの実行中に、「アプリケーションはroot権限を取得する必要があります」というメッセージが表示されます.次に重要なのは、androidドキュメントにDataOutputStream
とInputStream
が書かれていることです.public abstract InputStream getInputStream () Returns an input stream that is connected to the standard output stream (stdout) of the native process represented by this object. Returns the input stream to read from the output stream associated with the native process.
public abstract OutputStream getOutputStream () Returns an output stream that is connected to the standard input stream (stdin) of the native process represented by this object. Returns the output stream to write to the input stream associated with the native process.
率直に言えば、shellのstdinとstdoutを取得したので、私たちが直接読み書きするのはshellに関連するコマンドを入力し、対の出力結果を取得することに相当します.
いくつかの参考記事
以下は一部がネットで資料を調べたときに見たもので、記録する権利があります.http://www.android-doc.com/reference/java/lang/Process.html http://www.cnblogs.com/ycmoon/archive/2011/05/11/2042999.html?login=1 http://blog.csdn.net/y13872888163/article/details/6530430 http://www.open-open.com/lib/view/open1409190296025.html