New 4x1 widget

This commit is contained in:
Christopher Eby 2012-02-25 21:13:33 -06:00
parent eea5deceb6
commit d30361fb8f
6 changed files with 273 additions and 83 deletions

View File

@ -70,7 +70,7 @@ THE SOFTWARE.
</receiver>
<receiver
android:name=".FourLongWidget"
android:label="Vanilla Music 4x1">
android:label="Vanilla Music 4x1 A">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
@ -78,6 +78,16 @@ THE SOFTWARE.
android:name="android.appwidget.provider"
android:resource="@xml/four_long_widget" />
</receiver>
<receiver
android:name=".WidgetE"
android:label="Vanilla Music 4x1 B">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_e" />
</receiver>
<receiver
android:name=".FourSquareWidget"
android:label="Vanilla Music 2x2 A">

View File

@ -30,86 +30,5 @@ THE SOFTWARE.
android:layout_height="fill_parent"
android:adjustViewBounds="true"
android:scaleType="fitCenter" />
<LinearLayout
android:background="#a000"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:textSize="16sp"
android:textColor="#ffff"
android:textStyle="bold"
android:singleLine="true"
android:ellipsize="marquee"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/artist"
android:textSize="14sp"
android:textColor="#ffff"
android:singleLine="true"
android:ellipsize="marquee"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/buttons"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageButton
android:id="@+id/shuffle"
android:adjustViewBounds="true"
android:layout_height="fill_parent"
android:layout_width="0px"
android:layout_weight="1"
android:background="@null"
android:scaleType="fitCenter"
android:src="@drawable/shuffle_inactive"
android:contentDescription="@string/cycle_shuffle_mode" />
<ImageButton
android:id="@+id/previous"
android:adjustViewBounds="true"
android:layout_height="fill_parent"
android:layout_width="0px"
android:layout_weight="1"
android:background="@null"
android:scaleType="fitCenter"
android:src="@drawable/previous"
android:contentDescription="@string/previous_song" />
<ImageButton
android:id="@+id/play_pause"
android:adjustViewBounds="true"
android:layout_height="fill_parent"
android:layout_width="0px"
android:layout_weight="1"
android:background="@null"
android:scaleType="fitCenter"
android:src="@drawable/play"
android:contentDescription="@string/play_pause" />
<ImageButton
android:id="@+id/next"
android:adjustViewBounds="true"
android:layout_height="fill_parent"
android:layout_width="0px"
android:layout_weight="1"
android:background="@null"
android:scaleType="fitCenter"
android:src="@drawable/next"
android:contentDescription="@string/next_song" />
<ImageButton
android:id="@+id/end_action"
android:adjustViewBounds="true"
android:layout_height="fill_parent"
android:layout_width="0px"
android:layout_weight="1"
android:background="@null"
android:scaleType="fitCenter"
android:src="@drawable/repeat_inactive"
android:contentDescription="@string/cycle_repeat_mode" />
</LinearLayout>
</LinearLayout>
<include layout="@layout/widget_e" />
</FrameLayout>

107
res/layout/widget_e.xml Normal file
View File

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2012 Christopher Eby <kreed@kreed.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#a000"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:textSize="16sp"
android:textColor="#ffff"
android:textStyle="bold"
android:singleLine="true"
android:ellipsize="marquee"
android:gravity="center"
android:layout_width="fill_parent"
android:visibility="gone"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/artist"
android:text="@string/app_name"
android:textSize="14sp"
android:textColor="#ffff"
android:singleLine="true"
android:ellipsize="marquee"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/buttons"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageButton
android:id="@+id/shuffle"
android:adjustViewBounds="true"
android:layout_height="fill_parent"
android:layout_width="0px"
android:layout_weight="1"
android:background="@null"
android:scaleType="fitCenter"
android:src="@drawable/shuffle_inactive"
android:contentDescription="@string/cycle_shuffle_mode" />
<ImageButton
android:id="@+id/previous"
android:adjustViewBounds="true"
android:layout_height="fill_parent"
android:layout_width="0px"
android:layout_weight="1"
android:background="@null"
android:scaleType="fitCenter"
android:src="@drawable/previous"
android:contentDescription="@string/previous_song" />
<ImageButton
android:id="@+id/play_pause"
android:adjustViewBounds="true"
android:layout_height="fill_parent"
android:layout_width="0px"
android:layout_weight="1"
android:background="@null"
android:scaleType="fitCenter"
android:src="@drawable/play"
android:contentDescription="@string/play_pause" />
<ImageButton
android:id="@+id/next"
android:adjustViewBounds="true"
android:layout_height="fill_parent"
android:layout_width="0px"
android:layout_weight="1"
android:background="@null"
android:scaleType="fitCenter"
android:src="@drawable/next"
android:contentDescription="@string/next_song" />
<ImageButton
android:id="@+id/end_action"
android:adjustViewBounds="true"
android:layout_height="fill_parent"
android:layout_width="0px"
android:layout_weight="1"
android:background="@null"
android:scaleType="fitCenter"
android:src="@drawable/repeat_inactive"
android:contentDescription="@string/cycle_repeat_mode" />
</LinearLayout>
</LinearLayout>

