How to Show an Activity Before My App Is Uninstalled (Android)

How to show an Activity BEFORE my app is uninstalled (Android)

I noticed that NQ Mobile Security is able to show a message after I click on Uninstall and before the PackageUninstaller is called

They must be exploiting some security flaw in Android. I will research it and see if I can get it fixed. Apps are not supposed to get control at uninstall time.

Thanks for pointing this out!

Is there a different way to intercept your application UNINSTALL event?

I sure hope not.

How to start an Activity or Service before an App application is uninstalled by the User?

As @CommonsWare said The techniques used by NQ Mobile Security have been reported to the Android Security group, and they are working on a fix to stop this behavior from occurring. and have raised a feature request with Google hopefully they may listen to it.

http://code.google.com/p/android/issues/detail?can=2&q=33315&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars&id=33315

How can I do something before uninstalling my android app?

This is not possible, sorry. If you put your files in the proper directories, they will be deleted automatically, but no other work can be done when your app is uninstalled.

An Android app remembers its data after uninstall and reinstall

It's because Android 6 has automatic backup. You need to tune android:allowBackup and android:fullBackupContent in your manifest <application> tag if you don't want your data backed up or if you want to include or exclude some resources. It's not a bug.

More about AutoBackup on Android here.

How to get action that android application is trying removed/uninstalled from device

Please try to get the top activity in the task via ActivityManager, and check if it is the uninstall activity.

Core code:

ComponentName topActivity = mActivityManager.getRunningTasks(1).get(0).topActivity;
String packageName = topActivity.getPackageName();
String className = topActivity.getClassName();
Log.v(TAG, "packageName" + packageName);
Log.v(TAG, "className" + className);

if ("com.android.packageinstaller".equals(packageName)
&& "com.android.packageinstaller.UninstallerActivity".equals(className)) {
//Do anything you want here
}

Is it possible to detect Android app uninstall?

Unfortunately the ACTION_PACKAGE_REMOVED intent will be sent out to all receivers except for your own. This is confirmed here.

Some questions for your C2DM plan, since I'm not very familiar with it. If the user just leaves their device off for a long period of time, will that trigger the error condition you use? How does C2DM actually report an "unreachable" device? Is that a condition that only occurs when it attempts to send the push notification and fails or is it when it somehow determines it reaches the device but fails to be handled properly? Obviously in the second scenario your plan would work, but I can see some "false positives" occurring otherwise.

Older SO question for reference: android not receiving Intent ACTION_PACKAGE_REMOVED in the removed package

How can an app detect that it's going to be uninstalled?

Okay. I have been investigating a lot on this problem since 2 days and finally found a "wild way" to solve it without rooting the device :)

First, here are the highlights to achieve the solution:

1. Whenever user goes to Settings -> Manage Apps -> Selects a particular application
we receive a broadcast android.intent.action.QUERY_PACKAGE_RESTART with name of the application's package as extras.

2. After that when we click on the Uninstall button (with package installer), it opens an activity named - com.android.packageinstaller.UninstallerActivity

Control flow will be like:

Under App Settings the User Clicks on Uninstall button ---> We get control to show a dialogue / start another activity / etc ---> We finish our Pre-Uninstallation task ---> User is Returned back to Uninstallation confirmation screen ---> User confirms and uninstalls the app

Used Method:

We will implement a BroadcastReceiver in our application for listening the action "android.intent.action.QUERY_PACKAGE_RESTART" and match our package name inside onReceive() method. If the broadcast was received for selection of our desired application package, then we'll initiate a background thread that will keep monitoring the foreground running activities using the ActivityManager.

Once we find the foreground activity to be "com.android.packageinstaller.UninstallerActivity", it'll be confirm that user wants to uninstall our application. At this point we'll perform the desired tasks (either display a dialogue, or start another activity overlapping the uninstallation window, etc..) that are to be performed before uninstallation. After performing our task, we'll allow the user to continue with confirming the uninstallation process.

Implementation / Source Code:

In manifest.xml

add permission:

<uses-permission android:name="android.permission.GET_TASKS"/>

and broadcast receiver:

