Androidアプリケーション実行shell命令(root命令の実行を含む)

14434 ワード

プロジェクトはandroidのアプリケーションで事前に携帯電話に入れたプログラムを動的に実行する必要があるため、あちこちで多くの資料を探しています.ネット上にはいろいろなものがありますが、多少は足りないと感じて、半日振り回してやっと満足して、全体の過程を記録しました.su命令を実行するには、携帯電話rootを要求する必要があります.
関連クラス
  • 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
    
    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ドキュメントにDataOutputStreamInputStreamが書かれていることです.
  • 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