Run shell commands from android program

2019-02-14 02:58发布

问题:

This question has been asked here before but the solutions provided are not working..I am trying to display the contents of /data/dalvik-cache folder. I know that to do this we need to become su. I even did that but still i am unable to execute a shell command..

package org.linuxconfidg.Example2;

import android.app.Activity;
import android.widget.*;
import android.os.Bundle;
import java.io.*;
public class Example2Activity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String lsreturn=myFunLs();
        TextView tv=new TextView(this);
        tv.setText("Hello Sindhu !! Try to get it \n"+lsreturn);
        setContentView(tv);
    }

    public String myFunLs()
    {

        try {
            // Executes the command.
            Process process;
            process = Runtime.getRuntime().exec("/system/bin/su");
            process = Runtime.getRuntime().exec("/system/bin/ls /data/dalvik-cache > /data/local");
            pr
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(process.getInputStream()));
            int read;
            char[] buffer = new char[4096];
            StringBuffer output = new StringBuffer();
            while ((read = reader.read(buffer)) > 0) {
                output.append(buffer, 0, read);
            }
            reader.close();

            // Waits for the command to finish.
            process.waitFor();

            return output.toString();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

}

Can anyone please help me out in finding out how to run linux commands in android application. I am testing this app in my emulator which is defaultly rooted

回答1:

You can't simply run 'su' on the emulator, there's no root access by default. You'll need to install the 'su' program as well as the SuperUser.apk, and you'll have to do this each time you start the emulator unless using snapshots.

More information and links to the files you need can be found here on SO as well as this blog post by Russell Davis



回答2:

I think the problem comes from the fact that you are using TWO different process instances. You have to be on the su process to carry on sending commands:

You can check the question "Read command output inside su process" for an answer.

Then I tried & managed to make working code (I'm sure it works!)

public void runAsRoot(String[] cmds) throws Exception {
    Process p = Runtime.getRuntime().exec("su");
    DataOutputStream os = new DataOutputStream(p.getOutputStream());
    InputStream is = p.getInputStream();
    for (String tmpCmd : cmds) {
        os.writeBytes(tmpCmd+"\n");
        int readed = 0;
        byte[] buff = new byte[4096];

        // if cmd requires an output
        // due to the blocking behaviour of read(...)
        boolean cmdRequiresAnOutput = true;
        if (cmdRequiresAnOutput) {
            while( is.available() <= 0) {
                try { Thread.sleep(200); } catch(Exception ex) {}
            }

            while( is.available() > 0) {
                readed = is.read(buff);
                if ( readed <= 0 ) break;
                String seg = new String(buff,0,readed);
                console.println("#> "+seg);
            }
        }
    }        
    os.writeBytes("exit\n");
    os.flush();
}


回答3:

In the below example, I try to execute "/system/bin/screencap" to capture android screen.

via adb:

> adb shell
# /system/bin/screencap -p /sdcard/myscreenshot.png

via Android app:

sh = Runtime.getRuntime().exec("su", null,null);
OutputStream os = sh.getOutputStream();
os.write(("/system/bin/screencap -p " + path).getBytes("ASCII"));
os.flush();
os.close();
sh.waitFor();

Hope this helps.