package com.plusonelabs.calendar; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.graphics.Color; import android.net.Uri; import android.support.annotation.IdRes; import android.view.View; import android.widget.RemoteViews; import com.plusonelabs.calendar.prefs.InstanceSettings; import com.plusonelabs.calendar.util.PermissionsUtil; import org.joda.time.DateTime; import java.util.List; import java.util.Locale; import static android.graphics.Color.*; import static com.plusonelabs.calendar.CalendarIntentUtil.*; import static com.plusonelabs.calendar.RemoteViewsUtil.*; import static com.plusonelabs.calendar.Theme.themeNameToResId; public class EventAppWidgetProvider extends AppWidgetProvider { private static final String PACKAGE = EventAppWidgetProvider.class.getPackage().getName(); public static final String ACTION_REFRESH = PACKAGE + ".action.REFRESH"; public static int[] getWidgetIds(Context context) { return AppWidgetManager.getInstance(context) .getAppWidgetIds(new ComponentName(context, EventAppWidgetProvider.class)); } @Override public void onDeleted(Context context, int[] appWidgetIds) { super.onDeleted(context, appWidgetIds); for (int widgetId : appWidgetIds) { InstanceSettings.delete(context, widgetId); } } @Override public void onUpdate(Context baseContext, AppWidgetManager appWidgetManager, int[] appWidgetIds) { for (int widgetId : appWidgetIds) { InstanceSettings settings = InstanceSettings.fromId(baseContext, widgetId); AlarmReceiver.scheduleAlarm(settings.getHeaderThemeContext()); RemoteViews rv = new RemoteViews(baseContext.getPackageName(), R.layout.widget); configureBackground(settings, rv); configureWidgetHeader(settings, rv); configureList(settings, widgetId, rv); appWidgetManager.updateAppWidget(widgetId, rv); } } private void configureBackground(InstanceSettings settings, RemoteViews rv) { if (settings.getShowWidgetHeader()) { rv.setViewVisibility(R.id.action_bar, View.VISIBLE); } else { rv.setViewVisibility(R.id.action_bar, View.GONE); } int color = settings.getBackgroundColor(); int opaqueColor = Color.rgb(red(color), green(color), blue(color)); setColorFilter(rv, R.id.background_image, opaqueColor); setAlpha(rv, R.id.background_image, alpha(color)); } private void configureWidgetHeader(InstanceSettings settings, RemoteViews rv) { configureCurrentDate(settings, rv); setActionIcons(settings, rv); configureAddEvent(settings, rv); configureRefresh(settings.getContext(), rv); configureOverflowMenu(settings, rv); } private void configureCurrentDate(InstanceSettings settings, RemoteViews rv) { rv.setOnClickPendingIntent(R.id.calendar_current_date, createOpenCalendarPendingIntent(settings)); String formattedDate = DateUtil.createDateString(settings, DateUtil.now(settings.getTimeZone())).toUpperCase(Locale.getDefault()); rv.setTextViewText(R.id.calendar_current_date, formattedDate); setTextColorFromAttr(settings.getHeaderThemeContext(), rv, R.id.calendar_current_date, R.attr.header); } private void setActionIcons(InstanceSettings settings, RemoteViews rv) { setImageFromAttr(settings.getHeaderThemeContext(), rv, R.id.add_event, R.attr.header_action_add_event); setImageFromAttr(settings.getHeaderThemeContext(), rv, R.id.refresh, R.attr.header_action_refresh); setImageFromAttr(settings.getHeaderThemeContext(), rv, R.id.overflow_menu, R.attr.header_action_overflow); int themeId = themeNameToResId(settings.getHeaderTheme()); int alpha = 255; if (themeId == R.style.Theme_Calendar_Dark || themeId == R.style.Theme_Calendar_Light) { alpha = 154; } setAlpha(rv, R.id.add_event, alpha); setAlpha(rv, R.id.refresh, alpha); setAlpha(rv, R.id.overflow_menu, alpha); } private void configureAddEvent(InstanceSettings settings, RemoteViews rv) { rv.setOnClickPendingIntent(R.id.add_event, getPermittedAddEventPendingIntent(settings)); } private PendingIntent getPermittedAddEventPendingIntent(InstanceSettings settings) { Context context = settings.getContext(); Intent intent = PermissionsUtil.getPermittedIntent(context, CalendarIntentUtil.createNewEventIntent(settings.getTimeZone())); return isIntentAvailable(context, intent) ? PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) : getEmptyPendingIntent(context); } private static PendingIntent getEmptyPendingIntent(Context context) { return PendingIntent.getActivity( context.getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT); } private void configureRefresh(Context context, RemoteViews rv) { Intent intent = new Intent(ACTION_REFRESH); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0); rv.setOnClickPendingIntent(R.id.refresh, pendingIntent); } private void configureOverflowMenu(InstanceSettings settings, RemoteViews rv) { Intent intent = MainActivity.intentToConfigure(settings.getContext(), settings.getWidgetId()); PendingIntent menuPendingIntent = PermissionsUtil.getPermittedPendingIntent(settings, intent); rv.setOnClickPendingIntent(R.id.overflow_menu, menuPendingIntent); } private static boolean isIntentAvailable(Context context, Intent intent) { PackageManager packageManager = context.getPackageManager(); List<ResolveInfo> list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); return list.size() > 0; } private void configureList(InstanceSettings settings, int widgetId, RemoteViews rv) { Intent intent = new Intent(settings.getContext(), EventWidgetService.class); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId); intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); rv.setRemoteAdapter(R.id.event_list, intent); boolean permissionsGranted = PermissionsUtil.arePermissionsGranted(settings.getContext()); @IdRes int emptyViewId = R.id.empty_event_list; rv.setEmptyView(R.id.event_list, emptyViewId); rv.setTextViewText(emptyViewId, settings.getContext().getText( permissionsGranted ? R.string.no_upcoming_events : R.string.grant_permissions_verbose )); rv.setOnClickPendingIntent(emptyViewId, getPermittedAddEventPendingIntent(settings)); if (permissionsGranted) { rv.setPendingIntentTemplate(R.id.event_list, createOpenCalendarEventPendingIntent(settings)); rv.setOnClickFillInIntent(emptyViewId, createOpenCalendarAtDayIntent(new DateTime(settings.getTimeZone()))); } setTextSize(settings, rv, emptyViewId, R.dimen.event_entry_details); setTextColorFromAttr(settings.getEntryThemeContext(), rv, emptyViewId, R.attr.eventEntryTitle); } public static void updateEventList(Context context) { AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(getWidgetIds(context), R.id.event_list); } public static void updateAllWidgets(Context context) { Intent intent = new Intent(context, EventAppWidgetProvider.class); intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, getWidgetIds(context)); context.sendBroadcast(intent); } }