【问题标题】:Any way to run shell commands on android programmatically?任何方式以编程方式在android上运行shell命令?
【发布时间】:2011-03-21 23:40:51
【问题描述】:

有什么方法可以在我的应用程序上运行终端命令,然后访问我的 UI 上的数据?特别是top

【问题讨论】:

    标签: android linux


    【解决方案1】:

    以日志收集器为例。这是relevant file

    关键在这里:

    ArrayList<String> commandLine = new ArrayList<String>();
    commandLine.add("logcat");//$NON-NLS-1$
    [...]
    
    Process process = Runtime.getRuntime().exec(commandLine);
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
    

    【讨论】:

    • 所以基本上如果我想运行top,我可以用top替换commandLine,它应该可以正常工作吗?我遇到了一个错误,所以我想我需要更多帮助..谢谢..
    • 是否需要包围Process process = Runtime.getRuntime().exec(commandLine);尝试并抓住,因为我不断得到这个抛出 IOException。我看过java示例似乎是这样处理的......
    • 是的.. 再次查看链接以查看他们所做的一切。您肯定需要进行错误检查 - 不要期望所有手机上都有“top”。
    • 这个现在被谷歌禁止了
    【解决方案2】:

    好吧,这正是对我有用的东西,以防万一将来有人需要它... :)

    包围在尝试和捕捉中

    try {
        Process process = Runtime.getRuntime().exec("top -n 1 -d 1");
        BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    

    【讨论】:

    • 当我这样做后跟 String result = null;结果 = bufferedReader.readLine(); Log.i("OnClickListener", "result:" + result);它仅显示“结果:”(“结果”字符串为空)。关于为什么会这样的任何想法?另外,当我尝试 process = Runtime.getRuntime().exec("/system/bin/ping abc");相反,“结果”字符串为空。这两个命令都可以从“adb shell”终端按预期工作。
    • 对不起@DavidDoria,我已经两年没碰过安卓了。这是我在大学时尝试过的事情。您最好将其作为问题发布。
    • 我搞定了。问题是“顶部”的第一行是空的(一个新行,用于创建表)。它在实际输出时返回 null 的情况是因为我需要获取 stderror (getErrorStream) 而不是 stdout (getInputStream)。
    【解决方案3】:

    我们,可以执行如下命令,我成功了……!像这样尝试,这里我们需要指定命令的完整路径。获取命令的完整路径,在你的终端(android)输入

    *$ 哪一个

    /system/bin*

    try {
    
        // Executes the command.
    
        Process process = Runtime.getRuntime().exec("/system/bin/ls /sdcard");
    
        // 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);
    }
    

    【讨论】:

      【解决方案4】:

      这还取决于您在终端中运行的内容...如果您在文件上运行“cat”,您也可以这样做。

      final private String MEM_FILE = "/proc/meminfo";
      
      public Long readMem() {
          String[] segs;
          FileReader fstream;
          try {
              fstream = new FileReader(MEM_FILE);
          } catch (FileNotFoundException e) {
              Log.e("readMem", "Could not read " + MEM_FILE);
              return false;
          }
          BufferedReader in = new BufferedReader(fstream, 500);
          String line;
          try {
              while ((line = in.readLine()) != null) {
                  if (line.indexOf("MemTotal:") > 0) {
                      Log.e("MemTotal", line);
                      segs = line.trim().split("[ ]+");
                      memTotal = Long.parseLong(segs[1]);
                  }
                  if (line.indexOf("MemFree:") > 0) {
                      Log.e("MemFree", line);
                      segs = line.trim().split("[ ]+");
                      memFree = Long.parseLong(segs[1]);
                  }
              }
              updateMem(); //call function to update textviews or whatever
              return true;
          } catch (IOException e) {
              Log.e("readMem", e.toString());
          }
          return false;
      }
      

      编辑: 在名为 netmeter 的 android 实验室项目中有一个完美的例子。有一个名为 Top.java 的类实际上完全符合您的要求,并且在 TaskList.java 中使用它来显示。 http://code.google.com/p/android-labs/source/browse/#svn/trunk/NetMeter/src/com/google/android/netmeter

      【讨论】:

      • 不是猫,我特别想运行 top 并在屏幕上显示实时结果。我知道一些应用程序模拟了我发现 top 工作的终端,所以我想知道如何才能拉出 top 的结果并将它们显示在 UI 上。
      • 查看我上面的编辑,了解您想要的工作示例。
      • 嘿,谢谢...需要在这里花一些时间,但我认为就是这样...您帮了大忙!
      • line.indexOf 应该是 &gt; -1 而不是 &gt; 0。 -1 表示未找到
      【解决方案5】:

      对于Kotlin爱好者,可以使用以下

      fun executeShell() {
          val command: String = "top -n 1"
          try {
              val process: Process = Runtime.getRuntime().exec(command)
              // Read the lines using BufferedReader
              BufferedReader(InputStreamReader(process.inputStream)).forEachLine {
                  // Do something on each line read
                  Log.d(this::class.java.canonicalName, "$it")
              }
          } catch (e: InterruptedException) {
              Log.w(this::class.java.canonicalName, "Cannot execute command [$command].", e)
          } catch (e: Exception) {
              Log.e(this::class.java.canonicalName, "Cannot execute command [$command].", e)
          }
      }
      

      您甚至不必处理关闭缓冲区,因为 forEachLine 扩展函数会处理它。

      【讨论】:

        猜你喜欢
        • 2013-01-26
        • 1970-01-01
        • 2020-10-21
        • 2019-05-07
        • 1970-01-01
        • 2014-05-17
        • 1970-01-01
        • 2013-08-14
        • 1970-01-01
        相关资源
        最近更新 更多