@@ -0,0 +1,3244 @@
+package com.oasisfeng.pattern.update;%0A%0Aimport android.content.BroadcastReceiver;%0Aimport android.content.ComponentName;%0Aimport android.content.Context;%0Aimport android.content.Intent;%0Aimport android.content.pm.PackageManager;%0Aimport android.content.pm.ResolveInfo;%0Aimport android.os.Build;%0Aimport android.util.Log;%0A%0A/**%0A * Device experience friendly package update observer, eliminated the legacy broadcast receiver if running on Android 3.1+%0A *%0A * %3Cp%3EFirst, define two classes extending this abstract class, as following:%0A * %3Cpre%3E%0A   class PackageUpdateObserver extends AbstractPackageUpdateObserver %7B%0A%0A       %7B@literal @%7DOverride protected void onPackageUpdated(final Context context) %7B%0A           // Anything to be done after package update%0A       %7D%0A   %7D%0A%0A   class PackageUpdateObserverLegacy extends PackageUpdateObserver %7B%0A   %7D%3C/pre%3E%0A%0A * Then, declare two broadcast receivers in your AndroidManifest.xml%0A * %3Cpre%3E%0A   &lt;receiver android:name=%22.PackageUpdateObserverLegacy%22&gt;%0A       &lt;intent-filter%3E%0A           &lt;action android:name=%22android.intent.action.PACKAGE_REPLACED%22 /%3E%0A           &lt;data android:scheme=%22package%22 /%3E%0A       &lt;/intent-filter%3E%0A   &lt;/receiver%3E%0A%0A   &lt;receiver android:name=%22.PackageUpdateObserver%22&gt;%0A       &lt;intent-filter&gt;%0A           &lt;action android:name=%22android.intent.action.MY_PACKAGE_REPLACED%22 /&gt;%0A       &lt;/intent-filter&gt;%0A   &lt;/receiver&gt;%3C/pre%3E%0A%0A * @author Oasis%0A */%0Apublic abstract class AbstractPackageUpdateObserver extends BroadcastReceiver %7B%0A%0A    abstract protected void onPackageUpdated(final Context context);%0A%0A    @Override public void onReceive(final Context context, final Intent intent) %7B%0A        if (Intent.ACTION_PACKAGE_REPLACED.equals(intent.getAction())) %7B%0A            // Disable legacy receiver on Android 3.1+ for better device experience.%0A            if (Build.VERSION.SDK_INT %3E= Build.VERSION_CODES.HONEYCOMB_MR1) %7B%0A                for (final ResolveInfo receiver : context.getPackageManager().queryBroadcastReceivers(intent, 0)) %7B%0A                    Class%3C?%3E clazz; try %7B clazz = Class.forName(receiver.activityInfo.name);%0A                    %7D catch (final ClassNotFoundException e) %7B%0A                        Log.e(TAG, %22Cannot find receiver: %22 + receiver.activityInfo.name);%0A                        continue;%0A                    %7D%0A                    if (! AbstractPackageUpdateObserver.class.isAssignableFrom(clazz)) continue;  // Skip other receivers.%0A                    final ComponentName component = new ComponentName(context, clazz);%0A                    context.getPackageManager().setComponentEnabledSetting(component,%0A                            PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);%0A                %7D%0A                return;     // No need to proceed since Intent.ACTION_MY_PACKAGE_REPLACED will also be triggered.%0A            %7D%0A            // Ignore packages other than myself%0A            if (! context.getPackageName().equals(intent.getData().getSchemeSpecificPart())) return;%0A        %7D else if (! Intent.ACTION_MY_PACKAGE_REPLACED.equals(intent.getAction())) return;%0A%0A        Log.i(TAG, %22Package updated%22);%0A        onPackageUpdated(context);%0A    %7D%0A%0A    private static final String TAG = %22Installer%22;%0A%7D%0A

Add device experience friendly package update observer pattern.