简体   繁体   English

应用程序卸载时无法获取接收器

[英]Can't get receiver when the app uninstall

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: 我的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: 我的BroadcastReceiver代码如下:

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();
}

The reason that your BroadcastReceiver is not called is that your application is still in "stopped state". 不调用BroadcastReceiver的原因是您的应用程序仍处于“停止状态”。 Your application doesn't have any Activity components. 您的应用程序没有任何Activity组件。 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 请参阅http://developer.android.com/about/versions/android-3.1.html中的 “启动已停止的应用程序控件”部分


EDIT: Add more details regarding Intent.ACTION_QUERY_PACKAGE_RESTART in Android 4.x 编辑:在Android 4.x中添加有关Intent.ACTION_QUERY_PACKAGE_RESTART更多详细信息

It seems that this behaviour has changed since Android 2.3 (I'm not sure about Android 3.x). 从Android 2.3开始,这种行为似乎发生了变化(我不确定Android 3.x)。 In Android 4.0 and above, the code in InstalledAppDetails (part of the Settings application) looks like this: 在Android 4.0及更高版本中, InstalledAppDetails (Settings应用程序的一部分)中的代码如下所示:

 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. 否则,将广播Intent.ACTION_QUERY_PACKAGE_RESTART

This means that the Intent will only be broadcasted for non-device-admin applications that are already stopped. 这意味着只会为已停止的非设备管理应用程序广播Intent

I tested this on a 4.0 device with your code. 我用你的代码在4.0设备上测试了这个。 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 . 如果您安装了应用程序,那么您转到Settings->Apps并选择另一个已经“强制停止”的应用程序(不是您的应用程序) ,使用Intent.ACTION_QUERY_PACKAGE_RESTART调用onReceive()

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 :-) 对不起,解决这个问题花了这么长时间,并感谢您的挑战:-)

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 因此,在卸载时无法触发任何操作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM