summaryrefslogtreecommitdiffstats
path: root/src/com/android/music/MediaAppWidgetProvider4x2.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/music/MediaAppWidgetProvider4x2.java')
-rw-r--r--src/com/android/music/MediaAppWidgetProvider4x2.java349
1 files changed, 349 insertions, 0 deletions
diff --git a/src/com/android/music/MediaAppWidgetProvider4x2.java b/src/com/android/music/MediaAppWidgetProvider4x2.java
new file mode 100644
index 0000000..8dd335d
--- /dev/null
+++ b/src/com/android/music/MediaAppWidgetProvider4x2.java
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.music;
+
+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.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.Environment;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.widget.RemoteViews;
+
+/**
+ * Simple widget to show currently playing album art along with play/pause and
+ * next track buttons.
+ */
+public class MediaAppWidgetProvider4x2 extends AppWidgetProvider {
+ static final String TAG = "MusicAppWidgetProvider4x2";
+
+ public static final String CMDAPPWIDGETUPDATE = "appwidgetupdate4x2";
+
+ // ADW Theme constants
+ public static final int THEME_ITEM_BACKGROUND = 0;
+ public static final int THEME_ITEM_FOREGROUND = 1;
+ private static MediaAppWidgetProvider4x2 sInstance;
+
+ static synchronized MediaAppWidgetProvider4x2 getInstance() {
+ if (sInstance == null) {
+ sInstance = new MediaAppWidgetProvider4x2();
+ }
+ return sInstance;
+ }
+
+ @Override
+ public void onUpdate(Context context, AppWidgetManager appWidgetManager,
+ int[] appWidgetIds) {
+ defaultAppWidget(context, appWidgetIds);
+
+ // Send broadcast intent to any running MediaPlaybackService so it can
+ // wrap around with an immediate update.
+ Intent updateIntent = new Intent(MediaPlaybackService.SERVICECMD);
+ updateIntent.putExtra(MediaPlaybackService.CMDNAME,
+ MediaAppWidgetProvider4x2.CMDAPPWIDGETUPDATE);
+ updateIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,
+ appWidgetIds);
+ updateIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ context.sendBroadcast(updateIntent);
+ }
+
+ /**
+ * Initialize given widgets to default state, where we launch Music on
+ * default click and hide actions if service not running.
+ */
+ private void defaultAppWidget(Context context, int[] appWidgetIds) {
+ final Resources res = context.getResources();
+ final RemoteViews views = new RemoteViews(context.getPackageName(),
+ R.layout.album_appwidget4x2);
+
+ views.setViewVisibility(R.id.albumname, View.GONE);
+ views.setViewVisibility(R.id.trackname, View.GONE);
+ views.setTextViewText(R.id.artistname,
+ res.getText(R.string.widget_initial_text));
+ views.setImageViewResource(R.id.albumart,
+ R.drawable.albumart_mp_unknown);
+
+ linkButtons(context, views, false /* not playing */);
+ pushUpdate(context, appWidgetIds, views);
+ }
+
+ private void pushUpdate(Context context, int[] appWidgetIds,
+ RemoteViews views) {
+ // Update specific list of appWidgetIds if given, otherwise default to
+ // all
+ final AppWidgetManager gm = AppWidgetManager.getInstance(context);
+ if (appWidgetIds != null) {
+ gm.updateAppWidget(appWidgetIds, views);
+ } else {
+ gm.updateAppWidget(new ComponentName(context, this.getClass()),
+ views);
+ }
+ }
+
+ /**
+ * Check against {@link AppWidgetManager} if there are any instances of this
+ * widget.
+ */
+ private boolean hasInstances(Context context) {
+ AppWidgetManager appWidgetManager = AppWidgetManager
+ .getInstance(context);
+ int[] appWidgetIds = appWidgetManager
+ .getAppWidgetIds(new ComponentName(context, this.getClass()));
+ return (appWidgetIds.length > 0);
+ }
+
+ /**
+ * Handle a change notification coming over from
+ * {@link MediaPlaybackService}
+ */
+ void notifyChange(MediaPlaybackService service, String what) {
+ if (hasInstances(service)) {
+ if (MediaPlaybackService.META_CHANGED.equals(what)
+ || MediaPlaybackService.PROGRESSBAR_CHANGED.equals(what)
+ || MediaPlaybackService.PLAYSTATE_CHANGED.equals(what)
+ || MediaPlaybackService.REPEATMODE_CHANGED.equals(what)
+ || MediaPlaybackService.SHUFFLEMODE_CHANGED.equals(what)) {
+ performUpdate(service, null);
+ }
+ }
+ }
+
+ /**
+ * Update all active widget instances by pushing changes
+ */
+ void performUpdate(MediaPlaybackService service, int[] appWidgetIds) {
+ final Resources res = service.getResources();
+ final RemoteViews views = new RemoteViews(service.getPackageName(),
+ R.layout.album_appwidget4x2);
+
+ CharSequence artistName = service.getArtistName();
+ CharSequence albumName = service.getAlbumName();
+ CharSequence trackName = service.getTrackName();
+ long albumId = service.getAlbumId();
+ long songId = service.getAudioId();
+ long pos = service.position();
+ long dur = service.duration();
+ CharSequence errorState = null;
+
+ // Format title string with track number, or show SD card message
+ String status = Environment.getExternalStorageState();
+ if (status.equals(Environment.MEDIA_SHARED)
+ || status.equals(Environment.MEDIA_UNMOUNTED)) {
+ if (android.os.Environment.isExternalStorageRemovable()) {
+ errorState = res.getText(R.string.sdcard_busy_title);
+ } else {
+ errorState = res.getText(R.string.sdcard_busy_title_nosdcard);
+ }
+ } else if (status.equals(Environment.MEDIA_REMOVED)) {
+ if (android.os.Environment.isExternalStorageRemovable()) {
+ errorState = res.getText(R.string.sdcard_missing_title);
+ } else {
+ errorState = res
+ .getText(R.string.sdcard_missing_title_nosdcard);
+ }
+ } else if (trackName == null) {
+ errorState = res.getText(R.string.emptyplaylist);
+ }
+ SharedPreferences mPrefs = PreferenceManager
+ .getDefaultSharedPreferences(service);
+ int aColor = new Integer(mPrefs.getInt(null,
+ MusicSettingsActivity.DEFAULT_SCREENSAVER_COLOR_ALPHA));
+ int rColor = new Integer(mPrefs.getInt(null,
+ MusicSettingsActivity.DEFAULT_SCREENSAVER_COLOR_RED));
+ int gColor = new Integer(mPrefs.getInt(null,
+ MusicSettingsActivity.DEFAULT_SCREENSAVER_COLOR_GREEN));
+ int bColor = new Integer(mPrefs.getInt(null,
+ MusicSettingsActivity.DEFAULT_SCREENSAVER_COLOR_BLUE));
+ int SCREEN_SAVER_COLOR_DIM = Color.argb(aColor, rColor, gColor, bColor);
+
+ if (errorState != null) {
+ // Show error state to user
+ views.setViewVisibility(R.id.albumname, View.GONE);
+ views.setViewVisibility(R.id.trackname, View.GONE);
+ views.setTextViewText(R.id.artistname, errorState);
+ views.setImageViewResource(R.id.albumart,
+ R.drawable.albumart_mp_unknown);
+ } else {
+ // No error, so show normal titles and artwork
+ views.setViewVisibility(R.id.albumname, View.VISIBLE);
+ views.setViewVisibility(R.id.trackname, View.VISIBLE);
+ views.setTextViewText(R.id.artistname, " " + artistName);
+ views.setTextViewText(R.id.albumname, " " + albumName);
+ views.setTextViewText(R.id.trackname, " " + trackName);
+ views.setTextColor(R.id.artistname, SCREEN_SAVER_COLOR_DIM);
+ views.setTextColor(R.id.albumname, SCREEN_SAVER_COLOR_DIM);
+ views.setTextColor(R.id.trackname, SCREEN_SAVER_COLOR_DIM);
+ views.setProgressBar(R.id.progress, 1000, (int) (1000 * pos / dur),
+ false);
+
+ // Set album art
+ Uri uri = MusicUtils.getArtworkUri(service, songId, albumId);
+ if (uri != null) {
+ views.setImageViewUri(R.id.albumart, uri);
+ } else {
+ views.setImageViewResource(R.id.albumart,
+ R.drawable.albumart_mp_unknown);
+ }
+ }
+
+ // Set correct drawable for pause state
+ final boolean playing = service.isPlaying();
+ if (playing) {
+ views.setImageViewResource(R.id.control_play,
+ R.drawable.ic_media_pause);
+ } else {
+ views.setImageViewResource(R.id.control_play,
+ R.drawable.ic_appwidget_music_play);
+ }
+
+ // Set correct drawable for repeat state
+ switch (service.getRepeatMode()) {
+ case MediaPlaybackService.REPEAT_ALL:
+ views.setImageViewResource(R.id.control_repeat,
+ R.drawable.ic_mp_repeat_all_btn);
+ break;
+ case MediaPlaybackService.REPEAT_CURRENT:
+ views.setImageViewResource(R.id.control_repeat,
+ R.drawable.ic_mp_repeat_once_btn);
+ break;
+ default:
+ views.setImageViewResource(R.id.control_repeat,
+ R.drawable.ic_mp_repeat_off_btn);
+ break;
+ }
+
+ // Set correct drawable for shuffle state
+ switch (service.getShuffleMode()) {
+ case MediaPlaybackService.SHUFFLE_NONE:
+ views.setImageViewResource(R.id.control_shuffle,
+ R.drawable.ic_mp_shuffle_off_btn);
+ break;
+ case MediaPlaybackService.SHUFFLE_AUTO:
+ views.setImageViewResource(R.id.control_shuffle,
+ R.drawable.ic_mp_partyshuffle_on_btn);
+ break;
+ default:
+ views.setImageViewResource(R.id.control_shuffle,
+ R.drawable.ic_mp_shuffle_on_btn);
+ break;
+ }
+ // Link actions buttons to intents
+ linkButtons(service, views, playing);
+
+ pushUpdate(service, appWidgetIds, views);
+
+ }
+
+ /**
+ * Link up various button actions using {@link PendingIntents}.
+ *
+ * @param playerActive
+ * True if player is active in background, which means widget
+ * click will launch {@link MediaPlaybackActivity}, otherwise we
+ * launch {@link MusicBrowserActivity}.
+ */
+ private void linkButtons(Context context, RemoteViews views,
+ boolean playerActive) {
+
+ // ADW: Load the specified theme
+ String themePackage = MusicUtils.getThemePackageName(context,
+ MusicSettingsActivity.THEME_DEFAULT);
+ PackageManager pm = context.getPackageManager();
+ Resources themeResources = null;
+ if (!themePackage.equals(MusicSettingsActivity.THEME_DEFAULT)) {
+ try {
+ themeResources = pm.getResourcesForApplication(themePackage);
+ } catch (NameNotFoundException e) {
+ // ADW The saved theme was uninstalled so we save the
+ // default one
+ MusicUtils.setThemePackageName(context,
+ MusicSettingsActivity.THEME_DEFAULT);
+ }
+ int albumName = themeResources.getIdentifier(
+ "four_by_two_album_name", "color", themePackage);
+ if (albumName != 0) {
+ views.setTextColor(R.id.albumname,
+ themeResources.getColor(albumName));
+ }
+ int trackName = themeResources.getIdentifier(
+ "four_by_two_track_name", "color", themePackage);
+ if (trackName != 0) {
+ views.setTextColor(R.id.trackname,
+ themeResources.getColor(trackName));
+ }
+ int artistName = themeResources.getIdentifier(
+ "four_by_two_artist_name", "color", themePackage);
+ if (artistName != 0) {
+ views.setTextColor(R.id.artistname,
+ themeResources.getColor(artistName));
+ }
+ }
+
+ // Connect up various buttons and touch events
+ Intent intent;
+ PendingIntent pendingIntent;
+
+ final ComponentName serviceName = new ComponentName(context,
+ MediaPlaybackService.class);
+
+ if (playerActive) {
+ intent = new Intent(context, MediaPlaybackActivity.class);
+ pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
+ views.setOnClickPendingIntent(R.id.albumart, pendingIntent);
+ views.setOnClickPendingIntent(R.id.info, pendingIntent);
+ } else {
+ intent = new Intent(context, MusicBrowserActivity.class);
+ pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
+ views.setOnClickPendingIntent(R.id.albumart, pendingIntent);
+ views.setOnClickPendingIntent(R.id.info, pendingIntent);
+ }
+
+ intent = new Intent(MediaPlaybackService.TOGGLEPAUSE_ACTION);
+ intent.setComponent(serviceName);
+ pendingIntent = PendingIntent.getService(context, 0, intent, 0);
+ views.setOnClickPendingIntent(R.id.control_play, pendingIntent);
+
+ intent = new Intent(MediaPlaybackService.NEXT_ACTION);
+ intent.setComponent(serviceName);
+ pendingIntent = PendingIntent.getService(context, 0, intent, 0);
+ views.setOnClickPendingIntent(R.id.control_next, pendingIntent);
+
+ intent = new Intent(MediaPlaybackService.PREVIOUS_ACTION);
+ intent.setComponent(serviceName);
+ pendingIntent = PendingIntent.getService(context, 0, intent, 0);
+ views.setOnClickPendingIntent(R.id.control_prev, pendingIntent);
+
+ intent = new Intent(MediaPlaybackService.CYCLEREPEAT_ACTION);
+ intent.setComponent(serviceName);
+ pendingIntent = PendingIntent.getService(context, 0, intent, 0);
+ views.setOnClickPendingIntent(R.id.control_repeat, pendingIntent);
+
+ intent = new Intent(MediaPlaybackService.TOGGLESHUFFLE_ACTION);
+ intent.setComponent(serviceName);
+ pendingIntent = PendingIntent.getService(context, 0, intent, 0);
+ views.setOnClickPendingIntent(R.id.control_shuffle, pendingIntent);
+ }
+}