add onClickListeners, optimize image loading

This commit is contained in:
Domingos Lopes 2016-06-28 15:48:51 -04:00
parent 6d0debfd4d
commit 47015e937e
3 changed files with 139 additions and 24 deletions

View File

@ -1,29 +1,43 @@
package de.danoeh.antennapod.cast;
import android.app.PendingIntent;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.RemoteException;
import android.support.annotation.NonNull;
import android.support.v4.media.MediaDescriptionCompat;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaControllerCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
import android.support.v4.view.accessibility.AccessibilityEventCompat;
import android.support.v7.app.MediaRouteControllerDialog;
import android.support.v7.graphics.Palette;
import android.support.v7.media.MediaRouter;
import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.Target;
import java.util.concurrent.ExecutionException;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
public class CustomMRControllerDialog extends MediaRouteControllerDialog {
public static final String TAG = "CustomMRContrDialog";
@ -37,6 +51,10 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog {
private ImageButton playPauseButton;
private LinearLayout rootView;
private boolean viewsCreated = false;
private FetchArtTask fetchArtTask;
private MediaControllerCompat mediaController;
private MediaControllerCompat.Callback mediaControllerCallback;
@ -87,10 +105,24 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog {
ViewGroup.LayoutParams.WRAP_CONTENT));
rootView.setOrientation(LinearLayout.VERTICAL);
// Start the session activity when a content item (album art, title or subtitle) is clicked.
View.OnClickListener onClickListener = v -> {
if (mediaController != null) {
PendingIntent pi = mediaController.getSessionActivity();
if (pi != null) {
try {
pi.send();
dismiss();
} catch (PendingIntent.CanceledException e) {
Log.e(TAG, pi + " was not sent, it had been canceled.");
}
}
}
};
artView = new ImageView(getContext()) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int desiredWidth = widthMeasureSpec;
int desiredHeight = heightMeasureSpec;
if (MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY) {
Drawable drawable = getDrawable();
@ -110,26 +142,53 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog {
}
}
super.onMeasure(desiredWidth, desiredHeight);
super.onMeasure(widthMeasureSpec, desiredHeight);
}
};
artView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
artView.setScaleType(ImageView.ScaleType.FIT_CENTER);
artView.setOnClickListener(onClickListener);
rootView.addView(artView);
View playbackControlLayout = View.inflate(getContext(), R.layout.media_router_controller, rootView);
titleView = (TextView) playbackControlLayout.findViewById(R.id.mrc_control_title);
subtitleView = (TextView) playbackControlLayout.findViewById(R.id.mrc_control_subtitle);
playbackControlLayout.findViewById(R.id.mrc_control_title_container).setOnClickListener(onClickListener);
playPauseButton = (ImageButton) playbackControlLayout.findViewById(R.id.mrc_control_play_pause);
playPauseButton.setOnClickListener(v -> {
PlaybackStateCompat state;
if (mediaController != null && (state = mediaController.getPlaybackState()) != null) {
boolean isPlaying = state.getState() == PlaybackStateCompat.STATE_PLAYING;
if (isPlaying) {
mediaController.getTransportControls().pause();
} else {
mediaController.getTransportControls().play();
}
// Announce the action for accessibility.
AccessibilityManager accessibilityManager = (AccessibilityManager)
getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
if (accessibilityManager != null && accessibilityManager.isEnabled()) {
AccessibilityEvent event = AccessibilityEvent.obtain(
AccessibilityEventCompat.TYPE_ANNOUNCEMENT);
event.setPackageName(getContext().getPackageName());
event.setClassName(getClass().getName());
int resId = isPlaying ?
android.support.v7.mediarouter.R.string.mr_controller_pause : android.support.v7.mediarouter.R.string.mr_controller_play;
event.getText().add(getContext().getString(resId));
accessibilityManager.sendAccessibilityEvent(event);
}
}
});
viewsCreated = true;
updateViews();
return rootView;
}
private void updateViews() {
if (token == null || artView == null || mediaController == null) {
if (!viewsCreated || token == null || mediaController == null) {
rootView.setVisibility(View.GONE);
return;
}
@ -174,19 +233,27 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog {
showSubtitle = true;
}
}
if (showSubtitle) {
titleView.setSingleLine();
} else {
titleView.setMaxLines(2);
}
titleView.setVisibility(showTitle ? View.VISIBLE : View.GONE);
subtitleView.setVisibility(showSubtitle ? View.VISIBLE : View.GONE);
updateState();
Bitmap art = metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_ART);
if (art == null) {
if(rootView.getVisibility() != View.VISIBLE) {
artView.setVisibility(View.GONE);
return;
rootView.setVisibility(View.VISIBLE);
}
artView.setImageBitmap(art);
artView.setVisibility(View.VISIBLE);
rootView.setVisibility(View.VISIBLE);
if (fetchArtTask != null) {
fetchArtTask.cancel(true);
}
fetchArtTask = new FetchArtTask(description);
fetchArtTask.execute();
}
private void updateState() {
@ -223,4 +290,58 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog {
TypedValue value = new TypedValue();
return context.getTheme().resolveAttribute(attr, value, true) ? value.resourceId : 0;
}
private class FetchArtTask extends AsyncTask<Void, Void, Bitmap> {
final Bitmap iconBitmap;
final Uri iconUri;
int backgroundColor;
FetchArtTask(@NonNull MediaDescriptionCompat description) {
iconBitmap = description.getIconBitmap();
iconUri = description.getIconUri();
}
@Override
protected Bitmap doInBackground(Void... arg) {
Bitmap art = null;
if (iconBitmap != null) {
art = iconBitmap;
} else if (iconUri != null) {
try {
art = Glide.with(getContext().getApplicationContext())
.load(iconUri.toString())
.asBitmap()
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
.into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
.get();
} catch (InterruptedException | ExecutionException e) {
Log.e(TAG, "Image art load failed", e);
}
}
if (art != null && art.getWidth()*9 < art.getHeight()*16) {
// Portrait art requires dominant color as background color.
Palette palette = new Palette.Builder(art).maximumColorCount(1).generate();
backgroundColor = palette.getSwatches().isEmpty()
? 0 : palette.getSwatches().get(0).getRgb();
}
return art;
}
@Override
protected void onCancelled() {
fetchArtTask = null;
}
@Override
protected void onPostExecute(Bitmap art) {
fetchArtTask = null;
if (art != null) {
artView.setBackgroundColor(backgroundColor);
artView.setImageBitmap(art);
artView.setVisibility(View.VISIBLE);
} else {
artView.setVisibility(View.GONE);
}
}
}
}

