Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
315 views
in Technique[技术] by (71.8m points)

android - Execute shell commands and get output in a TextView

I want to execute some shell commands and get the output in a TextView. The command may have a continuous output like ping or logcat. Also, the TextView should scroll automatically as the command output is added in real-time. In order to do so, I have done this:

package com.example.rootapp;

import java.io.DataOutputStream;
import java.io.InputStream;

import android.app.Activity;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.widget.TextView;

public class MainActivity extends Activity {
    TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String[] cmdArray={"logcat -b radio"};
        try {
            runAsRoot(cmdArray);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void runAsRoot(String[] cmds) throws Exception {
        tv=(TextView)findViewById(R.id.cmdOp);
        tv.setMovementMethod(new ScrollingMovementMethod());
        Process p = Runtime.getRuntime().exec("su");
        DataOutputStream os = new DataOutputStream(p.getOutputStream());
        InputStream is = p.getInputStream();
        for (String tmpCmd : cmds) {
            os.writeBytes(tmpCmd+"
");
            int readed = 0;
            byte[] buff = new byte[4096];
            boolean cmdRequiresAnOutput = true;
            if (cmdRequiresAnOutput) {
                while( is.available() <= 0) {
                    try { Thread.sleep(5000); } catch(Exception ex) {}
                }

                while( is.available() > 0) {
                    readed = is.read(buff);
                    if ( readed <= 0 ) break;
                    String seg = new String(buff,0,readed);   
                    tv.append(seg);
                }
            }
        }        
    }
}

This works fine, but it does not update the TextView continuously. As you can see, I'm executing radio logcat as root user, the output is generated continuously (already checked in terminal emulator and adb shell). But in my case, the output is not added continuously. It stops after a few 100 lines. Here is my layout:

    <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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/cmdOp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="bottom"
        android:text="@string/hello_world" />
</ScrollView>

</RelativeLayout>

The output should keep scrolling the TextView. At least this is what I expect...... Any workaround for this please?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can run command and display command output into text as below :

public class MainActivity extends Activity {

    TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv=(TextView)findViewById(R.id.cmdOp);
        tv.setText("Output :"+"
"+runAsRoot());
    }

    public String runAsRoot() {

        try {
            // Executes the command.
            Process process = Runtime.getRuntime().exec("ls -l");

            // Reads stdout.
            // NOTE: You can write to stdin of the command using
            //       process.getOutputStream().
            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);
        }
    }
}

Note : The "su" command does only run if the device is rooted. Otherwise it throws an exception.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...