1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2011 Antoine Cellerier <dionoea at videolan dot org>
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 package org
.rockbox
.widgets
;
26 import org
.rockbox
.RockboxActivity
;
27 import org
.rockbox
.RockboxService
;
28 import android
.app
.PendingIntent
;
29 import android
.appwidget
.AppWidgetManager
;
30 import android
.appwidget
.AppWidgetProvider
;
31 import android
.appwidget
.AppWidgetProviderInfo
;
32 import android
.content
.ComponentName
;
33 import android
.content
.Context
;
34 import android
.content
.Intent
;
35 import android
.net
.Uri
;
36 import android
.view
.KeyEvent
;
37 import android
.view
.View
;
38 import android
.widget
.RemoteViews
;
40 public class RockboxWidgetProvider
extends AppWidgetProvider
42 static RockboxWidgetProvider mInstance
;
43 public RockboxWidgetProvider()
50 public void onUpdate(Context context
, AppWidgetManager appWidgetManager
, int[] appWidgetIds
)
52 final int N
= appWidgetIds
.length
;
53 for (int i
= 0; i
< N
; i
++)
55 int appWidgetId
= appWidgetIds
[i
];
56 updateAppWidget(context
, appWidgetManager
, appWidgetId
, null);
61 public static RockboxWidgetProvider
getInstance()
63 /* no new instance here, instanced by android */
68 public void onDeleted(Context context
, int[] appWidgetIds
)
73 public void onEnabled(Context context
)
78 public void onDisabled(Context context
)
83 public void onReceive(Context context
, Intent intent
)
85 String action
= intent
.getAction();
86 if (action
.equals("org.rockbox.TrackUpdateInfo") ||
87 action
.equals("org.rockbox.TrackFinish") ||
88 action
.equals("org.rockbox.UpdateState"))
90 AppWidgetManager gm
= AppWidgetManager
.getInstance(context
);
91 int[] appWidgetIds
= gm
.getAppWidgetIds(new ComponentName(context
, this.getClass()));
92 final int N
= appWidgetIds
.length
;
93 for (int i
= 0; i
< N
; i
++)
95 updateAppWidget(context
, gm
, appWidgetIds
[i
], intent
);
100 super.onReceive(context
, intent
);
104 public void updateAppWidget(Context context
, AppWidgetManager appWidgetManager
, int appWidgetId
, Intent args
)
106 AppWidgetProviderInfo provider
= appWidgetManager
.getAppWidgetInfo(appWidgetId
);
107 RemoteViews views
= null;
108 views
= new RemoteViews(context
.getPackageName(), provider
.initialLayout
);
110 Intent intent
= new Intent(context
, RockboxActivity
.class);
111 PendingIntent pendingIntent
= PendingIntent
.getActivity(context
, 0, intent
, 0);
112 views
.setOnClickPendingIntent(R
.id
.infoDisplay
, pendingIntent
);
113 views
.setOnClickPendingIntent(R
.id
.logo
, pendingIntent
);
115 RockboxWidgetConfigure
.WidgetPref state
= RockboxWidgetConfigure
.loadWidgetPref(context
, appWidgetId
);
117 /* enable/disable PREV */
118 if (state
.enablePrev
)
120 views
.setOnClickPendingIntent(R
.id
.prev
,
121 newPendingIntent(context
,
122 KeyEvent
.KEYCODE_MEDIA_PREVIOUS
));
125 views
.setViewVisibility(R
.id
.prev
, View
.GONE
);
127 /* enable/disable PLAY/PAUSE */
128 if (state
.enablePlayPause
)
130 views
.setOnClickPendingIntent(R
.id
.playPause
,
131 newPendingIntent(context
,
132 KeyEvent
.KEYCODE_MEDIA_PLAY_PAUSE
));
135 views
.setViewVisibility(R
.id
.playPause
, View
.GONE
);
137 /* enable/disable NEXT */
138 if (state
.enableNext
)
140 views
.setOnClickPendingIntent(R
.id
.next
,
141 newPendingIntent(context
,
142 KeyEvent
.KEYCODE_MEDIA_NEXT
));
145 views
.setViewVisibility(R
.id
.next
, View
.GONE
);
147 /* enable/disable STOP */
148 if (state
.enableStop
)
150 views
.setOnClickPendingIntent(R
.id
.stop
,
151 newPendingIntent(context
,
152 KeyEvent
.KEYCODE_MEDIA_STOP
));
155 views
.setViewVisibility(R
.id
.stop
, View
.GONE
);
158 views
.setViewVisibility(R
.id
.logo
, View
.GONE
);
162 if (args
.getAction().equals("org.rockbox.TrackUpdateInfo"))
164 CharSequence title
= args
.getCharSequenceExtra("title");
165 CharSequence artist
= args
.getCharSequenceExtra("artist");
166 CharSequence album
= args
.getCharSequenceExtra("album");
167 views
.setTextViewText(R
.id
.infoDisplay
, title
+"\n"+artist
+"\n"+album
);
168 CharSequence albumart
= args
.getCharSequenceExtra("albumart");
169 /* Uri.fromFile() is buggy in <2.2
170 * http://stackoverflow.com/questions/3004713/get-content-uri-from-file-path-in-android */
171 if (albumart
!= null)
172 views
.setImageViewUri(R
.id
.logo
, Uri
.parse(
173 new File(albumart
.toString()).toString()));
175 views
.setImageViewResource(R
.id
.logo
, R
.drawable
.rockbox
);
177 else if (args
.getAction().equals("org.rockbox.TrackFinish"))
179 // FIXME: looks like this event is always fired earlier than
180 // the actual track change (a few seconds)
181 views
.setTextViewText(R
.id
.infoDisplay
, context
.getString(R
.string
.appwidget_infoDisplay
));
182 views
.setImageViewResource(R
.id
.logo
, R
.drawable
.rockbox
);
184 else if (args
.getAction().equals("org.rockbox.UpdateState"))
186 CharSequence playstate
= args
.getCharSequenceExtra("state");
187 if (playstate
.equals("play"))
188 views
.setImageViewResource(R
.id
.playPause
, R
.drawable
.appwidget_pause
);
189 else /* pause or stop */
190 views
.setImageViewResource(R
.id
.playPause
, R
.drawable
.appwidget_play
);
194 appWidgetManager
.updateAppWidget(appWidgetId
, views
);
197 public static PendingIntent
newPendingIntent(Context context
, int keycode
)
199 /* Use keycode as request to code to prevent successive
200 * PendingIntents from overwritting one another.
201 * This seems hackish but at least it works.
202 * see: http://code.google.com/p/android/issues/detail?id=863
204 Intent intent
= new Intent(Intent
.ACTION_MEDIA_BUTTON
, Uri
.EMPTY
,
205 context
, RockboxService
.class);
206 intent
.putExtra(Intent
.EXTRA_KEY_EVENT
,
207 new KeyEvent(KeyEvent
.ACTION_UP
, keycode
));
208 return PendingIntent
.getService(context
, keycode
, intent
, 0);