Reputation: 10622
Can anyone say, whether adb
commands can be executed through my android application. If it is possible to execute, how it can be implemented?
Upvotes: 42
Views: 79807
Reputation: 1
Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
string cmd = "/system/bin/input keyevent 23\n";
os.writeBytes(cmd);
the phone must be rooted. here I have executed adb command "input keyevent 23". remember when you execute adb command through su you does not need to add "adb shell input keyevent 23"
Upvotes: 0
Reputation: 2628
This is what I do in Kotlin, I also get command responses too
fun runShellCommand(command: String) {
// Run the command
val process = Runtime.getRuntime().exec(command)
val bufferedReader = BufferedReader(
InputStreamReader(process.inputStream)
)
// Grab the results
val log = StringBuilder()
var line: String?
line = bufferedReader.readLine()
while (line != null) {
log.append(line + "\n")
line = bufferedReader.readLine()
}
val Reader = BufferedReader(
InputStreamReader(process.errorStream)
)
// if we had an error during ex we get here
val error_log = StringBuilder()
var error_line: String?
error_line = Reader.readLine()
while (error_line != null) {
error_log.append(error_line + "\n")
error_line = Reader.readLine()
}
if (error_log.toString() != "")
Log.info("ADB_COMMAND", "command : $command $log error $error_log")
else
Log.info("ADB_COMMAND", "command : $command $log")
}
Upvotes: 4
Reputation: 638
i came across this post looking for a different query, but i have worked specifically with input
on android before, so I'd just like to put some clarity on the matter.
The reason why
Runtime.getRuntime().exec("adb shell input keyevent 120");
Is not working, is because you are not removing
adb shell
The ADB
part is only for use on your computer, if you have incorrectly installed ADB, the command would actually be a path to the adb.exe file on your computer, like this
C:\XXXX\ADB Files\adb.exe shell
or
C:\XXXX\ADB Files\adb shell
The shell
part tells the ADB program on your computer to access the devices shell, so your device will not know what shell is either...
Using sh /path/to/commandList.sh
will execute the commads listed in commandList.sh as it is a shell script (a .batch file on windows is similar )
The command you want to use is
Runtime.getRuntime().exec("input keyevent 120");
However this will cause Environment null and working directory null, you can bypass this by writing the commands to a shell script ( .sh file ) and then running the script with
Runtime.getRuntime().exec("sh path/to/shellScript.sh");
Sometimes the sh
is not needed, but i use it just incase.
I hope this clears at least something up :)
Upvotes: 6
Reputation: 511
Normal Android apps have different privileges to processes started via adb
, e.g., processes started via adb
are allowed to the capture the screen whereas normal apps aren't. So, you can execute commands from your app via Runtime.getRuntime().exec()
, but they won't have the same privileges as if you had executed from an adb shell
.
Upvotes: 15
Reputation: 1198
Executing
Runtime.getRuntime().exec("adb shell input keyevent 120");
I got the following error: java.io.IOException: Cannot run program "adb": error=13, Permission denied.
Executing
Runtime.getRuntime().exec("adb shell input keyevent 120");
There is no error but at the same time, my request is not processed to take the screenshot.
I found out this was working in earlier versions of android but later it was removed. Though I'm not able to provide the source here why it is not working.
Hope this helps someone like me who is trying to use this approach to take the screenshot when the app is not in the foreground.
Upvotes: 0
Reputation: 49
adb shell invoked in Runtime.getRuntime().exec is not running under shell user. It provide shell but with same process owner user (like u0_a44). That's the reason all command did not work.
Upvotes: 1
Reputation: 72553
You can do it with this:
Process process = Runtime.getRuntime().exec("your command");
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
Don't forget to surround it with a try and catch statement.
Edit:
@Phix is right, ProcessBuilder would be better to use.
Upvotes: 32