package com.android.launcher3; import android.appwidget.AppWidgetHost; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.os.AsyncTask; import android.util.Log; import com.android.launcher3.LauncherSettings.Favorites; import java.util.ArrayList; import java.util.List; public class AppWidgetsRestoredReceiver extends BroadcastReceiver { private static final String TAG = "AppWidgetsRestoredReceiver"; @Override public void onReceive(Context context, Intent intent) { if (AppWidgetManager.ACTION_APPWIDGET_HOST_RESTORED.equals(intent.getAction())) { int[] oldIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS); int[] newIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS); if (oldIds.length == newIds.length) { restoreAppWidgetIds(context, oldIds, newIds); } else { Log.e(TAG, "Invalid host restored received"); } } } /** * Updates the app widgets whose id has changed during the restore process. */ static void restoreAppWidgetIds(Context context, int[] oldWidgetIds, int[] newWidgetIds) { final ContentResolver cr = context.getContentResolver(); final List idsToRemove = new ArrayList(); final AppWidgetManager widgets = AppWidgetManager.getInstance(context); for (int i = 0; i < oldWidgetIds.length; i++) { Log.i(TAG, "Widget state restore id " + oldWidgetIds[i] + " => " + newWidgetIds[i]); final AppWidgetProviderInfo provider = widgets.getAppWidgetInfo(newWidgetIds[i]); final int state; if (LauncherModel.isValidProvider(provider)) { state = LauncherAppWidgetInfo.RESTORE_COMPLETED; } else { state = LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY; } ContentValues values = new ContentValues(); values.put(LauncherSettings.Favorites.APPWIDGET_ID, newWidgetIds[i]); values.put(LauncherSettings.Favorites.RESTORED, state); String[] widgetIdParams = new String[] { Integer.toString(oldWidgetIds[i]) }; int result = cr.update(Favorites.CONTENT_URI, values, "appWidgetId=? and (restored & 1) = 1", widgetIdParams); if (result == 0) { Cursor cursor = cr.query(Favorites.CONTENT_URI, new String[] {Favorites.APPWIDGET_ID}, "appWidgetId=?", widgetIdParams, null); try { if (!cursor.moveToFirst()) { // The widget no long exists. idsToRemove.add(newWidgetIds[i]); } } finally { cursor.close(); } } } // Unregister the widget IDs which are not present on the workspace. This could happen // when a widget place holder is removed from workspace, before this method is called. if (!idsToRemove.isEmpty()) { final AppWidgetHost appWidgetHost = new AppWidgetHost(context, Launcher.APPWIDGET_HOST_ID); new AsyncTask() { public Void doInBackground(Void ... args) { for (Integer id : idsToRemove) { appWidgetHost.deleteAppWidgetId(id); Log.e(TAG, "Widget no longer present, appWidgetId=" + id); } return null; } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null); } } }