I am trying to access the database of another application and print it's contents to the console (USING ROOT), but for some reason I am getting this response:
E/[Error]: Error: incomplete SQL: ls
E/[Error]: exit
I don't really understand why this is happening. I tried to put my syntax in escaped quotations, I tried other sqlite commands, but it doesn't seem to work properly.
I can access the database and print it contents using ADB through my PC with the same path, and if I press the button in my application it asks me for root access, so those 2 are not the issues.
My dumbed down code:
onCreate
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnCon = (Button)findViewById(R.id.button1);
btnCon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RunWithRoot("su shell -c sqlite3 \"data/data/app.package/databases/Database.db\" \"select * from messages;\"");
}
});
}
RunWithRoot
private void RunWithRoot(String textView) {
try {
String line;
Process process = Runtime.getRuntime().exec(textView);
OutputStream stdin = process.getOutputStream();
InputStream stderr = process.getErrorStream();
InputStream stdout = process.getInputStream();
stdin.write(("ls\n").getBytes());
stdin.write("exit\n".getBytes());
stdin.flush();
stdin.close();
BufferedReader br =
new BufferedReader(new InputStreamReader(stdout));
while ((line = br.readLine()) != null) {
Log.d("[Output]", line);
}
br.close();
br =
new BufferedReader(new InputStreamReader(stderr));
while ((line = br.readLine()) != null) {
Log.e("[Error]", line);
}
br.close();
process.waitFor();
process.destroy();
} catch (Exception ex) {
}
}
Does someone know what I'm doing wrong? I am very new to Android development, and even newer to root. If someone could throw me in the right direction with this, that would be MUCH appreciated.
PS: This app will be for personal use only, so I don't need checks to see if people have root, or if the path exists, etc.. I already heard a few developer's minds worrying heh
I fixed it using the following code.
private void RunWithRoot(){
String line;
Process process = Runtime.getRuntime().exec("su shell");
OutputStream stdin = process.getOutputStream();
InputStream stderr = process.getErrorStream();
InputStream stdout = process.getInputStream();
stdin.write("su -c 'sqlite3 \"/data/data/app.pkge/databases/Database.db\" \"select * from messages;\"'\n".getBytes());
stdin.flush();
stdin.close();
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
while ((line = br.readLine()) != null) {
Log.d("[Output]", line);
}
br.close();
br = new BufferedReader(new InputStreamReader(stderr));
while ((line = br.readLine()) != null) {
Log.e("[Error]", line);
}
br.close();
process.waitFor();
process.destroy();
}
And now it works correctly! Mostly thanks to #ScaryWombat!
Related
I am working on a Server launcher. This launcher runs Minecraft servers.
I want to get colors from the server's process's input like windows command prompt. How can I do that?
My server thread:
serverThread = new RunnableThread("ServerThread-" + serverName) {
#Override
public void onRun() {
if (!getProcess().isAlive()) {
ServerStatusChangeEvent.change(LocalServer.this, StatusType.STOPPED);
closePort();
if(queryTimerTask != null) queryTimerTask.cancel(false);
cancel();
}
try {
final BufferedReader reader = new BufferedReader(
new InputStreamReader(getProcess().getInputStream(), Charset.forName("UTF-8")));
String line;
while ((line = reader.readLine()) != null) {
String l = line;
Platform.runLater(() -> parseLine(l));
}
reader.close();
} catch (final Exception e) {
//empty catch block
}
}
};
Thanks for the answers and sorry for my bad english!
I'm trying to run shell script by using ProcessBuilder. The script works but it can't run after the java code. And error stream doesn't output message. I'm running it on centOS 6.9 computer. Please find below my code.
public static ArrayList<String> runCommand(ArrayList<String> command)throws IOException {
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command(command);
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
ArrayList<String> commandOutput = new ArrayList<>();
String str;
while((str = reader.readLine()) != null) {
commandOutput.add(str);
}
StringBuilder errorBuilder = new StringBuilder();
while((str = errorReader.readLine()) != null) {
errorBuilder.append(str);
}
String errorMessage = errorBuilder.toString();
if(!errorMessage.equals("")) {
String message = LOG_TAG + ",[runCommand] error:" + errorMessage;
System.out.println(message);
}
reader.close();
errorReader.close();
process.destroy();
return commandOutput;
}
In your case, you are reading something from the output stream of the process, till you consume everything. Then, you try to read error stream.
If the process writes some considerable number of characters on the error stream, the other process will block till they are consumed. To consume both error stream and output stream at the same time, you need to use threads.
You may follow the StreamGobbler technique. You may get some details from that page: https://www.javaworld.com/article/2071275/when-runtime-exec---won-t.html?page=2
This is some code influenced from the page:
public class StreamGobbler extends Thread {
private static final String EOL = System.lineSeparator();
private final InputStream inputStream;
private final StringBuilder output = new StringBuilder();
public StreamGobbler(InputStream inputStream) {
this.inputStream = inputStream;
}
public void run() {
try (InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader reader = new BufferedReader(inputStreamReader);
) {
String line;
while ((line = reader.readLine()) != null) {
output.append(line);
output.append(EOL);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
public String getOutput() {
return output.toString();
}
}
In your code, you use StreamGobbler like this:
StreamGobbler outputGobbler = new StreamGobbler(process.getInputStream());
StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream());
process.waitFor();
String commandOutput = outputGobbler.getOutput();
String errorMessage = errorGobbler.getOutput();
process.destroy();
I have developed a demo app in JSFrame which should execute powershell script in my folder.
I am trying following code.
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
try
{
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec("powershell C:\\helloworld.ps1");
InputStream is = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(isr);
String line;
while ((line = reader.readLine()) != null)
{
System.out.println(line);
}
reader.close();
proc.getOutputStream().close();
}
catch(Exception ex)
{
}
}
And in helloworld.ps1, I am having following command :
$strString = "Hello World 123"
write-host $strString
But I am not getting any output.
I was trying to get the logcat content into a JTextPane. I used following code hoping it will return the content as String but it freeze and also, doesn't produce an error.
Process exec = null;
try {
exec = Runtime.getRuntime().exec("adb logcat -d");
InputStream errorStream = exec.getErrorStream();
BufferedReader ebr = new BufferedReader(new InputStreamReader(errorStream));
String errorLine;
while ((errorLine = ebr.readLine()) != null) {
System.out.println("[ERROR] :- " + errorLine);
}
if (exec.waitFor() == 0) {
InputStream infoStream = exec.getInputStream();
InputStreamReader isr = new InputStreamReader(infoStream);
BufferedReader ibr = new BufferedReader(isr);
String infoLine;
while ((infoLine = ibr.readLine()) != null) {
System.out.println("[INFO] :- " + infoLine);
}
}
} catch (IOException | InterruptedException ex) {
ex.printStackTrace();
} finally {
if (exec != null) {
exec.destroy();
}
}
I referred to some tutorials but, they were not filling my problem. Is this wrong? Are there any other methods to get the logcat content as a String programmatically? Sorry if this is a dumb question.
The issue you're seeing is that you're trying to process command streams and wait for the executing process, all in the same thread. It's blocking because the process reading the streams is waiting on the process and you're losing the stream input.
What you'll want to do is implement the function that reads/processes the command output (input stream) in another thread and kick off that thread when you start the process.
Second, you'll probably want to use ProcessBuilder rather than Runtime.exec.
Something like this can be adapted to do what you want:
public class Test {
public static void main(String[] args) throws Exception {
String startDir = System.getProperty("user.dir"); // start in current dir (change if needed)
ProcessBuilder pb = new ProcessBuilder("adb","logcat","-d");
pb.directory(new File(startDir)); // start directory
pb.redirectErrorStream(true); // redirect the error stream to stdout
Process p = pb.start(); // start the process
// start a new thread to handle the stream input
new Thread(new ProcessTestRunnable(p)).start();
p.waitFor(); // wait if needed
}
// mimics stream gobbler, but allows user to process the result
static class ProcessTestRunnable implements Runnable {
Process p;
BufferedReader br;
ProcessTestRunnable(Process p) {
this.p = p;
}
public void run() {
try {
InputStreamReader isr = new InputStreamReader(p.getInputStream());
br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null)
{
// do something with the output here...
}
}
catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
package burak;
import java.io.*;
public class Server {
public static void main(String[] args) {
try {
String[] command = new String[2];
command[0] = "cmd";
command[1] = "telnet";
Process p = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = reader.readLine();
while (line != null) {
System.out.println(line);
line = reader.readLine();
}
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String Error;
while ((Error = stdError.readLine()) != null) {
System.out.println(Error);
}
while ((Error = stdInput.readLine()) != null) {
System.out.println(Error);
}
} catch (Exception e) {
e.printStackTrace();
}
}
I want to open telnet and send some commands but ı failed to open telnet what is wrong can you tell me?and ı need some examples about telnet conneciton expcect apache.common because ı have to use many ips in one run and ı dont know how to use args in this condi