无法获取接收器时,应用程序卸载 [英] Can't get receiver when the app uninstall

查看:344
本文介绍了无法获取接收器时,应用程序卸载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我指<一个href="http://stackoverflow.com/questions/18692571/how-it-works-warning-that-app-is-going-to-be-uninstalled">this信息。

我写相同的程序,但我不能得到任何的日志信息,当我点击卸载按钮。

我在下面附上我的code。有没有人知道在这code问题?

我想要做的事情时,使用点击卸载按钮。也许就像打开浏览器,等等。

有任何人可以给我个忙吗?

这个问题已经困惑我很久了。

我的Andr​​oidManifest:

...        

 &LT;使用-权限的Andr​​oid:名称=android.permission.GET_TASKS/&GT;
&LT;使用-权限的Andr​​oid:名称=android.permission.RESTART_PACKAGES/&GT;

&lt;应用
    机器人:allowBackup =真
    机器人:图标=@可绘制/ ic_launcher
    机器人:标签=@字符串/ APP_NAME
    机器人:主题=@风格/ AppTheme&GT;
 &LT;接收机器人:名称=。UninstallIntentReceiver&GT;
        &LT;意向滤光器&gt;
           &lt;作用机器人:名称=android.intent.action.QUERY_PACKAGE_RESTART/&GT;
           &lt;作用机器人:名称=android.intent.action.PACKAGE_REMOVED/&GT;
           &lt;作用机器人:名称=android.intent.action.PACKAGE_ADDED/&GT;
           &lt;数据机器人:计划=一揽子&GT;&LT; /数据&GT;
        &所述; /意图滤光器&gt;
    &LT; /接收器&GT;
&LT; /用途&gt;
 

...

我的BroadcastReceiver $ C $低于C:

 公共类UninstallIntentReceiver扩展的BroadcastReceiver {

@覆盖
公共无效的onReceive(上下文的背景下,意图意图){

    的String [] packageNames = intent.getStringArrayExtra(android.intent.extra.PACKAGES);
    如果(packageNames!= NULL){
        对于(字符串的packageName:packageNames){
            如果(的packageName = NULL和放大器;!&安培; packageName.equals(yu.idv.uninstalldetected)){
                Log.i(信息,00000000);
               新ListenActivities(上下文)。开始();
               Log.i(信息,11111111);

            }
        }
    }
  }

}

类ListenActivities继承Thread {
布尔退出= FALSE;
ActivityManager AM = NULL;
上下文的背景下= NULL;

公共ListenActivities(上下文CON){
    上下文= CON;
    AM =(ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
}

公共无效的run(){

    活套prepare()。

    而(!出口){

         名单&LT; ActivityManager.RunningTaskInfo&GT; taskInfo = am.getRunningTasks(MAX_PRIORITY);

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


         Log.i(信息,==当前活动======= ::
                 + activityName);

         如果(activityName.equals(com.android.packageinstaller.UninstallerActivity)){
             退出= TRUE;
             Log.i(信息,2222222222);
            Toast.makeText(背景下,完成与preuninstallation任务......现在退出,Toast.LENGTH_SHORT).show();
        }否则,如果(activityName.equals(com.android.settings.ManageApplications)){
            退出= TRUE;
             Log.i(信息,33333333333);
        }
    }
    Looper.loop();
}
 

解决方案

这是你的的BroadcastReceiver 不叫的原因是,你的应用还处于停止状态。您的应用程序没有任何活动组件。这意味着,应用程序安装后也没有办法让用户启动它。从未被启动用户停留在停止状态应用程序。在应用程序中的停止状态将不会收到广播意图

的http:// developer.android.com/about/versions/android-3.1.html


编辑:添加有关的详细信息 Intent.ACTION_QUERY_PACKAGE_RESTART 中的Andr​​oid 4.x版

看来,这种行为已经由于Android 2.3(我不知道关于Android 3.X)改变​​。在安卓4.0及以上时, InstalledAppDetails 的code(在设置应用程序的一部分)看起来是这样的:

 私人无效checkForceStop(){
     如果(mDpm.packageHasActiveAdmins(mPackageInfo.packageName)){
         //用户不能强制停止装置管理员。
         updateForceStopButton(假);
     }否则,如果((mAppEntry.info.flags&安培; ApplicationInfo.FLAG_STOPPED)== 0){
         //如果应用程序没有明确停止,则始终显示
         //部队停止按钮。
         updateForceStopButton(真正的);
     } 其他 {
         意向意图=新的意图(Intent.ACTION_QUERY_PACKAGE_RESTART,
                 Uri.fromParts(包,mAppEntry.info.packageName,NULL));
         intent.putExtra(Intent.EXTRA_PACKAGES,新的String [] {m​​AppEntry.info.packageName});
         intent.putExtra(Intent.EXTRA_UID,mAppEntry.info.uid);
         getActivity()。sendOrderedBroadcast(意向,空,mCheckKillProcessesReceiver,空,
                 Activity.RESULT_CANCELED,NULL,NULL);
     }
 }
 

因此​​,如果应用程序正在显示的是设备管理,强制停机按钮将被禁用。如果所显示的应用程序的没有停止,然后在强制停机按钮将被启用。 ,否则, Intent.ACTION_QUERY_PACKAGE_RESTART 将broadcat。

这意味着意图将只通过广播对非设备管理员的应用程序已经停止。

我和你code测试,这是一个4.0的设备上。如果您安装应用程序,那么你去设置 - &GT;的应用然后选择其他应用程序(不是你的)已经被逼停 ,你的的onReceive()被称为与 Intent.ACTION_QUERY_PACKAGE_RESTART

我意识到这可能是没有太大的帮助,但它至少说明了你所看到的行为。

抱歉花了这么长时间来解决这个问题,并感谢了挑战: - )

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

解决方案

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 broadcat.

This means that the Intent will only by broadcast 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 :-)

这篇关于无法获取接收器时,应用程序卸载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