Building a Terminal Emulator for Android

有些话、适合烂在心里 提交于 2019-12-22 13:54:06

问题


I've been trying to build a Terminal Emulator for Android. Being pretty new to this, my idea was to execute each command and store the output in a file, whose contents would be displayed after each execution. Pseudo Code :

public Boolean execCommands(String command) {
        try {
            rt = Runtime.getRuntime();
            process = rt.exec("su");
            DataOutputStream os = new DataOutputStream(process.getOutputStream());
            os.writeBytes("echo $ \""+command+ "\" >> /sdcard/Android/data/terminalemulatorlog.txt\n\n\n"); 
            /**** Note :  String command = (EditText)findViewById(R.id.command).getText().toString(); ****/
            os.flush();
            os.writeBytes("exit\n");
            os.flush();
            process.waitFor();
            }
        // Error Handling
        displayOutput(); //Loads and displays the Text File (/sdcard/Android/data/terminalemulatorlog.txt)
        return true;
        }

This piece of code works except for a few special commands (Eg. 'clear'). But what I'm more concerned about are the following problems :

  1. Each time a command is to be executed, I end up seeking SuperUser permissions (second line of code). And I'd like to do away with this.
  2. In cases when the user enters one command followed by another,
    Such as :

    cd /sdcard    
    touch File.txt    
    

    The File.txt is created in '/' and not in '/sdcard'. As of now to avoid this, I'm keeping a track of all the 'cd' commands to figure out what the present working directory is. And I'm hoping that there is a better way around this.

I'd be grateful if someone could help me out here.


回答1:


Not sure if you are still needing this or not, but here is how I am issuing multiple commands at one time and not using "su" to have them run.

try {
    String[] commands = {           
            "dumpstate > /sdcard/LogFiles/dumpstate.txt",
            "dumpsys > /sdcard/LogFiles/dumpsys.txt",
            "logcat -d > /sdcard/LogFiles/log.txt",
            "cat /sdcard/LogFiles/dumpstate.txt /sdcard/LogFiles/dumpsys.txt /sdcard/LogFiles/log.txt > /sdcard/LogFiles/bugreport.rtf" };
    Process p = Runtime.getRuntime().exec("/system/bin/sh -");
    DataOutputStream os = new DataOutputStream(p.getOutputStream());
    for (String tmpCmd : commands) {
        os.writeBytes(tmpCmd + "\n");
    }
} catch (IOException e) {
    e.printStackTrace();
}



回答2:


This a bit late but here a few ways of doing this.

1)

Instead of using su as a starting point use /system/bin/sh.

and after calling

rt.exec("/system/bin/sh");

You should hold onto the Output Stream and Input Stream to give further commands.

After you issued a command you should echo a magic line like "---EOF---" and stop reading input after reading that line. If you don't have this you'll end up with the read function from the InputStream blocking.

2) Pipe the data to a native process you've written that simply moves the data on to your Android Application with a terminating character or string attached to the end.

I am not entirely sure how to do this, but it is essentially the same as the previous method just relies on you native application as a middle man.

This will get you close to a functioning "Terminal Emulator".

3)If you wan't a true Ternimal Emulator then there's no other way to do it than : using a native application that opens a connection to a psuedoterminal.

Here's some basic information of how to open a pty : link

Terminal Emulator is a open source project that uses this technique.

Have a look here



来源:https://stackoverflow.com/questions/8673016/building-a-terminal-emulator-for-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!