How-to Question: Sending calls to running apps using "am"? - G1 Q&A, Help & Troubleshooting

This is /sort/ of a development question; if the mods feel it's more properly in Q&A, please move it.
First off, a little disclosure; "IANAP".
Okay, here goes:
Currently I am trying to create what ought to be a /very/ simple script using "am" (as in; am start -a blahblah -n blahblah/.blah ) in order to invoke an activity for a specific application. Unfortunately, apparently the activity can only be called viably from //within// the application.
The app in question is "redditisfun" ( http://github.com/talklittle/reddit-is-fun ). The activity in question is ".InboxActivity". So far, I can get the first bit of code to pull up the app, but the second bit fails out due to lack of permission.
1)
Code:
am start -a android.intent.activity.MAIN -n com.andrewshu.android.redditdonation/.RedditIsFun
2)
Code:
am start -a android.intent.activity.MAIN -n com.andrewshu.android.redditdonation/.InboxActivity
I've tried it with "broadcast" rather than "start" -- that throws no errors, but simply does nothing. (logcat shows no activity that I can see.)
So here's my question; how does one send a system call to an app that is already running, using am? I am afraid that none of the documentation I've yet found says anything at all about this.

Related

Terminal Emulator config

Hi Folks, I used to be able to run the 'top' command from the "Terminal Emulator" app but when I run it now, it just scrolls constantly so I can't see the header etc.
Does anyone know how to configure it so it displays correctly. I'm guessing it may a TERM environment variable but I've tried vt100/vt220 to no avail.
top | head
Thanks but that only provides the first set of figures. I have gone back to CF-root 3.2 and its all OK.

[DEV GUIDE][2016.12.22] How-To SU

