How to know when the user has closed the Android application? - android

Is there any way of finding when an application is closed (either by user or system) i.e the application can only be restarted by the user by pressing the application launcher icon.
I think it is only possible if Android system broadcast any Intent when a name of a process is removed from getRunningAppProcesses().
I have read all the possible Q&A on the SO and the question is not related with the ActivityLifecycle.

Generally, waiting for a user to "exit" an app is a bad idea, since:
The user never actually exists the app, they simply leave it on the activity stack and come back to it later.
A user might do anything during your database update, such as reenter the app.
You can't really detect this without very hacky solutions; this is by design of the API, because you shouldn't need to do these kinds of things.
Because of this, I think any solution based on waiting for the app to "die" is a bad one. Instead, you should come up with a solution that respects the semantics of the application. For example, if you are entering data in one of its content providers then it should handle consistency (across fragments in the app, for example).

Hmm.. You can manually monitor /proc on the filesystem to see if the process id is present for the application you care about.
From your terminal window try the following. For example :
> MYPID=(`adb shell ps | grep com.mydomain.myapp | awk '{print $2}'`)
> adb shell [ -d /proc/$MYPID ] && echo "PID $MYPID Exists"
Replace com.mydomain.myapp with your apps package name
There are several apps available to monitor processes on android.
Take a look at http://code.google.com/p/android-os-monitor/
The android-os-monitor project uses a JNI layer to implement the interaction with /proc
http://code.google.com/p/android-os-monitor/source/browse/OSMonitor/jni/process.c?repo=osmonitor
http://code.google.com/p/android-os-monitor/source/browse/OSMonitor/src/com/eolwral/osmonitor/JNIInterface.java?repo=osmonitor
http://code.google.com/p/android-os-monitor/source/browse/OSMonitor/src/com/eolwral/osmonitor/processes/ProcessList.java?repo=osmonitor

Related

I can't get the activity name using adb shell

I know that many people already sent questions similar to this. However, this is a little different.
I have to try to get the current activity from an android app, but it is not possible. Normally, I interact with the app and execute this: adb shell dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp'. However, it always shows MainActivity. I checked the activity list on APK Info and this list is so little
So, there is some way to start a specific screen of apps similar to this?

Detecting the Android keyboard with Calabash?