7
res/xml/widget_e.xml Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="250dip"
android:minHeight="40dip"
android:initialLayout="@layout/widget_e"
android:resizeMode="horizontal|vertical" />

View File

@ -800,6 +800,7 @@ public final class PlaybackService extends Service
FourSquareWidget.checkEnabled(this, manager);
FourLongWidget.checkEnabled(this, manager);
WidgetD.checkEnabled(this, manager);
WidgetE.checkEnabled(this, manager);
}
/**
@ -814,6 +815,7 @@ public final class PlaybackService extends Service
FourLongWidget.updateWidget(this, manager, song, state);
FourSquareWidget.updateWidget(this, manager, song, state);
WidgetD.updateWidget(this, manager, song, state);
WidgetE.updateWidget(this, manager, song, state);
}
/**

View File

@ -0,0 +1,145 @@
/*
* Copyright (C) 2012 Christopher Eby <kreed@kreed.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.kreed.vanilla;
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.view.View;
import android.widget.RemoteViews;
/**
* 4x1 widget with many playback controls
*/
public class WidgetE extends AppWidgetProvider {
private static boolean sEnabled;
@Override
public void onEnabled(Context context)
{
sEnabled = true;
}
@Override
public void onDisabled(Context context)
{
sEnabled = false;
}
@Override
public void onUpdate(Context context, AppWidgetManager manager, int[] ids)
{
Song song = null;
int state = 0;
if (PlaybackService.hasInstance()) {
PlaybackService service = PlaybackService.get(context);
song = service.getSong(0);
state = service.getState();
}
sEnabled = true;
updateWidget(context, manager, song, state);
}
/**
* Check if there are any instances of this widget placed.
*/
public static void checkEnabled(Context context, AppWidgetManager manager)
{
sEnabled = manager.getAppWidgetIds(new ComponentName(context, WidgetE.class)).length != 0;
}
/**
* Populate the widgets with the given ids with the given info.
*
* @param context A Context to use.
* @param manager The AppWidgetManager that will be used to update the
* widget.
* @param song The current Song in PlaybackService.
* @param state The current PlaybackService state.
*/
public static void updateWidget(Context context, AppWidgetManager manager, Song song, int state)
{
if (!sEnabled)
return;
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_e);
if ((state & PlaybackService.FLAG_NO_MEDIA) != 0) {
views.setViewVisibility(R.id.buttons, View.GONE);
views.setViewVisibility(R.id.title, View.GONE);
views.setInt(R.id.artist, "setText", R.string.no_songs);
} else if (song == null) {
views.setViewVisibility(R.id.buttons, View.VISIBLE);
views.setViewVisibility(R.id.title, View.GONE);
views.setInt(R.id.artist, "setText", R.string.app_name);
} else {
views.setViewVisibility(R.id.title, View.VISIBLE);
views.setViewVisibility(R.id.buttons, View.VISIBLE);
views.setTextViewText(R.id.title, song.title);
views.setTextViewText(R.id.artist, song.artist);
}
boolean playing = (state & PlaybackService.FLAG_PLAYING) != 0;
views.setImageViewResource(R.id.play_pause, playing ? R.drawable.pause : R.drawable.play);
views.setImageViewResource(R.id.end_action, SongTimeline.FINISH_ICONS[PlaybackService.finishAction(state)]);
views.setImageViewResource(R.id.shuffle, SongTimeline.SHUFFLE_ICONS[PlaybackService.shuffleMode(state)]);
Intent intent;
PendingIntent pendingIntent;
ComponentName service = new ComponentName(context, PlaybackService.class);
intent = new Intent(context, LibraryActivity.class);
intent.setAction(Intent.ACTION_MAIN);
pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.title, pendingIntent);
views.setOnClickPendingIntent(R.id.artist, pendingIntent);
intent = new Intent(PlaybackService.ACTION_TOGGLE_PLAYBACK).setComponent(service);
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.play_pause, pendingIntent);
intent = new Intent(PlaybackService.ACTION_NEXT_SONG).setComponent(service);
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.next, pendingIntent);
intent = new Intent(PlaybackService.ACTION_PREVIOUS_SONG).setComponent(service);
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.previous, pendingIntent);
intent = new Intent(PlaybackService.ACTION_CYCLE_SHUFFLE).setComponent(service);
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.shuffle, pendingIntent);
intent = new Intent(PlaybackService.ACTION_CYCLE_REPEAT).setComponent(service);
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.end_action, pendingIntent);
manager.updateAppWidget(new ComponentName(context, WidgetE.class), views);
}
}