The first thing you should do is to log the stderr stream that is available for your process as well. This will give you information about what is wrong with your command.

Your command is not correctly processed as it is seen as one command. The reason is explained in this answer.

The solution is to use a String[] as an argument of exec and explicitly execute the command with the shell. I wrote some code that executes your command, but it is in Java on an unrooted device. Still, it generates output and grep works.

String[] arrayCommand = {"sh", "-c","dumpsys telephony.registry | grep \"permission\""};
            
Runtime r = Runtime.getRuntime();
Process process = r.exec(arrayCommand);

String stdoutString = convertInputStreamToString(process.getInputStream());
String stderrString = convertInputStreamToString(process.getErrorStream());
Answer from JANO on Stack Overflow
🌐
Android Developers
developer.android.com › api reference › runtime
Runtime | API reference | Android Developers
Skip to main content · English · Deutsch · Español – América Latina · Français · Indonesia · Polski · Português – Brasil · Tiếng Việt · 中文 – 简体
🌐
Stack Overflow
stackoverflow.com › questions › 64017722 › java-android-runtime-getruntime-exec
Java Android Runtime.getRuntime().exec() - Stack Overflow
I'm working on an app where I want to run an android shell command using: Process process = Runtime.getRuntime().exec("input keyevent 85"); This should start/stop the music player for me, and it works when I'm currently on my app. The way I do it is to set a prepared intent beforehand at a certain time, so I can have the music playing in a few minutes.
🌐
Stack Overflow
stackoverflow.com › questions › 22244143 › how-to-use-runtime-getruntime-execcmd-for-a-long-command-separated-by
android - How to use Runtime.getRuntime().exec(cmd) for a long command separated by ; - Stack Overflow
private void call( String cmd) { Process ans_call; InputStreamReader cmd_reader; BufferedReader cmd_bufferedReader; String line = null; try { sendMainUIMessage(MSG_KPI_UI_UPDATE_REQUEST, null, cmd); mLogWriter.writeDiagnoseLog(cmd); ans_call = Runtime.getRuntime().exec(cmd); NotifyRunning(ans_call); cmd_reader = new InputStreamReader(ans_call.getInputStream()); cmd_bufferedReader = new BufferedReader(cmd_reader); while (((line = cmd_bufferedReader.readLine()) != null)) { sendMainUIMessage(MSG_KPI_UI_UPDATE_REQUEST, null, line + "\n"); mLogWriter.writeDiagnoseLog(line); } //end of while ans_call.waitFor(); NotifyEnd(ans_call); cmd_reader.close(); cmd_bufferedReader.close(); } catch (IOException e) { Log.e(TAG, "Could not write file " + e.getMessage()); } catch (InterruptedException e) { Log.e(TAG, "Ping test Fail: InterruptedException"); } //end of try }
🌐
Google Support
support.google.com › android › thread › 46167428
Cannot start binary using Runtime.getRuntime().exec() - Android Community
May 12, 2020 - Skip to main content · Android Help · Sign in · Google Help · Help Center · Community · Android · Terms of Service · Submit feedback · Send feedback on
Top answer
1 of 4
11

Android java.lang.Process implementation is java.lang.ProcessManager$ProcessImpl and it has field private final int pid;. It can be get from Reflection:

public static int getPid(Process p) {
    int pid = -1;

    try {
        Field f = p.getClass().getDeclaredField("pid");
        f.setAccessible(true);
        pid = f.getInt(p);
        f.setAccessible(false);
    } catch (Throwable e) {
        pid = -1;
    }
    return pid;
}

Another way - use toString:

    public String toString() {
        return "Process[pid=" + pid + "]";
    }

You can parse output and get pid without Reflection.

So full method:

public static int getPid(Process p) {
    int pid = -1;

    try {
        Field f = p.getClass().getDeclaredField("pid");
        f.setAccessible(true);
        pid = f.getInt(p);
        f.setAccessible(false);
    } catch (Throwable ignored) {
        try {
            Matcher m = Pattern.compile("pid=(\\d+)").matcher(p.toString());
            pid = m.find() ? Integer.parseInt(m.group(1)) : -1;
        } catch (Throwable ignored2) {
            pid = -1;
        }
    }
    return pid;
}
2 of 4
2

Will you be using the PID to kill the process? If so, you can simply call destroy() on your Process instance. No need for the PID. Please note that you will need to launch the process using ProcessBuilder, rather than getRuntime().exec(), for this to work.

If you really do need the process ID, you may need to use a shell script. There is no way to get the PID from Java, AFAIK.

EDIT:

Since you need to keep a handle on the Process after leaving your app and returning to it, one solution is to make a static member in the class that spawns the Process:

private static Process myProcess;

Use this member to store the Process that you get back from calling start() on your ProcessBuilder. The static member will stay around as long as your app is in memory — it doesn't have to be visible. It should be possible to kill the process after returning to your app. If the system happens to kill your app to free up resources, then you will have no way to terminate the child process (if it stays running), but this solution should work for most cases.

Find elsewhere
🌐
Stack Overflow
stackoverflow.com › questions › 43914035 › how-to-get-the-result-of-runtime-getruntime-exec-directly
android - How to get the result of Runtime.getRuntime().exec directly - Stack Overflow
May 11, 2017 - I'm working on a rooted android device. I'm trying to capture the screen and store the result in Bitmap for later usage. String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath(); path += "/img.png"; Process 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(); final Bitmap x = BitmapFactory.decodeFile(path); What I'm doing here is naming a path for a new image and capturing the screen using the command /system/bin/screencap -p FILEPATH.
🌐
Blogger
shuiqingwang.blogspot.com › 2011 › 10 › android-application-runs-shell.html
Shuiqing Wang: Android application runs shell command/script using Runtime.exec().
To run shell commands in android application code, we can use the java function Runtime.exec(); e.g. Runtime.getRuntime().exec("cat ./example.txt");
🌐
GitHub
github.com › trongvu › notes › issues › 6
Android system hangs when executing command with Runtime.getRuntime().exec() · Issue #6 · trongvu/notes
February 17, 2019 - String cmd = "monkey -p com.google.android.calculator --throttle 200 -v 10000"; try { final Process p = Runtime.getRuntime().exec(cmd); new Thread(() -> { try { InputStreamReader isr = new InputStreamReader (p.getInputStream()); BufferedReader br = new BufferedReader(isr); while (true) { String s = br.readLine (); if (s == null) break; System.out.println (s); } p.getInputStream().close (); } catch (Exception ex) { System.out.println ("Problem reading stream getInputStream: " + ex); ex.printStackTrace (); } }).run(); new Thread(() -> { try { InputStreamReader isr = new InputStreamReader (p.getE
Author   trongvu
🌐
Stack Overflow
stackoverflow.com › questions › 30918384 › runtime-getruntime-exec-to-use-command-line-in-android-app
java - Runtime.getRuntime().exec() to use command-line in android app - Stack Overflow
June 18, 2015 - CopyRuntime rt = Runtime.getRuntime(); String cmdString = "su"; System.out.println(cmdString); Process pr = rt.exec(cmdString); When I do this, my app asks the user to be granted root access. when the user accepts, it says the app has been granted root access but then the app completely freezes. When I try to run other commands like ls, they work fine. Mobile Development Collective · java · android ·
🌐
Narkive
android-developers.narkive.com › Qu3wmzxe › problem-in-executing-runtime-getruntime-exec
problem in executing Runtime.getRuntime().exec()
To post to this group, send email to android-***@googlegroups.com To unsubscribe from this group, send email to android-developers+***@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en ... Post by Ali Process p = Runtime.getRuntime().exec("su"); p = Runtime.getRuntime().exec("sync"); p = Runtime.getRuntime().exec("echo 3 > /proc/sys/vm/drop_caches"); Regardless if these commands would or would not work with sufficient permission, your most obvious problem is a fundamental misunderstanding of the "su" command sometimes available on custom roms, and on unix-like systems in general.
🌐
XDA Forums
xdaforums.com › home › general development › android development and hacking › android q&a, help & troubleshooting
[Q] Runtime.getRuntime().exec dosn't work | XDA Forums
April 10, 2013 - Hi i'm trying to make an app with a button that free cache of the phone.. This is the code: package com.mkyong.android; import android.annotation.SuppressLint; import android.app.Activity; import android.os.Bundle; import android.util.Log...