Android shell get foreground app package name [duplicate] - android

This question already has answers here:
ADB - Android - Getting the name of the current activity
(13 answers)
Closed 5 years ago.
I'm using tasker to automate the SMS sending for which I need to check if the current foreground app package name is x. If it is x then do something else do something else. I tried to use pgrep but it returns the pid even when the app x is in the background. Is there a way to check from shell if x is in foreground?
Thanks

This worked for me:
adb shell dumpsys window windows | grep -E 'mCurrentFocus' | cut -d '/' -f1 | sed 's/.* //g'
com.facebook.katana
Updated answer for Android Q as mCurrentFocus was no longer working for me:
adb shell dumpsys activity recents | grep 'Recent #0' | cut -d= -f2 | sed 's| .*||' | cut -d '/' -f1

The accepted answer might give unexpected results in many cases.
Some UI elements (e.g., dialogs) will not show the package name on the mCurrentFocus (neither mFocusedApp) field. For example, when an app throws a dialog, the mCurrentFocus is often the dialog's title. Some apps show these on app start, making this approach unusable to detect if an app was successfully brought on foreground.
For example, the app com.imo.android.imoimbeta asks for the user country at start, and its current focus is:
$ adb shell dumpsys window windows | grep mCurrentFocus
mCurrentFocus=Window{21e4cca8 u0 Choose a country}
The mFocusedApp is null in this case, so the only way to know which app package name originated this dialog is by checking its mOwnerUID:
Window #3 Window{21d12418 u0 Choose a country}:
mDisplayId=0 mSession=Session{21cb88b8 5876:u0a10071} mClient=android.os.BinderProxy#21c32160
mOwnerUid=10071 mShowToOwnerOnly=true package=com.imo.android.imoimbeta appop=NONE
Depending on the use case the accepted solution might suffice but its worth mentioning its limitations.
A solution that i found to work so far:
window_output = %x(adb shell dumpsys window windows)
windows = Hash.new
app_window = nil
window_output.each_line do |line|
case line
#matches the mCurrentFocus, so we can check the actual owner
when /Window #\d+[^{]+({[^}]+})/ #New window
app_window=$1
#owner of the current window
when /mOwnerUid=[\d]+\s[^\s]+\spackage=([^\s]+)/
app_package=$1
#Lets store the respective app_package
windows[app_window] = app_package
when /mCurrentFocus=[^{]+({[^}]+})/
app_focus=$1
puts "Current Focus package name: #{windows[app_focus]}"
break
end
end

Related

Termux: pkg update shows "Waiting for cache lock" and it doesn't seem to stop

