Dimensions in Cells
For n number of Cells (Columns or Rows), the Available Size (dp) is approximately (70*n)-30. So, an app widget of dimensions minWidth 250 x minHeight 60, will be "stretched" to occupy 4x2 cells on screen.
1 = up to 40dp
2 = up to 110dp
3 = up to 180dp
4 = up to 250dp
AppWidget Configuration: Problem & Solution
As AppWidgetConfigure needs WidgetID, AppWidgetConfigure.onCreate() is also called after onEnabled().
That is, onEnabled() is already called even if Configuration later gets cancelled by pressing "Back" button.
2. If a Configuration Activity is declared, the AppWidgetProvider.onReceive(APPWIDGET_UPDATE)/onUpdate() method will not be called when the App Widget is created. It is the responsibility of the configuration Activity to request an update from the AppWidgetManager when the App Widget is first created. However, onUpdate() will be called for subsequent updates - it is only skipped the first time.
==> But in reality, onUpdate() is called even when Configuration Activity is declared.
3. The AppWidget Configuration documentation says "Setting the result to RESULT_CANCELED will cause the widget host to cancel out of the widget placement if they press the back button".
==> But in reality, when Configuration is cancelled by navigating "Back", the Widget is not Deleted!! That is, AppWidgetConfigure.onDestroy() is called, but AppWidgetProvider.onReceive(APPWIDGET_DELETED) is not called for corresponding Widget. This leaves unconfigured widget hidden (ghost) somewhere and hence, AppWidgetProvider.onReceive(APPWIDGET_DISABLED)/onDisabled doesn't get called even if onEnabled() already called before creating Configuration activity.
4. These and some more appear to be long-pending issues not resolved by Google/Android team:
Unconfigured home screen widgets are left in limbo
https://code.google.com/p/android/issues/detail?id=2539
Widget onUpdate is called once before displaying configuration activity
https://code.google.com/p/android/issues/detail?id=3696
Add AppWidget::
onReceive action=android.appwidget.action.APPWIDGET_ENABLED
onEnabled
onReceive action=android.appwidget.action.APPWIDGET_UPDATE
updateAppWidget(): appWidgetId=131
onReceive action=com.motorola.blur.home.ACTION_SET_WIDGET_SIZE
YmdhmsAppWidgetConfigure()
YmdhmsAppWidgetConfigure: onCreate()
YmdhmsAppWidgetConfigure: onCreate() finished. mAppWidgetId=131
---- config shown
Option A: Press Back button and NOTHING happens. Widget is "lost" without being deleted.
Option B: Accept Configuration (Don't press Back button)::
updateAppWidget(): appWidgetId=131
onReceive action=com.motorola.blur.home.ACTION_WIDGET_ADDED
onReceive action=android.appwidget.action.APPWIDGET_UPDATE
updateAppWidget(): appWidgetId=131
---- config accepted
Delete AppWidget:: (Note: This can't be done for Option A, where Widget is lost after pressing Back button)
onReceive action=android.appwidget.action.APPWIDGET_DELETED
onReceive action=android.appwidget.action.APPWIDGET_DISABLED
onDisabled
---- deleted
Resolution/Solution
Best option is to NOT use Widget Info "android:configure". Instead, let the widget be created & shown with default configuration and provide a choice to later reconfigure the settings. (In any case, even if "android:configure" is used, there is no default/recommended process to re-configure a widget after it's created).
Assign "id" to the AppWidget layout. Use setOnClickPendingIntent() on it to set explicit intent for (manually) starting the Configuration Activity.
Bundle extras = new Bundle();
extras.putInt(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
// Bind the Click intent for the on the (whole) widget
final Intent clickIntent = new Intent(context, YmdhmsAppWidgetProvider.class)
.putExtras(extras)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // in case activity is started outside of the context of an existing activity
final PendingIntent clickPendingIntent = PendingIntent.getActivity(context, appWidgetId, // use unique request code instead of 0, to create unique PendingIntents
clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.widget, clickPendingIntent);
No comments:
Post a Comment