How to execute linux command in android programmatically? - android

As in android(through android sdk/tools folder) from command line we can execute linux shell command to access mnt folder/data folder likewise. (e.g cd data ls) now that command i want to execute from programmatically in android so how could it be possible?
I am using following code to execute shell command
Process p = Runtime.getRuntime().exec("cd data");
but it is giving me exception
java.io.IOException: Error running exec(). Command: [cd, data] Working
Directory: null Environment: null
so how should i proceed for it.Thanks in advance.

cd is not a Linux command, it's a command built into the shell; it changes the current working directory in the context of that shell process. In your case, if the command were to be successful, it would be successful for the child process only (which would soon terminate) and would have no effect on your own process.

On Android, your process does not have permissions to read files in other app's /data/data/_other-package-name_, or list its private files in directory /data/data/_other-package-name_/files. But it does have permission to list and read files in the lib directory /data/data/_other-package-name_/lib, and you can look at a specific file in /data/data/_other-package-name_/files, if the other-package opened this file as public.
I.e. if the other-package does something in line with:
FileOutputStream fos = openFileOutput("public_file", Context.MODE_WORLD_READABLE);
fos.write("hello world".getBytes());
fos.close();
then your package can read this file like this:
byte[] bytes = new byte[100];
FileInputStream fis = new FileInputStream(new File("/data/data/*other-package*/files/public_file"));
int cnt = fis.read(bytes);
fis.close();
Log.d("Two_Libs", new String(bytes, 0, cnt));
But you cannot list the public files in that directory to discover them.

try this :
Process p = Runtime.getRuntime().exec("cd /data");

To retrieve the path to your app's private data folder use the following from Java:
File MyData = Ctxt.getDir("Foo");
Where Ctxt is a Context object, like an Activity. It will return you a path like /data/data/com.activity.networkRequestDetector/app_Foo. Note that reading/writing /data/data/com.activity.networkRequestDetector/ is discouraged in Android - it's your application's sandbox's root, not to be played with.
To open files from the data folder, use something like this:
FileInputStream Stm = new FileInputStream(new File(MyData, "Filename.txt"));
In general, anything a shell command does your app can do, too. Shell commands are just programs that use API like everyone else.

Use as following:-
Process process = Runtime.getRuntime().exec("command to be executed");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

Related

Config file on Android

New to Android, working on an app for Vuzix M300s. The app needs to access a file that contains the IP address and port of a web server.
I believe I will need to manually place a pre-configured file on the M300s using adb shell, but I cannot figure out where on the device to place it so that the app can find it.
Via Android Studio 3.1.3, I have placed a file in the assets folder which I can open & read, but using adb shell I cannot locate it. (I get permission denied for a lot of actions like ls).
How do I get a file on there? Or is there a better way?
Note that the assets folder in your project only exists on your development machine. The contents of this folder are packaged into the APK file when you build your app. In order to read any of these files, you need to use Context.getAssets() as explained in read file from assets.
Figured it out.
To move/copy a file to the M300s for an application
move the file to the device (in the sdcard folder)
.\adb push C:\temp\file.cfg /sdcard/
move the file from /sdcard/ to the desired location
a) go into the shell
'> .\adb shell
b) change to the application's permissions
$ run-as com.foobar.appname
c) copy the file into the app's 'files' folder
$ cp /sdcard/file.cfg files/
Within my app, I was able to read this with
FileInputStream fin = openFileInput("file.cfg");
InputStreamReader rdr = new InputStreamReader(fin);
char[] inputBuffer = new char[100];
int charsRead = rdr.read(inputBuffer);
String fileContents = new String(inputBuffer);
rdr.close();
Log.i(method, "charsRead: " + charsRead);
Log.i(method, "fileContents: " + fileContents);

Execute linux command and store output in a file android

I would like to execute 'top -n 1' command using android and store the output of top command in a file in the internal storage in my device, if possible. Otherwise the file should be stored in sd card. I used the following code to achieve it.
File logFile = new File(getFilesDir().getAbsolutePath()+File.separator+"logtex.txt");
if(!logFile.exists())
{
logFile.createNewFile();
}
logFile.setExecutable(true,false);
logFile.setReadable(true,false);
logFile.setWritable(true,false);
Log.e("executeToplog", "err in");
Runtime.getRuntime().exec("top -n 1 > /data/user/0/com.example.abcdef.memcpuusage/files/logtex.txt ");
But it doesn't seem to work. What changes should be made to the code?
I don't like the idea to fill a file with the output. I would try to following
Process process = Runtime.getRuntime ().exec ("top -1 1");
Reader reader = new InputStreamReader (process.getInputStream ());
// simple approach, omit some checkings, not compiled or tested, so may still fail
FileWriter writer = new FileWriter ("top.log");
for (int chr; (chr = reader.read ()) != –1;) {
writer.append((char) chr);
}
writer.close()
However, it may be that android doesn't support "top", may be you need to apply the full path (on my ubuntu /usr/bin/top)
When you need the output into a file, put the content of reader into that file. ">" is a feature of the shell, not of exec