I just downloaded Termux and used the 'pkg upgrade' command, then it showed me showed some options:
Y or () | Upgrade... (I can'tremember what)
N or () | Keep current version
D | Show differences
()
()
I then pressed D to see the differences, and a long manual-like text appeared.
But I didn't know how to exit and press either Y or N. I tried some things but no luck. So I closed Termux and exit from the notifications and tried again.
However, this time I couldn't get 'pkg upgrade' to work. Instead this was shown:
Running Processes:
Now, the second count goes above 5000s...
You need to wait for apt to finish the task before starting another apt task.

Android: How to process output of Runtime.getRuntime().exec() calling dumpsys on rooted phone

I am working on a small proof of concept on a rooted phone, which relys on being able to read dumpsys output.
If I call dumpsys on my (rooted) phone running Android 11 like this, using adb:
adb shell dumpsys telephony.registry | grep "mCi="
I get a pretty long printout. The grep filters for lines containing cell tower IDs, but that shouldn't e important here (it's just an example). Now I'm trying to execute the same command inside a very simple app, and log its output, like this:
private fun test() {
try {
val process = Runtime.getRuntime().exec("su dumpsys telephony.registry | grep \"mCi=\"")
val bufferedReader = BufferedReader(InputStreamReader(process.inputStream))
val string = bufferedReader.readText()
Timber.d("output: $string")
bufferedReader.close() // do I need this?
} catch (e: IOException) {
// handle Exception
}
}
I get no output at all (string length is 0). If I replace my process command with something simple like this: Runtime.getRuntime().exec("echo 'abcde'") the output is logged as intended (output: 'abcde').
I also tried shortening the possible output, in case that was the problem by appending --max-count=1, to have grep only put out the first found line. Again, it works using adb, does not work in code.
what am I doing wrong?
(I am using Timber to print my logs, if anyone doesn't know what that line is in the xample.)
The first thing you should do is to log the stderr stream that is available for your process as well. This will give you information about what is wrong with your command.
Your command is not correctly processed as it is seen as one command. The reason is explained in this answer.
The solution is to use a String[] as an argument of exec and explicitly execute the command with the shell. I wrote some code that executes your command, but it is in Java on an unrooted device. Still, it generates output and grep works.
String[] arrayCommand = {"sh", "-c","dumpsys telephony.registry | grep \"permission\""};
Runtime r = Runtime.getRuntime();
Process process = r.exec(arrayCommand);
String stdoutString = convertInputStreamToString(process.getInputStream());
String stderrString = convertInputStreamToString(process.getErrorStream());

ADB starting activity with extra string data [duplicate]

This question already has an answer here:
Send Intent to Start Activity With String Extras Via ADB
(1 answer)
Closed 1 year ago.
I am executing the following from ADB:
PS C:\> adb shell am start -a android.intent.action.MAIN -n boha.notify/.MainActivity -e primaryheader "One Two" -e primarytext "Primary text"
Starting: Intent { act=android.intent.action.MAIN pkg=Two cmp=boha.notify/.MainActivity (has extras) }
Warning: Activity not started, its current task has been brought to the front
PS C:\>
My application is setup to properly handle the new intent request without restarting the already running activity. I've overridden onNewIntent() as required. It's shown below:
#Override
protected void onNewIntent(Intent intent)
{
super.onNewIntent(intent);
Log.d( "AGENT", "NEW INTENT Extra data = " + intent.getStringExtra("primaryheader"));
String strPrimaryHeader = intent.getStringExtra("primaryheader");
String strPrimaryText = intent.getStringExtra("primarytext");
String strSecondayHeader = intent.getStringExtra("secondaryheader");
String strSecondaryText = intent.getStringExtra("secondarytext");
}
When I check the logcat I see that the extra data strings I'm passing in aren't being received correctly. Only the first word of each string is correct.
See below:
09-13 18:30:36.583 12248-12248/? D/AGENT: NEW INTENT Extra data = One
Why is the activity new intent only receiving "One" instead of "One Two"?
Am I not using the correct ADB am command parameters?
Use --es for string extras
adb shell am start -a android.intent.action.MAIN -n boha.notify/.MainActivity --es primaryheader "One Two" --es primarytext "Primary text"
I have explained the root cause multiple times before. It's because you have multiple sub shells. And when the outer shell (in your case powershell) parses the command it eats the " (i.e. uses them for properly splitting the command into separate command line parameters). But this information (that your multi word string is a single parameter) gets lost by the time the command reaches the inner shell (the /bin/sh of your android device). So as the result it launches the am command with every word being a separate parameter.
The easiest way to mitigate that is to double-quote the whole adb shell subcommand and use single quotes for the internal strings:
PS C:\> adb shell "am start -a android.intent.action.MAIN -n boha.notify/.MainActivity -e primaryheader 'One Two' -e primarytext 'Primary text'"

Filtering Logcat Logs on commandline

public static final TAG = "Legendry Eagle";
Issue: I want to see logs of "Legendry Eagle" from the commandline.
I tried:
adb logcat -s "Legendry Eagle"
adb logcat -s <Legendry Eagle>
But Still it is not working.
If you only want to show logcat for a specific TAG, do it like this:
adb logcat YourTAGHere:Priority *:S
The *:S is important, as it sets all other tags to silent. If I want to track only my MainActivity tag at Verbose level, the syntax would look like this.
adb logcat MainActivity:V *:S
Edit:
I found no good way of filtering out tags with spaces. LegendryEagle works fine, but I was not able to filter out Legendry Eagle
If the standard adb logcat -s tagname doesn't work, you can always pipe the output of adb to find to filter what you need, something like
adb logcat | find "Legendry Eagle"
This passes the entire logcat to DOS find command, which in turn filters out rows containing Legendry Eagle string.
adb logcat | grep "your tag"
will only display logs with "your tag"
Answer is very simple . Please remove space between two words and try again.
public static final TAG = "LegendryEagle";
adb logcat -s "LegendryEagle"
and see the logcat . You got your answer.
use this command adb logcat *:W and read this. http://developer.android.com/tools/debugging/debugging-log.html
Assuming you are using Eagle as the logging tag, use this:
adb logcat Eagle:* *:s
as I understand the Eagle:* means to turn on all logs for the Eagle tag, and the *:s means to make all other tags silent
I personally find the eclipse logcat view much easier to use than the command line, it has different colors for different levels of logs, and you can create a filter and save it, it'll stay there forever until you delete that filter

Switch from native-activity to a normal java activity

I am creating a game for android. The native activity is used for the main part of the game but i want to be able to switch to a java activity. I've searched almost all android header files but i cant find any function which allows me to switch activity.
Is there some way i can start a java activity?
The am command from the shell can be used to send Intents to Actvities. In the source code of SuperUser you can find, for instance:
char sysCmd[1024];
sprintf(sysCmd, "am start -a android.intent.action.MAIN -n com.koushikdutta.superuser/com.koushikdutta.superuser.SuperuserRequestActivity --ei uid %d --ei pid %d > /dev/null", g_puid, ppid);
if (system(sysCmd))
return executionFailure("am.");

Categories

Resources