Guidelines for problem-free su usage
How-To SU is my guide on using "su" in your own programs (to execute commands as root). The guide covers the major common pitfalls and also provides example code, as I have been asked by several developers to provide.
I also did a presentation on this stuff at the Big Android BBQ 2012, so if you're looking for the article and code promised there, here it is!
The text is too long to copy here, but you can find it here:
http://su.chainfire.eu/
Example code is located on GitHub:
https://github.com/Chainfire/libsuperuser
If you are not an app developer, you have no business posting in this thread. This thread is for developer discussion on the article/example code only. In fact, I do not expect many posts in this thread at all - it's all rather straightforward, and this is not a helpdesk.
Moderators: Do not move this thread to a development subsection, 0-posters need to be able to reply to it.
Awesome job man, I definitely learned some new stuff. I've done a little bit differently than your implementation: instead of doing AsyncTask -> run su code inside I did this in my Root class:
Code:
class BackgroundThread extends AsyncTask<String, Void, Void> {
private String s;
public BackgroundThread(String command) {
s = command;
}
@Override
protected Void doInBackground(String... command) {
Process process = null;
DataOutputStream os = null;
try {
process = Runtime.getRuntime().exec("su");
os = new DataOutputStream(process.getOutputStream());
os.writeBytes(s+"\n");
os.writeBytes("exit\n");
os.flush();
process.waitFor();
} catch (Exception e) {
}
finally {
try {
if (os != null)
os.close();
else
process.destroy();
} catch (Exception e) {
}
}
return null;
}
}
And then receive the command in the parameter:
Code:
public void run(String command) {
new BackgroundThread(command).doInBackground();
}
Is this acceptable from your point of view?
No it isn't acceptable, but the reason is not what you might think.
Using a generic AsyncTask derived class to run su calls can be a solution. As long as your code ends up running in the background, all is good. However, in my experience what usually happens is that you have to do a lot of things in the background.
For example, imagine that during your app's startup, you need to check some files, perform some su calls, check some more files, do some computations, etc. Those should all go in a single AsyncTask's doInBackground method. That way you can use onPreExecute and onPostExecute to show and dismiss a dialog that tells the user you are busy.
Furthermore, if you had 10 su commands to run, would you just call new BackgroundThread ... 10 times? As the call should return before the su command is finished executing, the order of the executions of those commands becomes semi-random, you can't depend on them being run in any specific order, it even differs between Android versions (some versions run AsyncTasks serially, others run X of them in parallel). Not to mention that you shouldn't create 10 separate su processes to run 10 commands unless you have a good reason. Batching commands together == much higher performance.
The above does depend on which commands you need to execute, the needs of your application, and how you use it. If you only have to execute a single su command, it can be done that way, but I think in general this is not an ideal solution.
Now, the reason why your solution is truly unacceptable is because you are calling doInBackground. This does not make the code run in the background. You override doInBackground and insert your code, but you call the execute method. You should call your code like this:
Code:
new BackgroundThread(command).execute();
Else you're still calling on the main thread !
If you really want to keep using this method, keep in mind that you can actually pass parameters to the execute() function that in turn will be passed to doInBackground. Look in the AsyncTask documentation ...
that's a nice read
thanks for the guide
Chainfire said:
No it isn't acceptable, but the reason is not what you might think.
Using a generic AsyncTask derived class to run su calls can be a solution. As long as your code ends up running in the background, all is good. However, in my experience what usually happens is that you have to do a lot of things in the background.
For example, imagine that during your app's startup, you need to check some files, perform some su calls, check some more files, do some computations, etc. Those should all go in a single AsyncTask's doInBackground method. That way you can use onPreExecute and onPostExecute to show and dismiss a dialog that tells the user you are busy.
Furthermore, if you had 10 su commands to run, would you just call new BackgroundThread ... 10 times? As the call should return before the su command is finished executing, the order of the executions of those commands becomes semi-random, you can't depend on them being run in any specific order, it even differs between Android versions (some versions run AsyncTasks serially, others run X of them in parallel). Not to mention that you shouldn't create 10 separate su processes to run 10 commands unless you have a good reason. Batching commands together == much higher performance.
The above does depend on which commands you need to execute, the needs of your application, and how you use it. If you only have to execute a single su command, it can be done that way, but I think in general this is not an ideal solution.
Now, the reason why your solution is truly unacceptable is because you are calling doInBackground. This does not make the code run in the background. You override doInBackground and insert your code, but you call the execute method. You should call your code like this:
Code:
new BackgroundThread(command).execute();
Else you're still calling on the main thread !
If you really want to keep using this method, keep in mind that you can actually pass parameters to the execute() function that in turn will be passed to doInBackground. Look in the AsyncTask documentation ...
Click to expand...
Click to collapse
Hmm... I thought calling new BackgroundThread(command).doInBackground(); was doing it in the background thread... if I call new BackgroundThread(command).execute; the commands won't be called at all until I close the application/activity.
I don't do X new calls, for example in the BootService I just batch commands together and execute it once.
I'll use your code and see how it works.
Very nice reading. I always use AsyncTask for su commands, although I learned it the hard way
I remember few months back I couldn't figure out why supersu pops up when timeout is at 2-3 seconds
Sent from my HTC EVO 3D X515m using Tapatalk 2
I generally work with desktop apps. Is there a reason to not use Runnable?
Code:
public void liveBackgroundShellCommand() {
Runnable r = new Runnable() {
public void run() {
boolean LinkLaunched = false;
try {
String[] params = (String[]) Statics.LiveSendCommand.toArray(new String[0]);
Process process = new ProcessBuilder(params).start();
BufferedReader STDOUT = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader STDERR = new BufferedReader(new InputStreamReader(process.getErrorStream()));
This is how I set up a background shell. Then I just pass in the su -c command. Is there a disadvantage to this?
AdamOutler said:
I generally work with desktop apps. Is there a reason to not use Runnable?
Code:
public void liveBackgroundShellCommand() {
Runnable r = new Runnable() {
public void run() {
boolean LinkLaunched = false;
try {
String[] params = (String[]) Statics.LiveSendCommand.toArray(new String[0]);
Process process = new ProcessBuilder(params).start();
BufferedReader STDOUT = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader STDERR = new BufferedReader(new InputStreamReader(process.getErrorStream()));
This is how I set up a background shell. Then I just pass in the su -c command. Is there a disadvantage to this?
Click to expand...
Click to collapse
If this is about desktop Java, then I don't know. I don't use desktop Java, but in most languages and frameworks it is generally frowning upon to block the UI thread, and the UI thread is usually the main/default/first thread.
If we're talking about Android, then this may be bad, depending on what you are doing. A Runnable by itself says nothing about threading or being in the background, a Runnable is just a generic way to define some code you want to run somewhere, sometime.
The code you pasted here does start the process, but it does not wait for the process to exit or read/write to the streams. As such, this piece of code does not block, and is fine. 9 out of 10 times however, a piece of code like this is going to be followed by something like process.waitFor() or reading from STDOUT/STDERR in which cases it does block, and is thus holding up your UI thread and thus bad.
Furthermore, as detailed in the article, calling "su -c" can be errorprone.
Right. I generally launch in a Thread T=new Thread(..). I'be never used AsyncTask. I'm just wondering what its all about.
AdamOutler said:
Right. I generally launch in a Thread T=new Thread(..). I'be never used AsyncTask. I'm just wondering what its all about.
Click to expand...
Click to collapse
Ok, yeah that's fine. AsyncTask is pretty much a Thread wrapper with handy utility functions (onPreExecute, onPostExecute, onProgressUpdate) that is specifically aimed at running a short-lived task away from the UI thread, often with UI feedback (it's brilliant for use with progress dialogs, for example).
Chainfire said:
Ok, yeah that's fine. AsyncTask is pretty much a Thread wrapper with handy utility functions (onPreExecute, onPostExecute, onProgressUpdate) that is specifically aimed at running a short-lived task away from the UI thread, often with UI feedback (it's brilliant for use with progress dialogs, for example).
Click to expand...
Click to collapse
Ah ha! its like a SwingWorker() but with better functionality... Thanks Chainfire! I just looked and apparently it's not available on desktop or I would be switching immediately. That's a wonderful class.
Chainfire said:
Guidelines for problem-free su usage
How-To SU is my guide on using "su" in your own programs (to execute commands as root). The guide covers the major common pitfalls and also provides example code, as I have been asked by several developers to provide.
Click to expand...
Click to collapse
Great & sorely needed topic, thank you. I rarely check this forum, but stumbled in here. Hopefully busy devs of SU apps will be pointed here by someone.
I continue to have lots of problems with SuperUser/SuperSU apps that seem to be pre-configured or something to prevent SU access; and the user is never even prompted. But I don't think this is being discussed here.
At some point in the early development of ICS ROMs I noted that SU calls were taking much longer, perhaps about 0.1 seconds. So I optimized the 4-5 seconds and 40 or 50 calls (including blind chmod's for files that didn't exist on many devices) to about 2-4 calls for most devices.
I know I continue to be guilty of calling SU, and shell, and various other things from improper places, such as UI threads, onCreate etc. But I don't think these cause too much trouble in general, so putting these in threads or wherever is an exercise I save for an app re-design.
My app currently allows selection of "SU Type", but it doesn't seem to be needed anymore, now that I'm avoiding the quoting problems I've had previously.
I use the system() call from C/JNI in a lib. My best/default is like this, where CMD is the command, and noting that \" is " escaped in C:
system ("echo \"CMD\" | su -c sh");
This works, but writes to the filesystem every time:
system ("su -c \"sh /data/local/cmd\""); // Write CMD to cmd file first.
The simplest, but I was having more problems with this for whatever reason; perhaps quoting issues:
system ("su -c \"CMD\"");
thx
---------- Post added at 11:03 PM ---------- Previous post was at 10:58 PM ----------
it is great
pisy3 said:
thx
---------- Post added at 11:03 PM ---------- Previous post was at 10:58 PM ----------
it is great
Click to expand...
Click to collapse
I'm trying to convert my app to use your example classes for running root commands, as most of my app was implemented ok, but I needed to change a couple of bits based on your document. Once chaning I keep running into the following error:
11-20 22:16:39.770: I/System(31924): libcore.io.ErrnoException: kill failed: ESRCH (No such process)
11-20 22:16:39.770: I/System(31924): at libcore.io.Posix.kill(Native Method)
11-20 22:16:39.770: I/System(31924): at libcore.io.ForwardingOs.kill(ForwardingOs.java:77)
11-20 22:16:39.770: I/System(31924): at java.lang.ProcessManager$ProcessImpl.destroy(ProcessManager.java:257)
11-20 22:16:39.770: I/System(31924): at eu.chainfire.libsuperuser.Shell.run(Shell.java:100)
11-20 22:16:39.770: I/System(31924): at eu.chainfire.libsuperuser.Shell$SH.run(Shell.java:149)
11-20 22:16:39.770: I/System(31924): at com.rageconsulting.android.lightflow.util.RootUtil.runRootUnixCommand(RootUtil.java:49)
I'm calling my own helper method which is just a wrapper around your Shell class and it's getting called from an IntentService so I'm not quite sure why this happens.
You can ignore that.
By calling exit here, the process is usually gone.
When it tries to destroy the process in this line, the process is already gone, so it throws that error message as there is nothing to kill/destroy.
Before Android 4.0 this message was not even printed into the log.
Update the library code with some changes (like proper gobbling). See GitHub
Hello dear developers of the supersu. first thanks for good work. I don't know if anyone informed but after htc one s jb update there seem to be some compatibility problems.
The article has been updated to v1.20.
Changes are clearly marked in the "Table of Contents"
http://su.chainfire.eu/
Does the library support other superuser apps too?
mcnamaragio said:
Does the library support other superuser apps too?
Click to expand...
Click to collapse
Yes, it's all about best practises when calling the su binary - it should work with all superuser apps.

Looking for a Dev to create my project

Hello,
I am looking for a Developer who can create an Android App/Service/Whatever for me to do the following task.
Since I have no expertise in Android Development I am very thankful for any help an will surely send some $ as compensation for the result.
TASK:
The App/Service/Whatever should be able to open up a webpage, perform a click on that page on a button (follow all redirections, parse and use javascript, use cookies) just act like a normal Browser, but completely invisible.
I dont want to see any Icon or UI Interaction. Maybe its possible to realize that only on Shell (Terminal) Level.
The Final Webpage's HTML-Code should be saved in a file on the FileSystem (/data/Whatever/page.html).
The App is only for me, my device is rooted and Running Android 4.4.1 .
I hope that someone can help me.

process listing only showing 2 processes (in ps and top)

I've noticed on Android 7.0 with Nov 5th patch level, that "ps" and "top" are only showing two processes owned by me. I am running this on the on-device command line through the Terminal Emulator app. This is on a nexus 6. Fully stock. Not rooted. It used to show all running processes. Any idea how to get that back? Is this normal?
shamu:/ $ ps
USER PID PPID VSIZE RSS WCHAN PC NAME
u0_a104 31024 31006 3544 1184 sigsuspend b42a77ac S /system/bin/sh
u0_a104 31048 31024 4532 1264 0 ababb5f8 R ps
shamu:/ $ whoami
u0_a104
shamu:/ $
Yep, normal. Linux allows you to lock things away from normal users.
Marshmallow shows all processes, though. Is there no way to list all processes on the android command line anymore? This ps doesn't seem to take switches like regular Linux ps.
Here, read up about it; https://www.cyberciti.biz/faq/linux-hide-processes-from-other-users/
Hint: its "2".
Thanks for providing that detailed Linux info. It let me Google the specifics on Android.
Here is a bug filed about this, which Google shot down.
https://code.google.com/p/android/issues/detail?id=205565
And a discussion on Stack Overflow.
http://stackoverflow.com/questions/38590140/file-system-changes-in-android-nougat
I find this change unfortunate since it makes simply running top to see which proc is hogging my CPU impossible.
bat_in_the_stacks said:
Thanks for providing that detailed Linux info. It let me Google the specifics on Android.
Here is a bug filed about this, which Google shot down.
https://code.google.com/p/android/issues/detail?id=205565
And a discussion on Stack Overflow.
http://stackoverflow.com/questions/38590140/file-system-changes-in-android-nougat
I find this change unfortunate since it makes simply running top to see which proc is hogging my CPU impossible.
Click to expand...
Click to collapse
Just do it as root.

Programmatically Uninstall List of Apps

Hi,
I'm just starting to use Tasker, was wondering if it is possible to query a list of approved apps and uninstall everything else once a day. I am rooted.
Thanks
Ok, so I tinkered around and ended up putting together some task as follows:
I have a approved list (BaselineApps.txt)
I run the following command via Termux Task plugin.
pm list packages >/storage/emulated/0/Apps.txt
diff --unchanged-line-format= --old-line-format= --new-line-format='%L' /storage/emulated/0/BaselineApps.txt /storage/emulated/0/Apps.txt | sed 's/^[^:]*://' >/storage/emulated/0/NewApps.txt
Read file NewApps.txt to variable %Apps
ArraySet %Apps value %Apps
For each %eachapp in %Apps()
Run Shell pm uninstall %eachapp
End for
For the most part it works, except it errors out sometimes. Can someone please help me?
Thanks
It would be helpful for you to use the export "Description to Clipboard" feature within tasker. Then pasting that into a txt file and attaching it, or paying to pastebin.com then giving a link here. You could paste it into a post but the forum tends to convert things like "n" to emojis affecting readability.
If it's error-ing out, being specific about the error and when it happens would allow be helpful.
"Good judgment comes from experience, and a lot of that comes from bad judgment." - Will Rogers
Attached are the files.
The file named DiffApps.txt is the code that is run in termux. The other file is an export of the task in Tasker.
I'm not sure when it errors, I definitely errors when no new apps installed, put I think it also errors when there is only 1 app. I will need to test mpre to see what causes the error.
Thanks

Categories

Resources