4

I refer this information.

I write the same program, but I can't get any log info when I click uninstall button .

I attach my code below. Have anyone know what's problem in this code?

I want to do something when use click uninstall button. Maybe like turn on browser, etc.

Have any one can give me a hand?

The problem has confused me for a long time.

My AndroidManifest:

...

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

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
 <receiver android:name=".UninstallIntentReceiver" >
        <intent-filter>
           <action android:name="android.intent.action.QUERY_PACKAGE_RESTART" />
           <action  android:name = "android.intent.action.PACKAGE_REMOVED"  />
           <action  android:name = "android.intent.action.PACKAGE_ADDED"  />
           <data android:scheme="package"></data>
        </intent-filter>
    </receiver>
</application>

...

my BroadcastReceiver code below:

public class UninstallIntentReceiver extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {

    String [] packageNames = intent.getStringArrayExtra("android.intent.extra.PACKAGES");
    if(packageNames!=null){
        for(String packageName: packageNames){
            if(packageName!=null && packageName.equals("yu.idv.uninstalldetected")){
                Log.i("info", "00000000"); 
               new ListenActivities(context).start();
               Log.i("info", "11111111");

            }
        }
    }
  }

}

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){

         List< ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(MAX_PRIORITY);

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


         Log.i("info", "======CURRENT Activity =======::"
                 + activityName);

         if (activityName.equals("com.android.packageinstaller.UninstallerActivity")) {
             exit = true;
             Log.i("info", "2222222222");                
            Toast.makeText(context, "Done with preuninstallation tasks... Exiting Now",            Toast.LENGTH_SHORT).show();
        } else if(activityName.equals("com.android.settings.ManageApplications")) {
            exit=true;
             Log.i("info", "33333333333");
        }
    }
    Looper.loop();
}
Community
  • 1
  • 1
dickfala
  • 3,246
  • 3
  • 31
  • 52

2 Answers2

1

The reason that your BroadcastReceiver is not called is that your application is still in "stopped state". Your application doesn't have any Activity components. This means that after the application is installed there is no way for the user to start it. Applications that have never been started by the user stay in the "stopped state". Applications in the "stopped state" will not receive broadcast Intents.

See the section on "Launch controls on stopped applications" in http://developer.android.com/about/versions/android-3.1.html


EDIT: Add more details regarding Intent.ACTION_QUERY_PACKAGE_RESTART in Android 4.x

It seems that this behaviour has changed since Android 2.3 (I'm not sure about Android 3.x). In Android 4.0 and above, the code in InstalledAppDetails (part of the Settings application) looks like this:

 private void checkForceStop() {
     if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) {
         // User can't force stop device admin.
         updateForceStopButton(false);
     } else if ((mAppEntry.info.flags&ApplicationInfo.FLAG_STOPPED) == 0) {
         // If the app isn't explicitly stopped, then always show the
         // force stop button.
         updateForceStopButton(true);
     } else {
         Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART,
                 Uri.fromParts("package", mAppEntry.info.packageName, null));
         intent.putExtra(Intent.EXTRA_PACKAGES, new String[] { mAppEntry.info.packageName });
         intent.putExtra(Intent.EXTRA_UID, mAppEntry.info.uid);
         getActivity().sendOrderedBroadcast(intent, null, mCheckKillProcessesReceiver, null,
                 Activity.RESULT_CANCELED, null, null);
     }
 }

So, if the application being shown is a device admin, the "force stop" button will be disabled. If the application being shown is not stopped, then the "force stop" button will be enabled. Otherwise, Intent.ACTION_QUERY_PACKAGE_RESTART will be broadcasted.

This means that the Intent will only be broadcasted for non-device-admin applications that are already stopped.

I tested this on a 4.0 device with your code. If you install your application, then you go to Settings->Apps and choose another application (not yours) that has been "force stopped", your onReceive() is called with Intent.ACTION_QUERY_PACKAGE_RESTART.

I realized this probably isn't much help, but it at least explains the behaviour that you are seeing.

Sorry it took so long to solve this, and thanks for the challenge :-)

azizbekian
  • 60,783
  • 13
  • 169
  • 249