View File

@ -39,12 +39,12 @@
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toLeftOf="@id/mrc_control_play_pause"
android:layout_toStartOf="@id/mrc_control_play_pause">
android:layout_toStartOf="@id/mrc_control_play_pause"
android:layout_centerVertical="true">
<TextView android:id="@+id/mrc_control_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?attr/mediaRouteControllerPrimaryTextStyle"
android:singleLine="true" />
android:textAppearance="?attr/mediaRouteControllerPrimaryTextStyle"/>
<TextView android:id="@+id/mrc_control_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@ -939,16 +939,16 @@ public class PlaybackService extends Service {
MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
builder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, p.getFeedTitle());
builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, p.getEpisodeTitle());
builder.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, p.getFeedTitle());
builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, p.getDuration());
builder.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, p.getEpisodeTitle());
builder.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, p.getFeedTitle());
builder.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, p.getFeedTitle());
String imageLocation = p.getImageLocation();
if (!TextUtils.isEmpty(imageLocation)) {
if (isCasting || UserPreferences.setLockscreenBackground()) {
if (UserPreferences.setLockscreenBackground()) {
builder.putString(MediaMetadataCompat.METADATA_KEY_ART_URI, imageLocation);
builder.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI, imageLocation);
try {
Bitmap art = Glide.with(this)
.load(imageLocation)
@ -957,18 +957,12 @@ public class PlaybackService extends Service {
.into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
.get();
builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, art);
// Icon is useful for MediaDescription,
Bitmap icon = Glide.with(this)
.load(imageLocation)
.asBitmap()
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
.fitCenter()
.into(128, 128)
.get();
builder.putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, icon);
} catch (Throwable tr) {
Log.e(TAG, Log.getStackTraceString(tr));
}
} else if (isCasting) {
// In the absence of metadata art, the controller dialog takes care of creating it.
builder.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI, imageLocation);
}
}
if (!Thread.currentThread().isInterrupted() && started) {