2 * Copyright (C) 2012 Andrew Neal
3 * Copyright (C) 2014 The CyanogenMod Project
4 * Licensed under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with the
6 * License. You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
8 * or agreed to in writing, software distributed under the License is
9 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
10 * KIND, either express or implied. See the License for the specific language
11 * governing permissions and limitations under the License.
14 package com.cyanogenmod.eleven.appwidgets;
16 import android.annotation.SuppressLint;
17 import android.app.PendingIntent;
18 import android.appwidget.AppWidgetManager;
19 import android.content.ComponentName;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.graphics.Bitmap;
23 import android.text.TextUtils;
24 import android.view.View;
25 import android.widget.RemoteViews;
27 import com.cyanogenmod.eleven.MusicPlaybackService;
28 import com.cyanogenmod.eleven.R;
29 import com.cyanogenmod.eleven.ui.activities.HomeActivity;
30 import com.cyanogenmod.eleven.utils.ApolloUtils;
35 * @author Andrew Neal (andrewdneal@gmail.com)
37 @SuppressLint("NewApi")
38 public class AppWidgetSmall extends AppWidgetBase {
40 public static final String CMDAPPWIDGETUPDATE = "app_widget_small_update";
42 private static AppWidgetSmall mInstance;
44 public static synchronized AppWidgetSmall getInstance() {
45 if (mInstance == null) {
46 mInstance = new AppWidgetSmall();
55 public void onUpdate(final Context context, final AppWidgetManager appWidgetManager,
56 final int[] appWidgetIds) {
57 defaultAppWidget(context, appWidgetIds);
58 final Intent updateIntent = new Intent(MusicPlaybackService.SERVICECMD);
59 updateIntent.putExtra(MusicPlaybackService.CMDNAME, AppWidgetSmall.CMDAPPWIDGETUPDATE);
60 updateIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
61 updateIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
62 context.sendBroadcast(updateIntent);
66 * Initialize given widgets to default state, where we launch Music on
67 * default click and hide actions if service not running.
69 private void defaultAppWidget(final Context context, final int[] appWidgetIds) {
70 final RemoteViews appWidgetViews = new RemoteViews(context.getPackageName(),
71 R.layout.app_widget_small);
72 appWidgetViews.setViewVisibility(R.id.app_widget_small_info_container, View.INVISIBLE);
73 linkButtons(context, appWidgetViews);
74 pushUpdate(context, appWidgetIds, appWidgetViews);
77 private void pushUpdate(final Context context, final int[] appWidgetIds, final RemoteViews views) {
78 final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
79 if (appWidgetIds != null) {
80 appWidgetManager.updateAppWidget(appWidgetIds, views);
82 appWidgetManager.updateAppWidget(new ComponentName(context, getClass()), views);
87 * Check against {@link AppWidgetManager} if there are any instances of this
90 private boolean hasInstances(final Context context) {
91 final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
92 final int[] mAppWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context,
94 return mAppWidgetIds.length > 0;
98 * Handle a change notification coming over from
99 * {@link MusicPlaybackService}
101 public void notifyChange(final MusicPlaybackService service, final String what) {
102 if (hasInstances(service)) {
103 if (MusicPlaybackService.META_CHANGED.equals(what)
104 || MusicPlaybackService.PLAYSTATE_CHANGED.equals(what)) {
105 performUpdate(service, null);
111 * Update all active widget instances by pushing changes
113 public void performUpdate(final MusicPlaybackService service, final int[] appWidgetIds) {
114 final RemoteViews appWidgetView = new RemoteViews(service.getPackageName(),
115 R.layout.app_widget_small);
117 final CharSequence trackName = service.getTrackName();
118 final CharSequence artistName = service.getArtistName();
119 final Bitmap bitmap = service.getAlbumArt(true).getBitmap();
121 // Set the titles and artwork
122 if (TextUtils.isEmpty(trackName) && TextUtils.isEmpty(artistName)) {
123 appWidgetView.setViewVisibility(R.id.app_widget_small_info_container, View.INVISIBLE);
125 appWidgetView.setViewVisibility(R.id.app_widget_small_info_container, View.VISIBLE);
126 appWidgetView.setTextViewText(R.id.app_widget_small_line_one, trackName);
127 appWidgetView.setTextViewText(R.id.app_widget_small_line_two, artistName);
129 appWidgetView.setImageViewBitmap(R.id.app_widget_small_image, bitmap);
131 // Set correct drawable for pause state
132 final boolean isPlaying = service.isPlaying();
134 appWidgetView.setImageViewResource(R.id.app_widget_small_play,
135 R.drawable.btn_playback_pause);
136 appWidgetView.setContentDescription(R.id.app_widget_small_play,
137 service.getString(R.string.accessibility_pause));
139 appWidgetView.setImageViewResource(R.id.app_widget_small_play,
140 R.drawable.btn_playback_play);
141 appWidgetView.setContentDescription(R.id.app_widget_small_play,
142 service.getString(R.string.accessibility_play));
145 // Link actions buttons to intents
146 linkButtons(service, appWidgetView);
148 // Update the app-widget
149 pushUpdate(service, appWidgetIds, appWidgetView);
153 * Link up various button actions using {@link PendingIntents}.
156 private void linkButtons(final Context context, final RemoteViews views) {
158 PendingIntent pendingIntent;
160 final ComponentName serviceName = new ComponentName(context, MusicPlaybackService.class);
163 action = new Intent(context, HomeActivity.class);
164 action.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
165 pendingIntent = PendingIntent.getActivity(context, 0, action, 0);
166 views.setOnClickPendingIntent(R.id.app_widget_small_info_container, pendingIntent);
167 views.setOnClickPendingIntent(R.id.app_widget_small_image, pendingIntent);
170 pendingIntent = buildPendingIntent(context, MusicPlaybackService.PREVIOUS_ACTION, serviceName);
171 views.setOnClickPendingIntent(R.id.app_widget_small_previous, pendingIntent);
174 pendingIntent = buildPendingIntent(context, MusicPlaybackService.TOGGLEPAUSE_ACTION, serviceName);
175 views.setOnClickPendingIntent(R.id.app_widget_small_play, pendingIntent);
178 pendingIntent = buildPendingIntent(context, MusicPlaybackService.NEXT_ACTION, serviceName);
179 views.setOnClickPendingIntent(R.id.app_widget_small_next, pendingIntent);