David Wasser
  • 93,459
  • 16
  • 209
  • 274
  • I had tried to add activity. But I still can't receive broadcast intetns.@@ – dickfala Dec 24 '13 at 02:16
  • Did you actually start the application (ie: launch the activity) after installing the application? – David Wasser Dec 24 '13 at 08:10
  • Yes, I have launch my activity. I attach my source code site. https://www.dropbox.com/s/0bgbcfn0a0gfoe3/UninstallDetected.zip :( – dickfala Dec 31 '13 at 02:42
  • OK. Are you uninstalling your own application? or another application? Ist `onReceive()` called when you try to uninstall another application? – David Wasser Jan 02 '14 at 14:53
  • I was used android menu function - setting > application > selected my application name(uninstallDetected) > click uninstall button > click sure. This time , I see logcat which not show my log information. @@ – dickfala Jan 03 '14 at 07:31
  • What version of Android are you testing on? – David Wasser Jan 03 '14 at 08:45
  • my device android version is 4.0.3 – dickfala Jan 03 '14 at 09:00
  • Thanks your response. Can you offer you complete project file to me? I want to see complete test file, "checkForceStop" method put where and the mDpm what is meaning? thank you very much. – dickfala Jan 06 '14 at 03:05
  • The code I posted is from the source code of the Android Settings application. You can find the whole thing here: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android-apps/4.0.1_r1/com/android/settings/applications/InstalledAppDetails.java/ If you compare the 4.0 version of `checkForceStop()` and the 2.x version you can see that this code has changed. – David Wasser Jan 06 '14 at 09:30
  • Thank you David Wasser~ I will research. – dickfala Jan 08 '14 at 08:03
  • @dickfala Nice example.I have test your code with my devices which has android 4.1.2 and 4.0.4 but unfortunately its not working means not showing any log in Logcat.So I want to know that is it working perfectly? – Nitish Patel Jan 28 '14 at 10:39
  • @nitishpatel If you are having trouble, I'd suggest that you post a new question that includes your code and a description of the problem. I don't think a comment thread in this answer is the best way to resolve your problem. – David Wasser Jan 28 '14 at 11:08
  • @DavidWasser as per your suggestion I have posted new question please check it out.[link](http://stackoverflow.com/questions/21404413/uninstall-application-uninstallreceiver-not-called) – Nitish Patel Jan 28 '14 at 11:30
  • @dickfala I have tested your code its work fine on android 2.3 OS devices but it will not work on android 4.0 or above.Do you know whats wrong? – Nitish Patel Jan 29 '14 at 11:37
  • @nitishpatel as you can see from my answer, this no longer works on Android 4.0. – David Wasser Jan 29 '14 at 11:46
  • @DavidWasser ok..thank you for your help but if I want to do same thing for 4.0 or above any other way is there ? – Nitish Patel Jan 29 '14 at 12:26
  • @nitishpatel as far as I know this isn't possible. There may be some hacks that allow this, but I don't know how they work. Sorry. – David Wasser Jan 29 '14 at 12:47
  • @nitish patel ha ha , I am not try out the question in android 2.3 and android 4.0. But I used to see some App was deleted, mobile turn on the browser. I don't know how to implement the function. – dickfala Feb 05 '14 at 00:39
0

Generally when you are uninstalling the application, all the resources are removed from the device. so you can not trigger any action at the time of un-installing

Ram kiran Pachigolla
  • 20,897
  • 15
  • 57
  • 78
  • If detected the user click uninstall button(not uninstall over), the application can recored the package name in logcat. We can use the logcat info parse packagename to do something. I think the refer meaning is [this](http://stackoverflow.com/questions/18692571/how-it-works-warning-that-app-is-going-to-be-uninstalled). But I can't implement @@. – dickfala Dec 20 '13 at 08:59
  • Can you post how to customize uninstall intent action? I really need learn how to implement. Thank you very much. – dickfala Dec 20 '13 at 09:06
  • @dickfala I am trying to get uninstaller intent name from logcat but till date what my observation is that logcat is may be caching all data.So history intents also when I start my app to read logcat.AS soon as I solved this I will share with it if I get succeed. – Nitish Patel Feb 05 '14 at 05:44