/* * 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. * * Modifications: * -Connect to VLC server instead of media service * -Listen for VLC status events * -Schedule status updates for time at which current track is expected to end */ package org.peterbaldwin.vlcremote.appwidget; import android.app.AlarmManager; 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.graphics.Bitmap; import android.net.ConnectivityManager; import android.os.SystemClock; import android.util.Log; import android.widget.RemoteViews; import org.peterbaldwin.client.android.vlcremote.R; import org.peterbaldwin.vlcremote.intent.Intents; import org.peterbaldwin.vlcremote.model.Preferences; import org.peterbaldwin.vlcremote.model.Status; import org.peterbaldwin.vlcremote.net.MediaServer; import org.peterbaldwin.vlcremote.widget.RemoteViewsFactory; /** * Simple widget to show currently playing album art along with play/pause and * next track buttons. */ public class MediaAppWidgetProvider extends AppWidgetProvider { public static final String LOG_TAG = "VlcRemoteAppWidgetProvider"; @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (Intents.ACTION_MANUAL_APPWIDGET_UPDATE.equals(action) || ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) { update(context); } else { super.onReceive(context, intent); } } public static int[] getWidgetIds(Context context) { AppWidgetManager app = AppWidgetManager.getInstance(context); ComponentName cn = new ComponentName(context, org.peterbaldwin.client.android.vlcremote.MediaAppWidgetProvider.class); return app.getAppWidgetIds(cn); } private static PendingIntent createManualAppWidgetUpdateIntent(Context context) { Intent intent = new Intent(Intents.ACTION_MANUAL_APPWIDGET_UPDATE); return PendingIntent.getBroadcast(context, 0, intent, 0); } /** * Schedule an update shortly after the current track is expected to end * @param context * @param status */ public static void scheduleUpdate(Context context, Status status) { long time = status.getTime(); long length = status.getLength(); if (status.isPlaying() && time >= 0L && length > 0L && time <= length) { long delay = (length - time + 1) * 1000; scheduleUpdate(context, delay); } else if(status.isPaused()) { scheduleUpdate(context, 1000 * 60 * 15); // check again in 15 mins } } private static void scheduleUpdate(Context context, long delay) { Object service = context.getSystemService(Context.ALARM_SERVICE); AlarmManager alarmManager = (AlarmManager) service; int type = AlarmManager.ELAPSED_REALTIME_WAKEUP; long triggerAtTime = SystemClock.elapsedRealtime() + delay; PendingIntent operation = createManualAppWidgetUpdateIntent(context); alarmManager.set(type, triggerAtTime, operation); } public static void cancelPendingUpdate(Context context) { Object service = context.getSystemService(Context.ALARM_SERVICE); AlarmManager alarmManager = (AlarmManager) service; PendingIntent operation = createManualAppWidgetUpdateIntent(context); alarmManager.cancel(operation); } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { context.startService(Intents.service(context, Intents.ACTION_PROGRAMMATIC_APPWIDGET_UPDATE)); } private void update(Context context) { String authority = Preferences.get(context).getAuthority(); if (authority != null) { new MediaServer(context, authority).status().get(); } else { update(context, context.getText(R.string.noserver).toString()); } } public static void update(Context context, Status status, Bitmap bitmap) { update(context, new RemoteViewsFactory(context).getWidget(status, bitmap)); } public static void update(Context context, Throwable tr) { update(context, new RemoteViewsFactory(context).getWidget(tr)); } public static void update(Context context, String title) { update(context, new RemoteViewsFactory(context).getWidget(title)); } private static void update(Context context, RemoteViews remote) { AppWidgetManager app = AppWidgetManager.getInstance(context); ComponentName cn = new ComponentName(context, org.peterbaldwin.client.android.vlcremote.MediaAppWidgetProvider.class); app.updateAppWidget(cn, remote); } }