After some play around with rooted devices, I got stuck on the files. Let's say we have a file somewhere in the root folder which I want to read/write from my application. The only way I found so far is changing the file permission like
String [] cmd = { "su", "-c", "chmod", "777", path};
Process process = new ProcessBuilder(cmd).start();
process.waitFor();
This works fine, the problem is that I want to return back the original file permissions after I'm done with it.
Can anybody help me with getting a file/directory current permissions?
Do ls -l on file/directory and parse the output
EDIT BY OP: the solution is in this thread. This answer just pushed me in the right direction.
Related
Suppose,
at timeA, the 1st process(P1) creates a file and begin writing to it, and after some time,
at timeB, the 2nd process tries to chmod the file permission. And, after some time,
at timeC, P1 finishes writing and closes the file.
The question is: at what time point can other process(say P3) observe that the file permission has been changed?
The file system is inside Android, which should be Linux file system.
I didn't find any document or specification addressing this concurrency issue.
In POSIX semantics which Linux tries to follow, the file access permissions are only checked when opening the file. After the process has an open file descriptor, the process can continue use those permissions the file descriptor was granted until the process closes the file descriptor.
It is also possible for a process to have an open file descriptor to a file that it didn't open, or never had permissions to open - the file descriptors can be inherited over fork and exec, and they can also be sent via Unix domain sockets.
Concurrency-wise there is only one thing: either the open happens before or after the chmod takes effect. If before, then the process writing into file can be completely oblivious that open happened.
Background: I'm working on application that will be used by limited users group and I will never put it on Store. App sometimes is having some troubles on clients devices and it seems like it would be very useful to me to have full access to logcat since I don't have access to devices. And I know that I have to give users "debug" app version - it's not a problem.
So I want to implement feature that allows user (eg. on my request) to redirect logcat to file, which can be sent to me. I already implemented redirecting to file, but I want to allow user for disabling saving to file since it gets big quite fast.
For redirecting to file I'm using
String cmd = "logcat -f " + file.getAbsolutePath();
Runtime.getRuntime().exec(cmd);
But once it's enabled I can't disable it. I mean stop saving to file. I tried with -c option with no luck.
What can I do?
Was asking myself the same thing...
This did the trick for me if anybody is still interested
Runtime.getRuntime().exec("logcat -f " + outputFile.getAbsolutePath() + " -d");
key is the "-d" here in the end.
You could also replace "-d" with "-t 1000" to print only the last 1000 lines to file and then stop.
Be aware that a new call to the same logfile will append logs. So you could delete that file if it already exists.
Runtime.getRuntime().exec() returns a process that you can kill, which will stop the logging.
// Start writing file
String cmd = "logcat -f " + file.getAbsolutePath();
Process logcatProcess = Runtime.getRuntime().exec(cmd);
// Stop writing file
logcatProcess.destroy();
You can switch it back to printing to stdout (default).
String cmd = "logcat -f stdout";
Runtime.getRuntime().exec(cmd);
I did not found solution to my problem, so it remains open. I just want to leave here my workaround as it might be useful.
So I decided to leave logcat printing to stdout and just dump it to file and then clear on button click. This solution have some advantages since logcat is separated in files with timestamps in names so I can look for problem depending on time when something happend.
You may want to call "ps | grep logcat" and kill it with its PID: "kill pid".
I want to use shell command for my app as root permission. I put in my manifest:
<uses-permission android:name="android.permission.ACCESS_SUPERUSER"/>
I want to know if there is a way to allow Super User permission programmatically without using any input device. As you know a window like this is appearing :
I want to avoid that step and programmatically select Remember choice forever.
Short answer! You can not do programatically !
Just exec the command su and within that Process you have root priviliges:
Process p = Runtime.getRuntime().exec("su");
See this blog post for full example.
Source
I want to modify my viber database on my app.
i use this code:
File f = new File("/data/data/com.viber.voip/databases/viber_messages");
boolean b1 = f.setExecutable(true, false);
boolean b2 = f.setWritable(true, false);
but b1,b2 are false.How can it be done?
i use "android.permission.WRITE_EXTERNAL_STORAGE" permission
You can't modify other apps. Your app is sandboxed, that prevents it from modifying other apps. To quote the docs here:
true if and only if the operation succeeded. If the user does not have permission to change the access permissions of this abstract pathname the operation will fail. If the underlying file system does not support execute permission and the value of executable is false, this operation will fail.
The permission "WRITE_TO_EXTERNAL_STORAGE" allows you to write to e.g. the SD card or other spaces that are "user- visible".
To modify other apps it's required that your phone is rooted and you must use something like a shell. Take a look a libsuperuser here. It gives you the option to create a superuser shell (su permissions). You could copy the db into the directory of your app to modify it (remember to set the required permissions).
I'm learning Android programming, and I want to make an application which has to run as root. The logical thing would be to add a root permission in the Android Manifest.
I saw this link in the documentation, and especially noted the FACTORY_TEST permission:
public static final String FACTORY_TEST
Since: API Level 1
Run as a manufacturer test
application, running as the root user.
Only available when the device is
running in manufacturer test mode.
Constant Value:
"android.permission.FACTORY_TEST"
Is that the best way?
If it's not possible using the SDK, how can I make a "root" application work?
What you need to do is something like:
Process root = Runtime.getRuntime().exec("su");
That causes SuperUser to show, which lets you either Allow or Block it from root access. This approach might not work if the user is not rooted. Here is a way you can test it.
First lets us get the basics right. Android run Linux kernel underneath. Now if you have to run your process on it with super user privileges(run it as root) the only way is to execute your process is via command line because it is the only way you can directly interact with the kernel. Also you need to use su before running any command. Also as Chris has mentioned in his comment on the 1st answer
Process process = Runtime.getRuntime().exec("su");
will accomplish nearly nothing. It will just ask for super use privilege using dialog. What you can do is instead of just executing su you can execute your process with su as following
Process process = Runtime.getRuntime().exec(new String[] { "su", "-c", yourCommand});
The -c Option
Among the most commonly used of su's few options is -c, which tells su to execute the command that directly follows it on the same line. Such command is executed as the new user, and then the terminal window or console from which su was run immediately returns to the account of the former user after the command has completed execution or after any program that it has launched has been closed.(More details)
Alternate Option
Alternative to above method one another way that might work is to use command line to copy you app to /system/app/ directory. Then your application will run automatically with root privileges(same as System apps)
The SDK does not offer a way to run an app as root.