Не удается получить приемник при удалении приложения.

Я отсылаю эту информацию.

Я пишу одну и ту же программу, но я не могу получить информацию о журнале, когда я нажимаю кнопку удаления.

Я прикладываю свой код ниже. Кто-нибудь знает, в чем проблема в этом коде?

Я хочу что-то сделать, когда вы нажмете кнопку удаления. Возможно, как включить браузер и т.д.

Есть ли кто-нибудь, кто может дать мне руку?

Проблема смутила меня в течение долгого времени.

Мой 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>

...

мой код 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();
}

Ответ 1

Причина, по которой ваш BroadcastReceiver не вызывается, заключается в том, что ваше приложение все еще находится в состоянии "остановлено". В вашем приложении нет компонентов Activity. Это означает, что после установки приложения пользователю не удастся его запустить. Приложения, которые никогда не запускались пользователем, остаются в "остановленном состоянии". Приложения в "остановленном состоянии" не будут получать трансляции..

См. раздел "Управление запуском остановленных приложений" в http://developer.android.com/about/versions/android-3.1.html


EDIT: добавьте более подробную информацию о Intent.ACTION_QUERY_PACKAGE_RESTART в Android 4.x

Похоже, это поведение изменилось с Android 2.3 (я не уверен в Android 3.x). В Android 4.0 и выше код в InstalledAppDetails (часть приложения "Настройки" ) выглядит следующим образом:

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

Итак, если отображаемое приложение является администратором устройства, кнопка "принудительная остановка" будет отключена. Если отображаемое приложение не остановлено, тогда кнопка "принудительная остановка" будет включена. В противном случае будет транслироваться Intent.ACTION_QUERY_PACKAGE_RESTART.

Это означает, что Intent будет транслироваться только для приложений, не связанных с устройством, которые уже были остановлены.

Я тестировал это на устройстве 4.0 с вашим кодом. Если вы установите приложение, перейдите к Settings->Apps и выберите другое приложение (не ваше), которое было принудительно остановлено, ваш onReceive() вызывается с помощью Intent.ACTION_QUERY_PACKAGE_RESTART.

Я понял, что это, вероятно, не очень помогает, но по крайней мере объясняет поведение, которое вы видите.

Жаль, что для этого не потребовалось столько времени, и спасибо за вызов: -)

Ответ 2

Как правило, при удалении приложения все ресурсы удаляются с устройства. поэтому вы не можете запускать какие-либо действия во время удаления установки