I am writing a series of automated tests for an android app using calabash-android and I need to be able to detect whether the android system keyboard is visible or not and (if possible) read some of the keys (i.e. if the return key says Done instead of Next or Enter). I know there is the keyboard_visible? commands for iOS but I have not been able to find anything similar for android.
Has anyone built their own functions to handle these instances?
there is a way to take a dump of the screens current contents on android using a tool called uiautomator from the android SDK. You can then check this for whatever you need to. It's not the most elegant solution but it might just work. Have a look at this post.
Calabash handling "Complete action using" dialog
windown_input_method = %x(adb -s #{ENV['ADB_DEVICE_ARG']} shell dumpsys window InputMethod | grep "mHasSurface")
windown_input_method.include?("isReadyForDisplay()=true")
This one returns true if keyboard is visible and false if not
ENV['ADB_DEVICE_ARG'] is environmental variable holding the device id of your android device connected. If you always run on one device, simply
windown_input_method = %x(adb shell dumpsys window InputMethod | grep "mHasSurface")
windown_input_method.include?("isReadyForDisplay()=true")
will do

Android : can native code get broadcast intent from android system? [duplicate]

This question already has answers here:
Listen to own application uninstall event on Android
(3 answers)
Closed 7 years ago.
Recently i've seen a funny app - Photo Wonder.
When this app is uninstalled, it shows a web survey page asking for the reason of app uninstall. Now, here is the problem.
As far as I know, after an app has been removed, the system broadcasts ACTION_PAKAGE_REMOVED intent.
But this funny app was able to show my the web page although the official doc says
"The package that is being installed does not receive this Intent."
Anyhow, I could find a process checking some kind of status of the app.
Now here is the question. Can the native app catch the broadcasted intent from android system?
If it is possible, please let me know how! :-(
I believe I've got the main idea of how they did it. Here is the pieces of the puzzle.
Any Android application can start a process by calling Runtime.exec() function.
Runtime.getRuntime().exec("chmod 755 '/data/data/my.app/files'/native_code");
After this line of code gets executed there is another process spawned. This process runs under the same linux user as the application itself.
When a user opens Settings -> Apps -> My App and presses "Force stop" button, main application process gets killed, but the process hosting native program (see above) still runs. I personally believe this is a security issue and I am going to report it back to AOSP.
Such native program can run infinitely and do nothing - just sleeping. But before going to sleep, it registers a termination signal handler which will be called when process is about to be terminated by the system.
int main(void) {
signal(SIGTERM, termination_handler);
while(1) {
sleep(10);
}
}
void termination_handler(int sig) {
// handle termination signal here
}
Now you should already know what the last piece is, right? My native termination_handler should be able to launch a browser. I didn't try this in code, but I assume this is possible, because I can do it using adb shell as following
adb shell am start -a android.intent.action.VIEW -d http://www.google.com
Now back to the question about how Dolphin Browser does it. Install the app and launch it at least once. Once started, it registers a native uninstall watcher using the principles described above. To see it, connect to the device and open adb shell. Then call ps to see list of processes. You will see two processes similar to following
u0_a109 315 ... mobi.mgeek.TunnyBrowser
u0_a109 371 ... /data/data/mobi.mgeek.TunnyBrowser/files/watch_server
As you can see it starts a watch_server native program, which is a part of its apk-file. Now open App info page of Dolphin Browser and press "Force Stop". Switch back to terminal and call ps again. You will see there is no mobi.mgeek.TunnyBrowser process anymore, but watch_server still runs.
By the way this approach will only work, if watcher server runs all the time. To
make sure it is always up, both apps require "run at startup"
permission, where they start their watchers.
Now, when you uninstall the app, Android stops all processes belonging to this application. Watcher receives termination signal and opens browser with predefined URL and then shuts down.
I might look a bit different in some details, but the main concept behind this hack must be as described.
There could be a tricky thing like that application is also having watcher service.
You can check the permission used by that app may contain INSTALL and UNINSTALL permissions.
HOW IT WORKS:
instead of single app that may have 2 app bundle.
as and when you install it, this app is also installing some service that is watching your app status
When you try to uninstall that app the system broadcast is called which is handled by that service and will check that if your package is exist in installed application or not.
as soon as this service finds that your package is not in the list it calls an intent with action view with the web url to open the brawser.

Logging file access in Android

I'm having trobule trying to create a custom file access logger for Android. I've check FileObsever but I need to get the PID (USERID would be useful also) of the process that had access to a certain list of files.
I've also tried different options but with no success.
Is is possible to log with PID accessed certain file?
Regards!
There's been some discussion of adding PID reporting to the Linux inotify() mechanism (which is what FileObserver is presumably based on), but I'm not finding out from initial searches if that was actually merged and thus inherited by Android - and if it was, it would likely only work for foreign UID's for a monitor with administrative privileges.
You could try the FileObserver and then immitate lsof by scanning through /proc for fd's, to whatever (limited?) extent you'd be allowed to do so on Android. This would however give you race condition issues - the file could be closed again before you saw "who done it".
Likely if you really want to do this, you'll need a custom ROM - you could apply any necessary patches to inotify and either bless your security app with permissions or (if you prefer to be that way) disable the permission checks on reporting.
What I found about the patch - current merge status unknown:
http://lwn.net/Articles/307536/
Intro to direct use of inotify() (without the PID reporting):
http://www.linuxjournal.com/article/8478?page=0,0

Stop running application with ADB

is there a simple way to stop a running application using ADB.
Szenario:
Working on App
Have a script which uploads, installs and starts App on change
Problem:
Currently running version gets killed (not shutdown), which make testing cleanup very hard. Option would be to "do cleanup in between", like after a certain time, but I would prefer to do it in the correct location (so like with the OS, as long as the App is still running, so need to save value, as soon as the OS tells me e.g. memory low or calls onDestroy, I want to save stuff)
Chris
I'm not aware of a way to do this. I was hoping there might be a way to send an intent to tell the app to exit using adb shell e.g.
adb shell am start -a [intent] -n [class]
However, I found that somebody asked this question on a Google forum but they haven't got an answer:
http://groups.google.com/group/android-platform/browse_thread/thread/3fd02d01c6c3b41a/56814e518503efd6

Categories

Resources