Don't send bitmaps through a parcel; send Uri instead
This speeds things up quite a bit, but requires some reworking to the widget layouts...
This commit is contained in:
parent
4311632dd5
commit
25ce5d6daf
Binary file not shown.
Before Width: | Height: | Size: 3.0 KiB |
@ -29,7 +29,6 @@ THE SOFTWARE.
|
||||
android:background="#B2191919">
|
||||
<ImageView
|
||||
android:id="@+id/cover"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
android:adjustViewBounds="true"
|
||||
@ -46,6 +45,7 @@ THE SOFTWARE.
|
||||
android:paddingRight="8dip">
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:visibility="gone"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#fff"
|
||||
@ -56,6 +56,7 @@ THE SOFTWARE.
|
||||
android:ellipsize="none" />
|
||||
<TextView
|
||||
android:id="@+id/artist"
|
||||
android:text="@string/app_name"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#fff"
|
||||
@ -66,6 +67,7 @@ THE SOFTWARE.
|
||||
android:ellipsize="none" />
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/buttons"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent">
|
||||
@ -88,4 +90,4 @@ THE SOFTWARE.
|
||||
android:background="#0000"
|
||||
android:scaleType="fitCenter" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2010 Christopher Eby <kreed@kreed.org>
|
||||
Copyright (C) 2010, 2011 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
|
||||
@ -29,69 +29,75 @@ THE SOFTWARE.
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:src="@drawable/black"
|
||||
android:adjustViewBounds="true"
|
||||
android:padding="5dip"
|
||||
android:background="#B2191919"
|
||||
android:scaleType="fitCenter" />
|
||||
<LinearLayout
|
||||
android:id="@+id/text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_alignTop="@id/cover"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@+id/cover"
|
||||
android:layout_alignLeft="@+id/cover"
|
||||
android:layout_alignRight="@+id/cover"
|
||||
android:layout_margin="10dip"
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:visibility="gone"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textColor="#fff"
|
||||
android:textSize="18dip"
|
||||
android:shadowColor="#f000"
|
||||
android:shadowDx="0"
|
||||
android:shadowDy="0"
|
||||
android:shadowRadius="5"
|
||||
android:textStyle="bold"
|
||||
android:ellipsize="none"
|
||||
android:shadowDx="0"
|
||||
android:shadowDy="0"
|
||||
android:shadowRadius="5"
|
||||
android:textStyle="bold"
|
||||
android:ellipsize="marquee"
|
||||
android:singleLine="true" />
|
||||
<TextView
|
||||
android:id="@+id/artist"
|
||||
android:text="@string/app_name"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textColor="#fff"
|
||||
android:shadowColor="#f000"
|
||||
android:shadowDx="0"
|
||||
android:shadowDy="0"
|
||||
android:shadowRadius="5"
|
||||
android:shadowDx="0"
|
||||
android:shadowDy="0"
|
||||
android:shadowRadius="5"
|
||||
android:textSize="15dip"
|
||||
android:ellipsize="none"
|
||||
android:ellipsize="marquee"
|
||||
android:singleLine="true" />
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/buttons"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBottom="@+id/cover"
|
||||
android:layout_alignLeft="@+id/cover"
|
||||
android:layout_alignRight="@+id/cover">
|
||||
<ImageButton
|
||||
android:id="@+id/play_pause"
|
||||
android:src="@drawable/hidden_play"
|
||||
android:background="#0000"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="0px"
|
||||
android:layout_weight="1" />
|
||||
<ImageButton
|
||||
android:id="@+id/next"
|
||||
android:src="@drawable/hidden_next"
|
||||
android:background="#0000"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_width="fill_parent"
|
||||
android:orientation="vertical">
|
||||
<!-- A dummy view that takes up the top half of the widget -->
|
||||
<LinearLayout
|
||||
android:layout_height="0px"
|
||||
android:layout_width="0px"
|
||||
android:layout_weight="1" />
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="0px"
|
||||
android:layout_weight="1">
|
||||
<ImageButton
|
||||
android:id="@+id/play_pause"
|
||||
android:src="@drawable/hidden_play"
|
||||
android:background="@null"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_width="0px"
|
||||
android:layout_weight="1" />
|
||||
<ImageButton
|
||||
android:id="@+id/next"
|
||||
android:src="@drawable/hidden_next"
|
||||
android:background="@null"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_width="0px"
|
||||
android:layout_weight="1" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2010 Christopher Eby <kreed@kreed.org>
|
||||
Copyright (C) 2010, 2011 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
|
||||
@ -25,9 +25,23 @@ THE SOFTWARE.
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_width="fill_parent">
|
||||
<ImageView
|
||||
android:id="@+id/cover_view"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_width="fill_parent" />
|
||||
android:id="@+id/cover"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content" />
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:text="@string/app_name"
|
||||
android:layout_alignBottom="@id/cover"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textColor="#fff"
|
||||
android:background="#a000"
|
||||
android:textSize="12dip"
|
||||
android:textStyle="bold"
|
||||
android:ellipsize="marquee"
|
||||
android:singleLine="true" />
|
||||
<LinearLayout
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_width="fill_parent"
|
||||
@ -35,16 +49,16 @@ THE SOFTWARE.
|
||||
<ImageButton
|
||||
android:id="@+id/play_pause"
|
||||
android:src="@drawable/hidden_play"
|
||||
android:background="#0000"
|
||||
android:background="@null"
|
||||
android:layout_height="0px"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_weight="1" />
|
||||
<ImageButton
|
||||
android:id="@+id/next"
|
||||
android:src="@drawable/hidden_next"
|
||||
android:background="#0000"
|
||||
android:background="@null"
|
||||
android:layout_height="0px"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_weight="1" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
|
@ -59,8 +59,6 @@ public final class CoverBitmap {
|
||||
private static int TEXT_SIZE = -1;
|
||||
private static int TEXT_SIZE_BIG;
|
||||
private static int PADDING;
|
||||
private static int TEXT_SIZE_COMPACT = -1;
|
||||
private static int PADDING_COMPACT;
|
||||
private static int TEXT_SPACE;
|
||||
private static Bitmap SONG_ICON;
|
||||
private static Bitmap ALBUM_ICON;
|
||||
@ -78,16 +76,6 @@ public final class CoverBitmap {
|
||||
TEXT_SPACE = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 150, metrics);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the compact text size members.
|
||||
*/
|
||||
private static void loadMiniTextSizes()
|
||||
{
|
||||
DisplayMetrics metrics = ContextApplication.getContext().getResources().getDisplayMetrics();
|
||||
TEXT_SIZE_COMPACT = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 12, metrics);
|
||||
PADDING_COMPACT = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, metrics);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the icon bitmaps.
|
||||
*/
|
||||
@ -126,75 +114,6 @@ public final class CoverBitmap {
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a compact image, displaying cover art with the song title
|
||||
* overlaid at the bottom edge.
|
||||
*
|
||||
* @param song The song to display information for
|
||||
* @param width Desired width of image
|
||||
* @param height Desired height of image
|
||||
* @return The image, or null if the song was null, or width or height
|
||||
* were less than 1
|
||||
*/
|
||||
public static Bitmap createCompactBitmap(Song song, int width, int height)
|
||||
{
|
||||
if (song == null || width < 1 || height < 1)
|
||||
return null;
|
||||
|
||||
if (TEXT_SIZE_COMPACT == -1)
|
||||
loadMiniTextSizes();
|
||||
|
||||
int textSize = TEXT_SIZE_COMPACT;
|
||||
int padding = PADDING_COMPACT;
|
||||
|
||||
Paint paint = new Paint();
|
||||
paint.setAntiAlias(true);
|
||||
paint.setTextSize(textSize);
|
||||
|
||||
String title = song.title == null ? "" : song.title;
|
||||
Bitmap cover = song.getCover();
|
||||
|
||||
int titleWidth = (int)paint.measureText(title);
|
||||
|
||||
int boxWidth = width;
|
||||
int boxHeight = Math.min(height, textSize + padding * 2);
|
||||
|
||||
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
|
||||
if (cover != null) {
|
||||
int coverWidth = cover.getWidth();
|
||||
int coverHeight = cover.getHeight();
|
||||
|
||||
float scale = Math.min((float)width / coverWidth, (float)height / coverHeight);
|
||||
|
||||
coverWidth *= scale;
|
||||
coverHeight *= scale;
|
||||
|
||||
int x = (width - coverWidth) / 2;
|
||||
int y = (height - coverHeight) / 2;
|
||||
Rect rect = new Rect(x, y, x + coverWidth, y + coverHeight);
|
||||
canvas.drawBitmap(cover, null, rect, paint);
|
||||
}
|
||||
|
||||
int left = 0;
|
||||
int top = height - boxHeight;
|
||||
int right = width;
|
||||
int bottom = height;
|
||||
|
||||
paint.setARGB(150, 0, 0, 0);
|
||||
canvas.drawRect(left, top, right, bottom, paint);
|
||||
|
||||
int maxWidth = boxWidth - padding * 2;
|
||||
paint.setARGB(255, 255, 255, 255);
|
||||
top += padding;
|
||||
left += padding;
|
||||
|
||||
drawText(canvas, title, left, top, titleWidth, maxWidth, paint);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an image representing the given song. Includes cover art and
|
||||
* possibly song title/artist/ablum, depending on the given style.
|
||||
|
@ -28,8 +28,6 @@ import android.appwidget.AppWidgetProvider;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.view.View;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
@ -102,30 +100,19 @@ public class FourLongWidget extends AppWidgetProvider {
|
||||
if (ids == null || ids.length == 0)
|
||||
return;
|
||||
|
||||
Resources res = context.getResources();
|
||||
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.four_long_widget);
|
||||
|
||||
Bitmap cover = null;
|
||||
|
||||
if (song == null) {
|
||||
views.setViewVisibility(R.id.buttons, View.GONE);
|
||||
views.setViewVisibility(R.id.title, View.GONE);
|
||||
views.setViewVisibility(R.id.next, View.GONE);
|
||||
views.setViewVisibility(R.id.play_pause, View.GONE);
|
||||
views.setTextViewText(R.id.artist, res.getText(R.string.no_songs));
|
||||
views.setInt(R.id.artist, "setText", R.string.no_songs);
|
||||
views.setImageViewResource(R.id.cover, 0);
|
||||
} else {
|
||||
views.setViewVisibility(R.id.title, View.VISIBLE);
|
||||
views.setViewVisibility(R.id.next, View.VISIBLE);
|
||||
views.setViewVisibility(R.id.play_pause, View.VISIBLE);
|
||||
views.setViewVisibility(R.id.buttons, View.VISIBLE);
|
||||
views.setTextViewText(R.id.title, song.title);
|
||||
views.setTextViewText(R.id.artist, song.artist);
|
||||
cover = song.getCover();
|
||||
}
|
||||
|
||||
if (cover == null) {
|
||||
views.setViewVisibility(R.id.cover, View.GONE);
|
||||
} else {
|
||||
views.setViewVisibility(R.id.cover, View.VISIBLE);
|
||||
views.setImageViewBitmap(R.id.cover, cover);
|
||||
views.setImageViewUri(R.id.cover, song.getCoverUri());
|
||||
}
|
||||
|
||||
if (state != -1) {
|
||||
|
@ -28,8 +28,6 @@ import android.appwidget.AppWidgetProvider;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.view.View;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
@ -102,28 +100,21 @@ public class FourSquareWidget extends AppWidgetProvider {
|
||||
if (ids == null || ids.length == 0)
|
||||
return;
|
||||
|
||||
Resources res = context.getResources();
|
||||
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.four_square_widget);
|
||||
|
||||
Bitmap cover = null;
|
||||
|
||||
if (song == null) {
|
||||
views.setViewVisibility(R.id.title, View.GONE);
|
||||
views.setViewVisibility(R.id.buttons, View.GONE);
|
||||
views.setTextViewText(R.id.artist, res.getText(R.string.no_songs));
|
||||
views.setViewVisibility(R.id.title, View.GONE);
|
||||
views.setInt(R.id.artist, "setText", R.string.no_songs);
|
||||
views.setImageViewResource(R.id.cover, 0);
|
||||
} 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);
|
||||
cover = song.getCover();
|
||||
views.setImageViewUri(R.id.cover, song.getCoverUri());
|
||||
}
|
||||
|
||||
if (cover == null)
|
||||
views.setImageViewResource(R.id.cover, R.drawable.black);
|
||||
else
|
||||
views.setImageViewBitmap(R.id.cover, cover);
|
||||
|
||||
if (state != -1) {
|
||||
boolean playing = (state & PlaybackService.FLAG_PLAYING) != 0;
|
||||
views.setImageViewResource(R.id.play_pause, playing ? R.drawable.hidden_pause : R.drawable.hidden_play);
|
||||
|
@ -30,7 +30,6 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.TypedValue;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
/**
|
||||
@ -122,10 +121,11 @@ public class OneCellWidget extends AppWidgetProvider {
|
||||
views.setOnClickPendingIntent(R.id.next, PendingIntent.getService(context, 0, next, 0));
|
||||
|
||||
if (song == null) {
|
||||
views.setImageViewResource(R.id.cover_view, R.drawable.icon);
|
||||
views.setImageViewResource(R.id.cover, 0);
|
||||
views.setInt(R.id.title, "setText", R.string.no_songs);
|
||||
} else {
|
||||
int size = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 72, context.getResources().getDisplayMetrics());
|
||||
views.setImageViewBitmap(R.id.cover_view, CoverBitmap.createCompactBitmap(song, size, size));
|
||||
views.setImageViewUri(R.id.cover, song.getCoverUri());
|
||||
views.setTextViewText(R.id.title, song.title);
|
||||
}
|
||||
|
||||
manager.updateAppWidget(ids, views);
|
||||
|
@ -412,6 +412,20 @@ public class Song implements Parcelable {
|
||||
return cover;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a URI describing where the cover art is stored, or null if this
|
||||
* song has not been populated.
|
||||
*/
|
||||
public Uri getCoverUri()
|
||||
{
|
||||
// Use undocumented API to extract the cover from the media file from Eclair
|
||||
// See http://android.git.kernel.org/?p=platform/packages/apps/Music.git;a=blob;f=src/com/android/music/MusicUtils.java;h=d1aea0660009940a0160cb981f381e2115768845;hb=0749a3f1c11e052f97a3ba60fd624c9283ee7331#l986
|
||||
|
||||
if (id == -1)
|
||||
return null;
|
||||
return Uri.parse("content://media/external/audio/media/" + id + "/albumart");
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to read the album art directly from a media file using the
|
||||
* media ContentProvider.
|
||||
@ -421,13 +435,10 @@ public class Song implements Parcelable {
|
||||
*/
|
||||
private Bitmap getCoverFromMediaFile(ContentResolver resolver)
|
||||
{
|
||||
// Use undocumented API to extract the cover from the media file from Eclair
|
||||
// See http://android.git.kernel.org/?p=platform/packages/apps/Music.git;a=blob;f=src/com/android/music/MusicUtils.java;h=d1aea0660009940a0160cb981f381e2115768845;hb=0749a3f1c11e052f97a3ba60fd624c9283ee7331#l986
|
||||
Bitmap cover = null;
|
||||
|
||||
try {
|
||||
Uri uri = Uri.parse("content://media/external/audio/media/" + id + "/albumart");
|
||||
ParcelFileDescriptor parcelFileDescriptor = resolver.openFileDescriptor(uri, "r");
|
||||
ParcelFileDescriptor parcelFileDescriptor = resolver.openFileDescriptor(getCoverUri(), "r");
|
||||
if (parcelFileDescriptor != null) {
|
||||
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
|
||||
cover = BitmapFactory.decodeFileDescriptor(fileDescriptor, null, BITMAP_OPTIONS);
|
||||
|
Loading…
x
Reference in New Issue
Block a user