mirror of
https://github.com/antebudimir/tempus.git
synced 2025-12-31 09:33:33 +00:00
cache artwork bitmap
This commit is contained in:
parent
eb5c4721d1
commit
b335ddec01
3 changed files with 97 additions and 28 deletions
|
|
@ -5,6 +5,8 @@ import android.app.PendingIntent.FLAG_IMMUTABLE
|
|||
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
||||
import android.app.TaskStackBuilder
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.Network
|
||||
import android.net.NetworkCapabilities
|
||||
|
|
@ -13,6 +15,7 @@ import android.os.Bundle
|
|||
import android.os.IBinder
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import androidx.media3.common.*
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
|
|
@ -21,7 +24,10 @@ import androidx.media3.exoplayer.ExoPlayer
|
|||
import androidx.media3.exoplayer.source.MediaSource
|
||||
import androidx.media3.session.*
|
||||
import androidx.media3.session.MediaSession.ControllerInfo
|
||||
import com.bumptech.glide.request.target.CustomTarget
|
||||
import com.bumptech.glide.request.transition.Transition
|
||||
import com.cappielloantonio.tempo.R
|
||||
import com.cappielloantonio.tempo.glide.CustomGlideRequest
|
||||
import com.cappielloantonio.tempo.repository.QueueRepository
|
||||
import com.cappielloantonio.tempo.ui.activity.MainActivity
|
||||
import com.cappielloantonio.tempo.util.AssetLinkUtil
|
||||
|
|
@ -35,6 +41,7 @@ import com.cappielloantonio.tempo.widget.WidgetUpdateManager
|
|||
import com.google.common.collect.ImmutableList
|
||||
import com.google.common.util.concurrent.Futures
|
||||
import com.google.common.util.concurrent.ListenableFuture
|
||||
import java.util.Optional
|
||||
|
||||
|
||||
@UnstableApi
|
||||
|
|
@ -61,6 +68,7 @@ class MediaService : MediaLibraryService() {
|
|||
widgetUpdateHandler.postDelayed(this, WIDGET_UPDATE_INTERVAL_MS)
|
||||
}
|
||||
}
|
||||
@Volatile private var artCache : Optional<Optional<Bitmap>> = Optional.empty<Optional<Bitmap>>()
|
||||
|
||||
inner class LocalBinder : Binder() {
|
||||
fun getEqualizerManager(): EqualizerManager {
|
||||
|
|
@ -368,6 +376,7 @@ class MediaService : MediaLibraryService() {
|
|||
}
|
||||
|
||||
override fun onIsPlayingChanged(isPlaying: Boolean) {
|
||||
artCache = Optional.empty()
|
||||
if (!isPlaying) {
|
||||
MediaManager.setPlayingPausedTimestamp(
|
||||
player.currentMediaItem,
|
||||
|
|
@ -494,6 +503,16 @@ class MediaService : MediaLibraryService() {
|
|||
.build()
|
||||
}
|
||||
|
||||
private inner class CustomGlideTarget : CustomTarget<Bitmap>() {
|
||||
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
|
||||
artCache = Optional.of(Optional.of(resource))
|
||||
}
|
||||
|
||||
override fun onLoadCleared(placeholder: Drawable?) {
|
||||
artCache = Optional.of(Optional.empty())
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateWidget() {
|
||||
val mi = player.currentMediaItem
|
||||
val title = mi?.mediaMetadata?.title?.toString()
|
||||
|
|
@ -512,12 +531,21 @@ class MediaService : MediaLibraryService() {
|
|||
?: AssetLinkUtil.buildLink(AssetLinkUtil.TYPE_ARTIST, extras?.getString("artistId"))
|
||||
val position = player.currentPosition.takeIf { it != C.TIME_UNSET } ?: 0L
|
||||
val duration = player.duration.takeIf { it != C.TIME_UNSET } ?: 0L
|
||||
|
||||
if (!TextUtils.isEmpty(coverId) && artCache.isEmpty) {
|
||||
CustomGlideRequest.loadAlbumArtBitmap(
|
||||
applicationContext,
|
||||
coverId,
|
||||
WidgetUpdateManager.WIDGET_SAFE_ART_SIZE,
|
||||
CustomGlideTarget())
|
||||
}
|
||||
|
||||
WidgetUpdateManager.updateFromState(
|
||||
this,
|
||||
title ?: "",
|
||||
artist ?: "",
|
||||
album ?: "",
|
||||
coverId,
|
||||
artCache,
|
||||
player.isPlaying,
|
||||
player.shuffleModeEnabled,
|
||||
player.repeatMode,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@ import com.bumptech.glide.request.transition.Transition;
|
|||
import com.cappielloantonio.tempo.glide.CustomGlideRequest;
|
||||
import com.cappielloantonio.tempo.R;
|
||||
|
||||
import androidx.annotation.OptIn;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.session.MediaController;
|
||||
import androidx.media3.session.SessionToken;
|
||||
|
||||
|
|
@ -23,11 +25,12 @@ import com.cappielloantonio.tempo.util.MusicUtil;
|
|||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public final class WidgetUpdateManager {
|
||||
|
||||
private static final int WIDGET_SAFE_ART_SIZE = 512;
|
||||
public static final int WIDGET_SAFE_ART_SIZE = 512;
|
||||
|
||||
public static void updateFromState(Context ctx,
|
||||
String title,
|
||||
|
|
@ -68,11 +71,12 @@ public final class WidgetUpdateManager {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static void updateFromState(Context ctx,
|
||||
String title,
|
||||
String artist,
|
||||
String album,
|
||||
String coverArtId,
|
||||
Optional<Optional<Bitmap>> coverArt,
|
||||
boolean playing,
|
||||
boolean shuffleEnabled,
|
||||
int repeatMode,
|
||||
|
|
@ -93,16 +97,10 @@ public final class WidgetUpdateManager {
|
|||
final String albumLinkFinal = albumLink;
|
||||
final String artistLinkFinal = artistLink;
|
||||
|
||||
if (!TextUtils.isEmpty(coverArtId)) {
|
||||
CustomGlideRequest.loadAlbumArtBitmap(
|
||||
appCtx,
|
||||
coverArtId,
|
||||
WIDGET_SAFE_ART_SIZE,
|
||||
new CustomTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
|
||||
AppWidgetManager mgr = AppWidgetManager.getInstance(appCtx);
|
||||
int[] ids = mgr.getAppWidgetIds(new ComponentName(appCtx, WidgetProvider4x1.class));
|
||||
Bitmap resource = coverArt.filter(Optional::isPresent).map(Optional::get).orElse(null);
|
||||
|
||||
for (int id : ids) {
|
||||
android.widget.RemoteViews rv = choosePopulate(appCtx, t, a, alb, resource, p,
|
||||
timing.elapsedText, timing.totalText, timing.progress, sh, rep, id);
|
||||
|
|
@ -111,31 +109,46 @@ public final class WidgetUpdateManager {
|
|||
}
|
||||
}
|
||||
|
||||
public static void updateFromState(Context ctx,
|
||||
String title,
|
||||
String artist,
|
||||
String album,
|
||||
String coverArtId,
|
||||
boolean playing,
|
||||
boolean shuffleEnabled,
|
||||
int repeatMode,
|
||||
long positionMs,
|
||||
long durationMs,
|
||||
String songLink,
|
||||
String albumLink,
|
||||
String artistLink) {
|
||||
final Context appCtx = ctx.getApplicationContext();
|
||||
if (!TextUtils.isEmpty(coverArtId)) {
|
||||
CustomGlideRequest.loadAlbumArtBitmap(
|
||||
appCtx,
|
||||
coverArtId,
|
||||
WIDGET_SAFE_ART_SIZE,
|
||||
new CustomTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
|
||||
updateFromState(ctx, title, artist, album, Optional.of(Optional.of(resource)),
|
||||
playing, shuffleEnabled, repeatMode, positionMs, durationMs, songLink, albumLink, artistLink);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadCleared(Drawable placeholder) {
|
||||
AppWidgetManager mgr = AppWidgetManager.getInstance(appCtx);
|
||||
int[] ids = mgr.getAppWidgetIds(new ComponentName(appCtx, WidgetProvider4x1.class));
|
||||
for (int id : ids) {
|
||||
android.widget.RemoteViews rv = choosePopulate(appCtx, t, a, alb, null, p,
|
||||
timing.elapsedText, timing.totalText, timing.progress, sh, rep, id);
|
||||
WidgetProvider.attachIntents(appCtx, rv, id, songLinkFinal, albumLinkFinal, artistLinkFinal);
|
||||
mgr.updateAppWidget(id, rv);
|
||||
}
|
||||
updateFromState(ctx, title, artist, album, Optional.of(Optional.empty()),
|
||||
playing, shuffleEnabled, repeatMode, positionMs, durationMs, songLink, albumLink, artistLink);
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
AppWidgetManager mgr = AppWidgetManager.getInstance(appCtx);
|
||||
int[] ids = mgr.getAppWidgetIds(new ComponentName(appCtx, WidgetProvider4x1.class));
|
||||
for (int id : ids) {
|
||||
android.widget.RemoteViews rv = choosePopulate(appCtx, t, a, alb, null, p,
|
||||
timing.elapsedText, timing.totalText, timing.progress, sh, rep, id);
|
||||
WidgetProvider.attachIntents(appCtx, rv, id, songLinkFinal, albumLinkFinal, artistLinkFinal);
|
||||
mgr.updateAppWidget(id, rv);
|
||||
}
|
||||
updateFromState(ctx, title, artist, album, Optional.of(Optional.empty()),
|
||||
playing, shuffleEnabled, repeatMode, positionMs, durationMs, songLink, albumLink, artistLink);
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
public static void refreshFromController(Context ctx) {
|
||||
final Context appCtx = ctx.getApplicationContext();
|
||||
SessionToken token = new SessionToken(appCtx, new ComponentName(appCtx, MediaService.class));
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import android.app.PendingIntent.FLAG_IMMUTABLE
|
|||
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
||||
import android.app.TaskStackBuilder
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.Network
|
||||
import android.net.NetworkCapabilities
|
||||
|
|
@ -11,6 +13,7 @@ import android.os.Binder
|
|||
import android.os.IBinder
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.media3.cast.CastPlayer
|
||||
|
|
@ -25,7 +28,10 @@ import androidx.media3.exoplayer.DefaultLoadControl
|
|||
import androidx.media3.exoplayer.ExoPlayer
|
||||
import androidx.media3.session.MediaLibraryService
|
||||
import androidx.media3.session.MediaSession.ControllerInfo
|
||||
import com.bumptech.glide.request.target.CustomTarget
|
||||
import com.bumptech.glide.request.transition.Transition
|
||||
import com.cappielloantonio.tempo.repository.AutomotiveRepository
|
||||
import com.cappielloantonio.tempo.glide.CustomGlideRequest
|
||||
import com.cappielloantonio.tempo.repository.QueueRepository
|
||||
import com.cappielloantonio.tempo.ui.activity.MainActivity
|
||||
import com.cappielloantonio.tempo.util.AssetLinkUtil
|
||||
|
|
@ -39,6 +45,7 @@ import com.cappielloantonio.tempo.widget.WidgetUpdateManager
|
|||
import com.google.android.gms.cast.framework.CastContext
|
||||
import com.google.android.gms.common.ConnectionResult
|
||||
import com.google.android.gms.common.GoogleApiAvailability
|
||||
import java.util.Optional
|
||||
|
||||
@UnstableApi
|
||||
class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
||||
|
|
@ -49,6 +56,7 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
|||
private lateinit var librarySessionCallback: MediaLibrarySessionCallback
|
||||
private lateinit var networkCallback: CustomNetworkCallback
|
||||
lateinit var equalizerManager: EqualizerManager
|
||||
@Volatile private var artCache : Optional<Optional<Bitmap>> = Optional.empty<Optional<Bitmap>>()
|
||||
|
||||
inner class LocalBinder : Binder() {
|
||||
fun getEqualizerManager(): EqualizerManager {
|
||||
|
|
@ -278,6 +286,7 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
|||
}
|
||||
|
||||
override fun onIsPlayingChanged(isPlaying: Boolean) {
|
||||
artCache = Optional.empty()
|
||||
if (!isPlaying) {
|
||||
MediaManager.setPlayingPausedTimestamp(
|
||||
player.currentMediaItem,
|
||||
|
|
@ -339,6 +348,16 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
|||
}
|
||||
}
|
||||
|
||||
private inner class CustomGlideTarget : CustomTarget<Bitmap>() {
|
||||
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
|
||||
artCache = Optional.of(Optional.of(resource))
|
||||
}
|
||||
|
||||
override fun onLoadCleared(placeholder: Drawable?) {
|
||||
artCache = Optional.of(Optional.empty())
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateWidget() {
|
||||
val mi = player.currentMediaItem
|
||||
val title = mi?.mediaMetadata?.title?.toString()
|
||||
|
|
@ -357,12 +376,21 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
|||
?: AssetLinkUtil.buildLink(AssetLinkUtil.TYPE_ARTIST, extras?.getString("artistId"))
|
||||
val position = player.currentPosition.takeIf { it != C.TIME_UNSET } ?: 0L
|
||||
val duration = player.duration.takeIf { it != C.TIME_UNSET } ?: 0L
|
||||
|
||||
if (!TextUtils.isEmpty(coverId) && artCache.isEmpty) {
|
||||
CustomGlideRequest.loadAlbumArtBitmap(
|
||||
applicationContext,
|
||||
coverId,
|
||||
WidgetUpdateManager.WIDGET_SAFE_ART_SIZE,
|
||||
CustomGlideTarget())
|
||||
}
|
||||
|
||||
WidgetUpdateManager.updateFromState(
|
||||
this,
|
||||
title ?: "",
|
||||
artist ?: "",
|
||||
album ?: "",
|
||||
coverId,
|
||||
artCache,
|
||||
player.isPlaying,
|
||||
player.shuffleModeEnabled,
|
||||
player.repeatMode,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue