[Android] widget: fix widget updates when launcher is restarted

Sébastien Toque git at videolan.org
Wed Aug 14 13:32:39 CEST 2013


vlc-ports/android | branch: master | Sébastien Toque <xilasz at gmail.com> | Wed Aug 14 13:29:55 2013 +0200| [6b896d99ca568273d91937d4ca64e009b4ca9d90] | committer: Sébastien Toque

widget: fix widget updates when launcher is restarted

When the launcher is killed/restarted, only the latest RemoteViews is restored.
so use partial updates if possible (API11+), else update everything.

Unfortunately, in API below 17, partial updates are not cached by android,
so we have to force those updates from the service.

To avoid spamming with several big intents during playback,
the cover is not restored, only state, text and position.

> http://git.videolan.org/gitweb.cgi/vlc-ports/android.git/?a=commit;h=6b896d99ca568273d91937d4ca64e009b4ca9d90
---

 vlc-android/src/org/videolan/vlc/AudioService.java |   20 +++++++-
 .../videolan/vlc/widget/VLCAppWidgetProvider.java  |   48 +++++++++++---------
 2 files changed, 44 insertions(+), 24 deletions(-)

diff --git a/vlc-android/src/org/videolan/vlc/AudioService.java b/vlc-android/src/org/videolan/vlc/AudioService.java
index ec6c638..28a6465 100644
--- a/vlc-android/src/org/videolan/vlc/AudioService.java
+++ b/vlc-android/src/org/videolan/vlc/AudioService.java
@@ -94,6 +94,7 @@ public class AudioService extends Service {
     public static final String ACTION_REMOTE_LAST_PLAYLIST = "org.videolan.vlc.remote.LastPlaylist";
     public static final String ACTION_WIDGET_INIT = "org.videolan.vlc.widget.INIT";
     public static final String ACTION_WIDGET_UPDATE = "org.videolan.vlc.widget.UPDATE";
+    public static final String ACTION_WIDGET_UPDATE_COVER = "org.videolan.vlc.widget.UPDATE_COVER";
     public static final String ACTION_WIDGET_UPDATE_POSITION = "org.videolan.vlc.widget.UPDATE_POSITION";
 
     public static final String WIDGET_PACKAGE = "org.videolan.vlc";
@@ -1067,9 +1068,13 @@ public class AudioService extends Service {
         }
     };
 
-    private void updateWidget(Context context)
-    {
+    private void updateWidget(Context context) {
         Log.d(TAG, "Updating widget");
+        updateWidgetState(context);
+        updateWidgetCover(context);
+    }
+
+    private void updateWidgetState(Context context) {
         Intent i = new Intent();
         i.setClassName(WIDGET_PACKAGE, WIDGET_CLASS);
         i.setAction(ACTION_WIDGET_UPDATE);
@@ -1084,6 +1089,15 @@ public class AudioService extends Service {
         }
         i.putExtra("isplaying", mLibVLC.isPlaying());
 
+        sendBroadcast(i);
+    }
+
+    private void updateWidgetCover(Context context)
+    {
+        Intent i = new Intent();
+        i.setClassName(WIDGET_PACKAGE, WIDGET_CLASS);
+        i.setAction(ACTION_WIDGET_UPDATE_COVER);
+
         Bitmap cover = mCurrentMedia != null ? AudioUtil.getCover(this, mCurrentMedia, 64) : null;
         i.putExtra("cover", cover);
 
@@ -1098,6 +1112,8 @@ public class AudioService extends Service {
             timestamp - mWidgetPositionTimestamp < mCurrentMedia.getLength() / 50)
             return;
 
+        updateWidgetState(context);
+
         mWidgetPositionTimestamp = timestamp;
         Intent i = new Intent();
         i.setClassName(WIDGET_PACKAGE, WIDGET_CLASS);
diff --git a/vlc-android/src/org/videolan/vlc/widget/VLCAppWidgetProvider.java b/vlc-android/src/org/videolan/vlc/widget/VLCAppWidgetProvider.java
index fd99184..50190ac 100644
--- a/vlc-android/src/org/videolan/vlc/widget/VLCAppWidgetProvider.java
+++ b/vlc-android/src/org/videolan/vlc/widget/VLCAppWidgetProvider.java
@@ -21,7 +21,9 @@
 package org.videolan.vlc.widget;
 
 import org.videolan.vlc.R;
+import org.videolan.vlc.Util;
 
+import android.annotation.TargetApi;
 import android.app.PendingIntent;
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProvider;
@@ -29,6 +31,7 @@ import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
+import android.os.Build;
 import android.view.View;
 import android.widget.RemoteViews;
 
@@ -39,8 +42,10 @@ public class VLCAppWidgetProvider extends AppWidgetProvider {
     public static final String ACTION_REMOTE_PLAYPAUSE = "org.videolan.vlc.remote.PlayPause";
     public static final String ACTION_REMOTE_STOP = "org.videolan.vlc.remote.Stop";
     public static final String ACTION_REMOTE_FORWARD = "org.videolan.vlc.remote.Forward";
+    public static final String ACTION_WIDGET_PREFIX = "org.videolan.vlc.widget.";
     public static final String ACTION_WIDGET_INIT = "org.videolan.vlc.widget.INIT";
     public static final String ACTION_WIDGET_UPDATE = "org.videolan.vlc.widget.UPDATE";
+    public static final String ACTION_WIDGET_UPDATE_COVER = "org.videolan.vlc.widget.UPDATE_COVER";
     public static final String ACTION_WIDGET_UPDATE_POSITION = "org.videolan.vlc.widget.UPDATE_POSITION";
 
     public static final String VLC_PACKAGE = "org.videolan.vlc";
@@ -62,13 +67,19 @@ public class VLCAppWidgetProvider extends AppWidgetProvider {
         context.sendBroadcast(i);
     }
 
+    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
     @Override
     public void onReceive(Context context, Intent intent) {
         String action = intent.getAction();
+        if (!action.startsWith(ACTION_WIDGET_PREFIX)) {
+            super.onReceive(context, intent);
+            return;
+        }
 
-        if (ACTION_WIDGET_INIT.equals(action)) {
-            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.vlcwidget);
+        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.vlcwidget);
+        boolean partial = Util.isHoneycombOrLater();
 
+        if (ACTION_WIDGET_INIT.equals(action) || !partial) {
             /* commands */
             Intent iBackward = new Intent(ACTION_REMOTE_BACKWARD);
             Intent iPlay = new Intent(ACTION_REMOTE_PLAYPAUSE);
@@ -89,44 +100,37 @@ public class VLCAppWidgetProvider extends AppWidgetProvider {
             views.setOnClickPendingIntent(R.id.stop, piStop);
             views.setOnClickPendingIntent(R.id.forward, piForward);
             views.setOnClickPendingIntent(R.id.cover, piVlc);
-
-            ComponentName widget = new ComponentName(context, VLCAppWidgetProvider.class);
-            AppWidgetManager manager = AppWidgetManager.getInstance(context);
-            manager.updateAppWidget(widget, views);
+            partial = false;
         }
-        else if (ACTION_WIDGET_UPDATE.equals(action)) {
-            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.vlcwidget);
 
+        if (ACTION_WIDGET_UPDATE.equals(action)) {
             String title = intent.getStringExtra("title");
             String artist = intent.getStringExtra("artist");
             boolean isplaying = intent.getBooleanExtra("isplaying", false);
-            Bitmap cover = intent.getParcelableExtra("cover");
 
             views.setTextViewText(R.id.songName, title);
             views.setTextViewText(R.id.artist, artist);
             views.setImageViewResource(R.id.play_pause, isplaying ? R.drawable.ic_pause : R.drawable.ic_play);
+            views.setViewVisibility(R.id.timeline_parent, artist != null && artist.length() > 0 ? View.VISIBLE : View.INVISIBLE);
+        }
+        else if (ACTION_WIDGET_UPDATE_COVER.equals(action)) {
+            Bitmap cover = intent.getParcelableExtra("cover");
             if (cover != null)
                 views.setImageViewBitmap(R.id.cover, cover);
             else
                 views.setImageViewResource(R.id.cover, R.drawable.cone);
-
-            views.setViewVisibility(R.id.timeline_parent, artist != null && artist.length() > 0 ? View.VISIBLE : View.INVISIBLE);
-
-            ComponentName widget = new ComponentName(context, VLCAppWidgetProvider.class);
-            AppWidgetManager manager = AppWidgetManager.getInstance(context);
-            manager.updateAppWidget(widget, views);
+            views.setProgressBar(R.id.timeline, 100, 0, false);
         }
         else if (ACTION_WIDGET_UPDATE_POSITION.equals(action)) {
-            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.vlcwidget);
-
             float pos = intent.getFloatExtra("position", 0f);
             views.setProgressBar(R.id.timeline, 100, (int) (100 * pos), false);
-
-            ComponentName widget = new ComponentName(context, VLCAppWidgetProvider.class);
-            AppWidgetManager manager = AppWidgetManager.getInstance(context);
-            manager.updateAppWidget(widget, views);
         }
+
+        ComponentName widget = new ComponentName(context, VLCAppWidgetProvider.class);
+        AppWidgetManager manager = AppWidgetManager.getInstance(context);
+        if (partial)
+            manager.partiallyUpdateAppWidget(manager.getAppWidgetIds(widget), views);
         else
-            super.onReceive(context, intent);
+            manager.updateAppWidget(widget, views);
     }
 }



More information about the Android mailing list