<receiver android:name=".UninstallIntentReceiver">
<intent-filter android:priority="0">
<action android:name="android.intent.action.QUERY_PACKAGE_RESTART" />
<data android:scheme="package" />
</intent-filter>
</receiver>

UninstallIntentReceiver.java (broadcast receiver class)

public class UninstallIntentReceiver extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
// fetching package names from extras
String[] packageNames = intent.getStringArrayExtra("android.intent.extra.PACKAGES");

if(packageNames!=null){
for(String packageName: packageNames){
if(packageName!=null && packageName.equals("YOUR_APPLICATION_PACKAGE_NAME")){
// User has selected our application under the Manage Apps settings
// now initiating background thread to watch for activity
new ListenActivities(context).start();

}
}
}
}

}

ListenActivities class - for monitoring the foreground activities

class ListenActivities extends Thread{
boolean exit = false;
ActivityManager am = null;
Context context = null;

public ListenActivities(Context con){
context = con;
am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
}

public void run(){

Looper.prepare();

while(!exit){

// get the info from the currently running task
List< ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(MAX_PRIORITY);

String activityName = taskInfo.get(0).topActivity.getClassName();

Log.d("topActivity", "CURRENT Activity ::"
+ activityName);

if (activityName.equals("com.android.packageinstaller.UninstallerActivity")) {
// User has clicked on the Uninstall button under the Manage Apps settings

//do whatever pre-uninstallation task you want to perform here
// show dialogue or start another activity or database operations etc..etc..

// context.startActivity(new Intent(context, MyPreUninstallationMsgActivity.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
exit = true;
Toast.makeText(context, "Done with preuninstallation tasks... Exiting Now", Toast.LENGTH_SHORT).show();
} else if(activityName.equals("com.android.settings.ManageApplications")) {
// back button was pressed and the user has been taken back to Manage Applications window
// we should close the activity monitoring now
exit=true;
}
}
Looper.loop();
}
}

Known Limitations:

When the user clicks on the Uninstall button under Manage Apps settings, we'll perform our pre-uninstallation tasks and then promt the user to the Confirmation window where user can either confirm to uninstall or can Cancel the operation.

The approach described above is as of now not covering the case if user clicks on Cancel button after we have performed our task. But this could be tackled easily with some ammendments.

E.g.: We can implement a logic to revert the changes we made if the broadcast "android.intent.action.PACKAGE_REMOVED" was not received in the end.

I hope this approach will be helpful to you :) As this is the only way in my opinion we can solve your problem without rooting the device!

[Update 1]:
Suggested Approach to check if the Uninstallation task was Canceled:

Its kind of funny that I had entirely different and much complex idea earlier(involving broadcasts, ActivityManager, etc.. etc..), but while writing it here just another idea struck into my mind which is comparatively very simple :)

When the User clicks on Uninstall button under Manage Apps settings and after you have performed your pre-uninstallation tasks, you just set some SharedPreference in your app that you have performed the pre-uninstall tasks and are ready for uninstallation. After this you need not to care about anything.

If the user continues to uninstall -> its well and good as you have already performed required tasks.

While if user finally clicks on Cancel button and goes away -> don't bother. Until the user goes and run your application again. Now inside "onStart()" / "onResume()" of your application's main activity, you can check the SharedPreference's value and if it was set for uninstallation, that will mean that user didn't finally proceeded with the uninstallation. And now you could revert the changes made earlier(reversing the pre-uninstall tasks performed) to ensure that your application runs perfectly!

Tracking uninstall of android app

You can maintain a table of users actively using your app.After that call a Webservice at a fixed point in your code that will show if it is active or not. If the app is not used for a certain time which you can call expiretime, then you can call it as inactive.

Otherwise you can Use GCM.
From GCM documentation: "An application can be automatically unregistered after it is uninstalled from the device. However, this process does not happens right away, as Android does not provide an uninstall callback."

Actaully, the device will tell GCM the application was uninstalled when GCM tries to send the next push notifiaction.

Such as,While notifying friends, GCM will send a NotRegistered error to your notification server when this failure occurs but it won't be immediate.



Related Topics



Leave a reply



Submit