Android Runtime.getRuntime().exec() to nav through directories - android

So I want to be able to write an app that can turn on and display logcat messages, dmesg, and also be able to run commands like 'ls' 'cat' 'echo' 'cd.'
If I do the following:
nativeProc = Runtime.getRuntime().exec("ls\n");
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(nativeProc.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(nativeProc.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
full = full + "\n" + line;
}
I can put the text "full" to a Text View and see the root directory.
However, that's about all I can do. Let's say I want to find a directory, and change to it, I'm having trouble.
So if I do this:
nativeProc = Runtime.getRuntime().exec("ls\n");
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(nativeProc.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(nativeProc.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
full = full + "\n" + line;
}
/* Code here to confirm the existing of a directory*/
nativeProc = Runtime.getRuntime().exec("cd tmp\n");
BufferedReader in2 = new BufferedReader(new InputStreamReader(nativeProc.getInputStream()));
line = null;
String test = "\nStart1:\n";
while ((line = in2.readLine()) != null) {
test = test + "\n" + line;
}
I get nothing for both "full" and "text"
Any ideas?

You can execute ls with provided path for which folders should be listed
Runtime.getRuntime().exec(new String[] { "ls", "\\tmp"});

The current working directory is associated with the current process. When you exec("cd tmp") you are creating a process, changing its directory to "tmp", and then the process exits. The parent process' working directory doesn't change.
See this for a more general discussion of changing the current working directory in Java.

How about writing a shell file which checks for existence of the file and all other implementaion in this file and added it to sdcard and trigger the shell file from java using getRuntimr.exec().you can also pass parameters to it.

Related

Android - Save and Read from file

I have a listview lv_operationListand I'm trying to save it to a file and read it after. I can save and read files but I dont know if what I'm saving and reading is correct.
Basically I want to save the list rows and when I load a program I want to fill the same listview with the saved data.
Saving:
for (int i = 0; i < lv_operationList.getAdapter().getCount() - 1; i++) {
fileOutputStream.write(lv_operationList.getAdapter().toString().getBytes());
}
fileOutputStream.close();
Load?? Maybe something like this?
`fileInputStream = getContext().openFileInput(programName);
Scanner scanner = new Scanner(new DataInputStream(fileInputStream));
while(scanner.hasNext()) {
//Read??
}
//and display on lv_operationList. How?
i think you need to append the contents to the same file so you need to use append_mode like this.
OutputStreamWriter out = new OutputStreamWriter(openFileOutput("save.txt", Context.MODE_APPEND));
out.write("text");
out.write('\n');
in order to read them you can use this method.
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
Log.i("reading line by line",""+text);
}

Connect to third-party app's database?

I am creating an app for personal use only, and for a while now I have been trying to figure out how to connect to a third-party's app's database without sharing content user ID. Note: I have root, so all root options are welcome too!
I have been using this:
protected String RefreshMessages() {
try {
String line;
String result = "";
Process process = Runtime.getRuntime().exec("su");
OutputStream stdin = process.getOutputStream();
InputStream stdout = process.getInputStream();
stdin.write("su -c 'sqlite3 \"/data/data/<app>/databases/database.db\" \"" + REFRESH_QUERY + "\"'\n".getBytes());
stdin.write("exit\n".getBytes());
stdin.flush();
stdin.close();
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
while((line = br.readLine()) != null){
result = result + line;
}
Log.d("[Output]", result);
br.close();
process.waitFor();
process.destroy();
return result;
} catch (Exception ex) {
Log.d("ERR-RFRSH-MSG", ex.toString());
return "0";
}
}
And spamming it in a service as fast as I can to get updates, but seriously.. there has to be a better option available... especially as a root user. Something that allows me to connect properly and get live information from the database. I have literally Google'd for months and this is the best I could find.
I also found stuff about copying the database into a TEMP folder within my app's domain and then reading contents, but I need to read information quick. Constantly copying over the whole database is too slow.
Please tell me I have better options, Android wizards!

Unable to input "enter" key event from within my app android

I want to input "enter" key event programmatically from within my app.
I have tried it using abd shell command as well as using AccessibilityService, but found no luck in it.
Similar question was asked here as well
Below is my code which I used to execute adb shell command :
try {
Runtime runtime = Runtime.getRuntime();
Process p = runtime.exec("input keyevent 66");
BufferedReader standardIn = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader errorIn = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String output = "";
String line;
while ((line = standardIn.readLine()) != null) {
output += line + "\n";
}
while ((line = errorIn.readLine()) != null) {
output += line + "\n";
}
Log.d("output", "" + output);
} catch (IOException e) {
e.printStackTrace();
}
I am getting the following output :
sh: resetreason: can't execute: Permission denied
Someone please help me out.
If anyone knows how to achieve it using AccessibilityService as well, please let me know.
Thanks in advance!
Add this <uses-permission android:name="android.permission.ACCESS_SUPERUSER" /> permission & Try again .

Xposed - How to get the package name of a process

I'm building an xposed module and i want to hook a method only if certain process (app) called this method.
I can get the process pid and uid using Binder, but I can't find a way to get the package name without having a context (i'm running my code in a class that can't get any Context as parameter).
How can I get it?
Thanks,
Gidi
There is a solution working for me in the case you don't have Context:
BufferedReader cmdlineReader = null;
try {
cmdlineReader = new BufferedReader(new InputStreamReader(
new FileInputStream(
"/proc/" + android.os.Process.myPid() + "/cmdline"),
"iso-8859-1"));
int c;
StringBuilder processName = new StringBuilder();
while ((c = cmdlineReader.read()) > 0) {
processName.append((char) c);
}
return processName.toString();
} finally {
if (cmdlineReader != null) {
cmdlineReader.close();
}
}
Source: Is there a way to get current process name in Android

Reading Logcat within the app returns null

I read the other posts and can't figure out the "trick".
I looked at Log Collector but can't use a separate APK. I'm basically using the same approach and I consistently get nothing back on the processes inputstream.
I have READ_LOGS in the manifest.
From within my default activity, I'm able to get the log, but if I move the logic to another activity or utilize an asynctask, no output is returned.
this code is from my default activity... inline, i dump it to the log
try {
Process process = Runtime.getRuntime().exec("logcat -d");
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
StringBuilder log=new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
log.append(line);
}
Log.d(LOGTAG, "Logcat: " +log.toString());
} catch (IOException e) {}
if i wrap it in an asynctask or just inline it in another activity, it returns nothing
ArrayList<String> commandLine = new ArrayList<String>();
//terminate on completion and suppress everything except the filter
commandLine.add("logcat -d -s");
...
//replace asynctask with inline (could not get log in asynctask)
showProgressDialog(getString(R.string.acquiring_log_progress_dialog_message));
final StringBuilder log = new StringBuilder();
BufferedReader bufferedReader = null;
try{
Process process = Runtime.getRuntime().exec(commandLine.toArray(new String[0]));
bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null){
log.append(line);
log.append(MangoApp.LINE_SEPARATOR);
}
sendIntent.putExtra(Intent.EXTRA_TEXT, log.toString());
startActivity(Intent.createChooser(sendIntent, getString(R.string.chooser_title)));
dismissProgressDialog();
dismissMainDialog();
finish();
}
catch (IOException e){
dismissProgressDialog();
showErrorDialog(getString(R.string.failed_to_get_log_message));
Log.e(LOGTAG, "Log collection failed: ", e);//$NON-NLS-1$
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ignore) {}
}
}
Can anyone spot the diff or explain the magic? I'm pretty sure the commandline is right in the second version so scratching my head. I'm using 2.1 SDK 7 on the emulator.
Thanks
Hope this will be helpful, you don't have to create file by your self just execute the below command, to get the error info.
Runtime.getRuntime().exec("logcat -v time -r 100 -f /sdcard/log.txt *:E");
Logcat parameters options:
-r <size in kilobytes> -> for specifying the size of file
-f <filename> -> file to which you want to write the logs.
Can you try it without the ArrayList. Just pass the command String
I have implemented it in the following way (without the ArrayList). It works for me.
String baseCommand = "logcat -v time";
baseCommand += " MyApp:I "; // Info for my app
baseCommand += " *:S "; // Silence others
ServicesController.logReaderProcess = Runtime.getRuntime().exec(baseCommand);

Categories

Resources