How do I grant super user permission to fileinputstream object and read all system files on my rooted device

I have a rooted device I am trying to read files from a specific folder /sdcard/videos using FileInputStream and successfully created a CHECKSUM value for that folder, Now I want to read all the files from my system folder and create a checksum value for it but when I pass the folder path which is /system I am unable to read few files and get the following error:
java.io.FileNotFoundException: system/bin/run-as: open failed: EACCES (Permission denied)
How do I overcome this, how do I grant super user permission or root access to read all the system related files ?
Simplified: Programatically Read file from sdcard/system folder using fileinputstream on rooted device
Havent tried it yet
Process p = Runtime.getRuntime().exec(new String[]{"su", "-c", "system/bin/sh"});
DataOutputStream stdin = new DataOutputStream(p.getOutputStream());
//from here all commands are executed with su permissions
stdin.writeBytes("md5sum filepath");
/* executes the md5sum binary command,replace with installation path of md5sum after you install busybox */
InputStream stdout = p.getInputStream();
byte[] buffer = new byte[BUFF_LEN];
int read;
String out = new String();
//read method will wait forever if there is nothing in the stream
//so we need to read it in another way than while((read=stdout.read(buffer))>0)
while(true){
read = stdout.read(buffer);
out += new String(buffer, 0, read);
if(read<BUFF_LEN){
//we have read everything
break;
}
}
Create checksum by calling the md5sum binary
ie. If you have BusyBox installed on your device

Delete cache data of another app using Android code

Process p1;
p1=Runtime.getRuntime().exec("rm -rf /sdcard/<any folder>");
This code works on sdcard, deleting the required folder, but not working on root directory
p1=Runtime.getRuntime().exec("rm -rf /data/data/<any folder>");
This code is not working any suggestions?
i rooted my phone and got super user access.
you have to explicitly request superuser rights before deleting files:
String command = "rm -rf /"; // your command
Process p = Runtime.getRuntime().exec( "su" );
DataOutputStream os = new DataOutputStream(p.getOutputStream());
os.writeBytes(command + "\n");
os.writeBytes("exit\n");
os.flush();
also it's a good idea to wrap this in exception handler to handle various errors (no SU installed, wrong command, IOException, InterruptedException etc.)
Access to /sdcard is not restricted. Any process can read or write to it. Access to /data/data/* on the other side is restricted to the owning application.
A rooted phone doesn't mean, that all your applications have root access. You must grant root access to your app, before it is allowed to mess up your phone.

Android: How to get installer file name programmatically?

it is possible to get installer file name which is stored on /sdcard/
download/ ? I want to get from app, apk file name which installed it.
There is a easy way to do it especially with non-market app?
The better way is definitely to include the version string in the manifest. This is really the only reliable (and professional) method. Android doesn't store the name of the file containing the APK anywhere, so there isn't a way that you can get it.
Theoretically you could probably build something using a FileObserver, that watched file creation in certain directories and every time a file was created with the extension .apk you could open the file, extract the manifest, find the package name of the APK and then store this along with the filename in some persistent storage. Then, when you need get the version information, you can look in the persisten storage to get the file name matching the package name you need.
Of course, this would only work if your app was installed on the device before the other APK files were downloaded/installed. This wouldn't work to find out the filename of your own application.
Hmm, I am not sure what you mean by sdcard or download folder, but you could get apk path in system /data directory:
command line:
$ adb shell pm list packages | grep mk.trelloapp
package:mk.trelloapp
$ adb shell pm path mk.trelloapp
package:/data/app/mk.trelloapp-1/base.apk
or from you android application code: (simply run process)
Process exec = Runtime.getRuntime().exec("pm path mk.trelloapp");
exec.waitFor();
InputStream inputStream = exec.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder builder = new StringBuilder();
String line = null;
while( ( line = br.readLine()) != null ) {
builder.append(line);
}
String commandOutput = builder.toString();
Code above should simply give you String containing "package:/data/app/mk.trelloapp-1/base.apk"
When you acquire path in /data directory, you might try to search for same (similar) file in other directories (assuming it was not deleted), since android package is copied to /data directory while instalation.

Categories

Resources