I have an Android application utilizing RootTools v4.2 (the latest I know of) and I have followed their documentation on how to execute shell commands as root. Sometimes the commands execute just fine, other times the app crashes with the following exception.
java.lang.IllegalStateException: Unable to add commands to a closed shell
Here is the actual code the exception is being throw on:
RootTools.getShell(true).add(cmd);
So I'm wondering since the docs make no mention of this sort of problem if there is something else I'm doing wrong? Looking through the docs I see nothing on how to ensure I get an open shell before I start adding commands.
This code is working with me . Try to install the Library again may be its not vaild .
if(RootTools.isAccessGiven()){
try {
Shell shell = RootTools.getShell(true);
JavaCommand cmd = new JavaCommand(0,this,"input keyevent 26");
shell.add(cmd);
}
catch (Exception e){
Log.d("ERRORS : ",e.getMessage());
}
}
Related
I am able to run a shell script on the Mac command line, but when I call it in Android Studio java it fails with this error:
GenerateActivity::THE COMMAND=[./go.top-level, Sweden]
java.io.IOException: Cannot run program "./go.top-level" (in directory "/data/user/0/com.example.frontpage/files/scripts"): error=13, Permission denied
My java code to call the script is as follows:
dir = lcontext.getFilesDir(); //lcontext is passed into this procedure
File workingDirectory = new File(dir + "/scripts/");//go.top-level is in /scripts dir
List<String> command = new ArrayList<String>();
command.add("./go.top-level"); // command
command.add(country); // command
System.out.println(TAG + "THE COMMAND=" + command.toString());
// creating the process
ProcessBuilder pb = new ProcessBuilder(command);
pb.directory(workingDirectory);
try {
pb.start(); //pb.wait() errors out indicating need a lock and a thread.....
} catch (Exception e) {
e.printStackTrace();
}
The process is failing immediately in the java. But, when I run it at the command line, i.e., via:
%./go.top-level Sweden (in /scripts dir)
it works, although it takes a couple of minutes. (note: I do "run-as com.example.frontpage" before running). The java seems logical to me since I set the workingDirectory appropriately. Also the /scripts folder and all of the files in it as well as the other folders used in this code are set to 777 permissions dynamically in the code. Why doesn't the error say, "./go.top-level Sweden" since the script call takes one argument? What am I missing here as far as this permission error? Is pb.start() a bad idea since the execution takes on the order of minutes? But when I try pb.wait() I get a different error indicating I need a lock and a thread. If that is best can someone indicate how best to do that?
TIA
my environment:
cpu:rk3288
os:android7.1
transfer method:sftp
I wrote android code to do these things below:
get the logcat with code "adb logcat -d -v time -f /mnt/sdcard/logcat.txt"
pull the file logcat.tx to the server with sftp
in 1st step I coding some java language with android studio like below, if anyone can help me, thanks!
Process p = Runtime.getRuntime().exec("adb logcat -d -v time -f /mnt/sdcard/logcat.txt");
error massage:
java.io.IOException: Cannot run program "adb": error=13, Permission denied
You can't use adb commands from inside the device, even if you somehow have it in the device you would need root permissions. The adb is the bridge between the PC and the device. Take a look here: https://developer.android.com/studio/command-line/adb
Although you probably can just remove the adb and use logcat directly, like:
Process p = Runtime.getRuntime().exec("logcat -d -v time -f /mnt/sdcard/logcat.txt");
Here you can see some more options about using the logcat command: Read logcat programmatically within application, including Reetpreet Brar's answer, that I think will be better for you:
Process pq=Runtime.getRuntime().exec("logcat v main"); //adapt the command for yourself
BufferedReader brq = new BufferedReader(new InputStreamReader(pq.getInputStream()));
String sq="";
while ((sq = brq.readLine()) != null)
{
//here you can do what you want with the log, like writing in a file to
//send to the server later.
}
Here you can choose methods to write your file: How to Read/Write String from a File in Android
Then, just send the file to the server.
I open a cmd on windows system, and then input "adb shell am instrument -w com.demo.uia.test/android.support.test.runner.AndroidJUnitRunner" to run android test.
I want to print log in the cmd while run the test, can anyone tell me how to write code to print log? I have tied system.out.println("xx") and Log.i("xx","xx"), but it's useless.
I want to show the log in cmd line, not in logcat.
I solved the problem now, use sendStatus api.
I guess #MoMo did something like this to have logging output in command prompt window:
In your test class define a function:
private void out(String str) {
Bundle b = new Bundle();
b.putString(Instrumentation.REPORT_KEY_STREAMRESULT, "\n" + str);
InstrumentationRegistry.getInstrumentation().sendStatus(0, b);
}
Then simply use it in #Test functions like:
out("Some message...");
The output appears when running the test in Command Prompt window with adb shell am instrument..., but it is not shown in Run window of Android Studio. It somehow filters the output of test runs, and I cannot find a setting to modify this filter.
I have just built Libgit2 (v0.20.0) for Android (target SDK version 18, debugging on a rooted device running Cyanogenmod 10.1.2, Android 4.2.2) and a simple function like getting the version number of Libgit2 works fine through the JNI. But when I use the git_clone function it stops right after the objects/info folder is created and returns this error:
Error -1 cloning repository - Failed to set permissions on '/storage/sdcard0/it/ptt/.git/objects/info': Operation not permitted
I have given the application the WRITE_EXTERNAL_STORAGE permission but I guess it still can't chmod unless owner of the file. When I use adb shell to check out the permission mode of the info folder I get:
d---rwxr-x system sdcard_rw 2014-05-15 09:31 info
And by using pwd.h functions I get the username that the c code (that is calling git_clone) is under to be u0_a92. How am I suppose to get pass this I suppose very Android related issue? Is there a simple way to stop Libgit2 from calling p_chmod or can I give it permissions to do so?
I ended up defining p_chmod as a method always returning true to get passed the error. In the bash script I use to build libgit2 I inserted the following lines that leaves the source files in an unmodified condition after building for android:
LIBGIT2_POSIX_PATH="$LIBGIT2_SOURCE_PATH/src/posix.h"
LIBGIT2_POSIX_BACKUP_PATH="$LIBGIT2_SOURCE_PATH/src/posix_original.h"
printf "#include \"always_success.h\"\nint always_success() { return 0; }" > "$LIBGIT2_SOURCE_PATH/src/always_success.c"
printf "int always_success();" > "$LIBGIT2_SOURCE_PATH/src/always_success.h"
cp $LIBGIT2_POSIX_PATH "$LIBGIT2_POSIX_BACKUP_PATH"
sed -i "s/^#define\sp_chmod(p, m).*$/#include \"always_success.h\"\n#define p_chmod(p, m) always_success()\nextern int always_success();\n/" $LIBGIT2_POSIX_PATH
# run the build process with cmake ...
# restore chmod manipulated source header
mv $LIBGIT2_POSIX_BACKUP_PATH $LIBGIT2_POSIX_PATH
There is probably a cleaner way to solve this but at least now I dont get that error anymore. Thanks to Carlos for his help!
UPDATE
Running adb shell mount | grep sdcard I could see that the sdcard which I am trying to clone the repository into uses the vfat file system which according to this forum thread doesn't support unix-style permissions.
Using adb.exe that comes with the Android SDK, I can get root access to an Android device.
For testing purposes, I would like to give an Android app root permissions as well.
I know that app is running under a particular account called app_68.
Is there an adb shell command to add app_68 to the "root group"?
Thanks in advance for your comments/solutions.
You need the superuser (su) binary to run your app as root user.
For running as root implement this:
Process p = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
os.writeBytes("yourCommand\n");
os.writeBytes("exit\n");
os.flush();
os.close();
try { p.waitFor(); } catch (InterruptedException e) {}
If you get something like su: uid xxxx not allowed, then you need to update your su-binary using SuperSU.
Also see https://stackoverflow.com/a/26654728/4479004 if you want a fully detailed and working source.Just look at the code below:
Update: To get the result (the output to stdout), use: