mirror of
https://github.com/antebudimir/tempus.git
synced 2025-12-31 09:33:33 +00:00
avoid full updates
This commit is contained in:
parent
b335ddec01
commit
be9eec625a
3 changed files with 108 additions and 65 deletions
|
|
@ -4,7 +4,10 @@ import android.annotation.SuppressLint
|
||||||
import android.app.PendingIntent.FLAG_IMMUTABLE
|
import android.app.PendingIntent.FLAG_IMMUTABLE
|
||||||
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
import android.app.TaskStackBuilder
|
import android.app.TaskStackBuilder
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.IntentFilter
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
|
|
@ -60,7 +63,7 @@ class MediaService : MediaLibraryService() {
|
||||||
private var widgetUpdateScheduled = false
|
private var widgetUpdateScheduled = false
|
||||||
private val widgetUpdateRunnable = object : Runnable {
|
private val widgetUpdateRunnable = object : Runnable {
|
||||||
override fun run() {
|
override fun run() {
|
||||||
if (!player.isPlaying) {
|
if (!player.isPlaying || !screenOn) {
|
||||||
widgetUpdateScheduled = false
|
widgetUpdateScheduled = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -68,7 +71,29 @@ class MediaService : MediaLibraryService() {
|
||||||
widgetUpdateHandler.postDelayed(this, WIDGET_UPDATE_INTERVAL_MS)
|
widgetUpdateHandler.postDelayed(this, WIDGET_UPDATE_INTERVAL_MS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Volatile private var artCache : Optional<Optional<Bitmap>> = Optional.empty<Optional<Bitmap>>()
|
|
||||||
|
private var prevPlayerStates = Triple(false, false, -1)
|
||||||
|
@Volatile private var nowPlayingChanged = false
|
||||||
|
@Volatile private var artCacheUpdated = false
|
||||||
|
@Volatile private var artCache : Bitmap? = null
|
||||||
|
@Volatile private var screenOn = true
|
||||||
|
|
||||||
|
val broadCastReceiver = object : BroadcastReceiver() {
|
||||||
|
override fun onReceive(contxt: Context?, intent: Intent?) {
|
||||||
|
when (intent?.action) {
|
||||||
|
Intent.ACTION_SCREEN_ON -> {
|
||||||
|
Log.d("MediaService", "screenOn");
|
||||||
|
screenOn = true
|
||||||
|
widgetUpdateHandler.post(widgetUpdateRunnable)
|
||||||
|
}
|
||||||
|
Intent.ACTION_SCREEN_OFF -> {
|
||||||
|
Log.d("MediaService", "screenOff");
|
||||||
|
screenOn = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inner class LocalBinder : Binder() {
|
inner class LocalBinder : Binder() {
|
||||||
fun getEqualizerManager(): EqualizerManager {
|
fun getEqualizerManager(): EqualizerManager {
|
||||||
|
|
@ -134,6 +159,7 @@ class MediaService : MediaLibraryService() {
|
||||||
initializePlayerListener()
|
initializePlayerListener()
|
||||||
initializeEqualizerManager()
|
initializeEqualizerManager()
|
||||||
initializeNetworkListener()
|
initializeNetworkListener()
|
||||||
|
initializeScreenListener()
|
||||||
|
|
||||||
setPlayer(player)
|
setPlayer(player)
|
||||||
}
|
}
|
||||||
|
|
@ -143,6 +169,7 @@ class MediaService : MediaLibraryService() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
unregisterReceiver(broadCastReceiver)
|
||||||
releaseNetworkCallback()
|
releaseNetworkCallback()
|
||||||
equalizerManager.release()
|
equalizerManager.release()
|
||||||
stopWidgetUpdates()
|
stopWidgetUpdates()
|
||||||
|
|
@ -288,6 +315,12 @@ class MediaService : MediaLibraryService() {
|
||||||
player.repeatMode = Preferences.getRepeatMode()
|
player.repeatMode = Preferences.getRepeatMode()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initializeScreenListener() {
|
||||||
|
val filter = IntentFilter(Intent.ACTION_SCREEN_ON)
|
||||||
|
filter.addAction(Intent.ACTION_SCREEN_OFF)
|
||||||
|
registerReceiver(broadCastReceiver, filter)
|
||||||
|
}
|
||||||
|
|
||||||
private fun initializeEqualizerManager() {
|
private fun initializeEqualizerManager() {
|
||||||
equalizerManager = EqualizerManager()
|
equalizerManager = EqualizerManager()
|
||||||
val audioSessionId = player.audioSessionId
|
val audioSessionId = player.audioSessionId
|
||||||
|
|
@ -376,7 +409,9 @@ class MediaService : MediaLibraryService() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onIsPlayingChanged(isPlaying: Boolean) {
|
override fun onIsPlayingChanged(isPlaying: Boolean) {
|
||||||
artCache = Optional.empty()
|
nowPlayingChanged = true
|
||||||
|
artCacheUpdated = false
|
||||||
|
artCache = null
|
||||||
if (!isPlaying) {
|
if (!isPlaying) {
|
||||||
MediaManager.setPlayingPausedTimestamp(
|
MediaManager.setPlayingPausedTimestamp(
|
||||||
player.currentMediaItem,
|
player.currentMediaItem,
|
||||||
|
|
@ -390,7 +425,8 @@ class MediaService : MediaLibraryService() {
|
||||||
} else {
|
} else {
|
||||||
stopWidgetUpdates()
|
stopWidgetUpdates()
|
||||||
}
|
}
|
||||||
updateWidget()
|
if (screenOn)
|
||||||
|
updateWidget()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPlaybackStateChanged(playbackState: Int) {
|
override fun onPlaybackStateChanged(playbackState: Int) {
|
||||||
|
|
@ -505,11 +541,11 @@ class MediaService : MediaLibraryService() {
|
||||||
|
|
||||||
private inner class CustomGlideTarget : CustomTarget<Bitmap>() {
|
private inner class CustomGlideTarget : CustomTarget<Bitmap>() {
|
||||||
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
|
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
|
||||||
artCache = Optional.of(Optional.of(resource))
|
artCache = resource
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLoadCleared(placeholder: Drawable?) {
|
override fun onLoadCleared(placeholder: Drawable?) {
|
||||||
artCache = Optional.of(Optional.empty())
|
artCache = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -532,7 +568,7 @@ class MediaService : MediaLibraryService() {
|
||||||
val position = player.currentPosition.takeIf { it != C.TIME_UNSET } ?: 0L
|
val position = player.currentPosition.takeIf { it != C.TIME_UNSET } ?: 0L
|
||||||
val duration = player.duration.takeIf { it != C.TIME_UNSET } ?: 0L
|
val duration = player.duration.takeIf { it != C.TIME_UNSET } ?: 0L
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(coverId) && artCache.isEmpty) {
|
if (!TextUtils.isEmpty(coverId) && nowPlayingChanged) {
|
||||||
CustomGlideRequest.loadAlbumArtBitmap(
|
CustomGlideRequest.loadAlbumArtBitmap(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
coverId,
|
coverId,
|
||||||
|
|
@ -540,21 +576,30 @@ class MediaService : MediaLibraryService() {
|
||||||
CustomGlideTarget())
|
CustomGlideTarget())
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetUpdateManager.updateFromState(
|
val newPlayerState = Triple(player.isPlaying, player.shuffleModeEnabled, player.repeatMode)
|
||||||
this,
|
if (nowPlayingChanged || prevPlayerStates != newPlayerState) {
|
||||||
title ?: "",
|
WidgetUpdateManager.updateFromState(
|
||||||
artist ?: "",
|
this,
|
||||||
album ?: "",
|
title ?: "",
|
||||||
artCache,
|
artist ?: "",
|
||||||
player.isPlaying,
|
album ?: "",
|
||||||
player.shuffleModeEnabled,
|
Optional.ofNullable(artCache),
|
||||||
player.repeatMode,
|
player.isPlaying,
|
||||||
position,
|
player.shuffleModeEnabled,
|
||||||
duration,
|
player.repeatMode,
|
||||||
songLink,
|
position,
|
||||||
albumLink,
|
duration,
|
||||||
artistLink
|
songLink,
|
||||||
)
|
albumLink,
|
||||||
|
artistLink
|
||||||
|
)
|
||||||
|
prevPlayerStates = newPlayerState
|
||||||
|
Log.d("MediaService", "fullUpdate");
|
||||||
|
} else {
|
||||||
|
WidgetUpdateManager.updateProgress(this, position, duration)
|
||||||
|
Log.d("MediaService", "updateProgress");
|
||||||
|
}
|
||||||
|
nowPlayingChanged = false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun scheduleWidgetUpdates() {
|
private fun scheduleWidgetUpdates() {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import android.graphics.Bitmap;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.widget.RemoteViews;
|
||||||
|
|
||||||
import com.bumptech.glide.request.target.CustomTarget;
|
import com.bumptech.glide.request.target.CustomTarget;
|
||||||
import com.bumptech.glide.request.transition.Transition;
|
import com.bumptech.glide.request.transition.Transition;
|
||||||
|
|
@ -36,7 +37,7 @@ public final class WidgetUpdateManager {
|
||||||
String title,
|
String title,
|
||||||
String artist,
|
String artist,
|
||||||
String album,
|
String album,
|
||||||
Bitmap art,
|
Optional<Bitmap> art,
|
||||||
boolean playing,
|
boolean playing,
|
||||||
boolean shuffleEnabled,
|
boolean shuffleEnabled,
|
||||||
int repeatMode,
|
int repeatMode,
|
||||||
|
|
@ -54,13 +55,47 @@ public final class WidgetUpdateManager {
|
||||||
AppWidgetManager mgr = AppWidgetManager.getInstance(ctx);
|
AppWidgetManager mgr = AppWidgetManager.getInstance(ctx);
|
||||||
int[] ids = mgr.getAppWidgetIds(new ComponentName(ctx, WidgetProvider4x1.class));
|
int[] ids = mgr.getAppWidgetIds(new ComponentName(ctx, WidgetProvider4x1.class));
|
||||||
for (int id : ids) {
|
for (int id : ids) {
|
||||||
android.widget.RemoteViews rv = choosePopulate(ctx, title, artist, album, art, playing,
|
android.widget.RemoteViews rv = choosePopulate(ctx, title, artist, album, art.orElse(null), playing,
|
||||||
timing.elapsedText, timing.totalText, timing.progress, shuffleEnabled, repeatMode, id);
|
timing.elapsedText, timing.totalText, timing.progress, shuffleEnabled, repeatMode, id);
|
||||||
WidgetProvider.attachIntents(ctx, rv, id, songLink, albumLink, artistLink);
|
WidgetProvider.attachIntents(ctx, rv, id, songLink, albumLink, artistLink);
|
||||||
mgr.updateAppWidget(id, rv);
|
mgr.updateAppWidget(id, rv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void updateProgress(Context ctx,
|
||||||
|
long positionMs,
|
||||||
|
long durationMs) {
|
||||||
|
final TimingInfo timing = createTimingInfo(positionMs, durationMs);
|
||||||
|
AppWidgetManager mgr = AppWidgetManager.getInstance(ctx);
|
||||||
|
int[] ids = mgr.getAppWidgetIds(new ComponentName(ctx, WidgetProvider4x1.class));
|
||||||
|
for (int id : ids) {
|
||||||
|
LayoutSize size = resolveLayoutSize(ctx, id);
|
||||||
|
int layoutRes = 0;
|
||||||
|
switch (size) {
|
||||||
|
case MEDIUM:
|
||||||
|
layoutRes = R.layout.widget_layout_medium;
|
||||||
|
break;
|
||||||
|
case LARGE:
|
||||||
|
layoutRes = R.layout.widget_layout_large_short;
|
||||||
|
break;
|
||||||
|
case EXPANDED:
|
||||||
|
layoutRes = R.layout.widget_layout_large;
|
||||||
|
break;
|
||||||
|
case COMPACT:
|
||||||
|
default:
|
||||||
|
layoutRes = R.layout.widget_layout_compact;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoteViews rv = new RemoteViews(ctx.getPackageName(), layoutRes);
|
||||||
|
int safeProgress = Math.max(0, Math.min(timing.progress, WidgetViewsFactory.PROGRESS_MAX));
|
||||||
|
rv.setTextViewText(R.id.time_elapsed, timing.elapsedText);
|
||||||
|
rv.setTextViewText(R.id.time_total, timing.totalText);
|
||||||
|
rv.setProgressBar(R.id.progress, WidgetViewsFactory.PROGRESS_MAX, safeProgress, false);
|
||||||
|
mgr.updateAppWidget(id, rv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void pushNow(Context ctx) {
|
public static void pushNow(Context ctx) {
|
||||||
AppWidgetManager mgr = AppWidgetManager.getInstance(ctx);
|
AppWidgetManager mgr = AppWidgetManager.getInstance(ctx);
|
||||||
int[] ids = mgr.getAppWidgetIds(new ComponentName(ctx, WidgetProvider4x1.class));
|
int[] ids = mgr.getAppWidgetIds(new ComponentName(ctx, WidgetProvider4x1.class));
|
||||||
|
|
@ -72,43 +107,6 @@ public final class WidgetUpdateManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void updateFromState(Context ctx,
|
|
||||||
String title,
|
|
||||||
String artist,
|
|
||||||
String album,
|
|
||||||
Optional<Optional<Bitmap>> coverArt,
|
|
||||||
boolean playing,
|
|
||||||
boolean shuffleEnabled,
|
|
||||||
int repeatMode,
|
|
||||||
long positionMs,
|
|
||||||
long durationMs,
|
|
||||||
String songLink,
|
|
||||||
String albumLink,
|
|
||||||
String artistLink) {
|
|
||||||
final Context appCtx = ctx.getApplicationContext();
|
|
||||||
final String t = TextUtils.isEmpty(title) ? appCtx.getString(R.string.widget_not_playing) : title;
|
|
||||||
final String a = TextUtils.isEmpty(artist) ? appCtx.getString(R.string.widget_placeholder_subtitle) : artist;
|
|
||||||
final String alb = !TextUtils.isEmpty(album) ? album : "";
|
|
||||||
final boolean p = playing;
|
|
||||||
final boolean sh = shuffleEnabled;
|
|
||||||
final int rep = repeatMode;
|
|
||||||
final TimingInfo timing = createTimingInfo(positionMs, durationMs);
|
|
||||||
final String songLinkFinal = songLink;
|
|
||||||
final String albumLinkFinal = albumLink;
|
|
||||||
final String artistLinkFinal = artistLink;
|
|
||||||
|
|
||||||
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);
|
|
||||||
WidgetProvider.attachIntents(appCtx, rv, id, songLinkFinal, albumLinkFinal, artistLinkFinal);
|
|
||||||
mgr.updateAppWidget(id, rv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void updateFromState(Context ctx,
|
public static void updateFromState(Context ctx,
|
||||||
String title,
|
String title,
|
||||||
String artist,
|
String artist,
|
||||||
|
|
@ -131,19 +129,19 @@ public final class WidgetUpdateManager {
|
||||||
new CustomTarget<Bitmap>() {
|
new CustomTarget<Bitmap>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
|
public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
|
||||||
updateFromState(ctx, title, artist, album, Optional.of(Optional.of(resource)),
|
updateFromState(ctx, title, artist, album, Optional.of(resource),
|
||||||
playing, shuffleEnabled, repeatMode, positionMs, durationMs, songLink, albumLink, artistLink);
|
playing, shuffleEnabled, repeatMode, positionMs, durationMs, songLink, albumLink, artistLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadCleared(Drawable placeholder) {
|
public void onLoadCleared(Drawable placeholder) {
|
||||||
updateFromState(ctx, title, artist, album, Optional.of(Optional.empty()),
|
updateFromState(ctx, title, artist, album, Optional.empty(),
|
||||||
playing, shuffleEnabled, repeatMode, positionMs, durationMs, songLink, albumLink, artistLink);
|
playing, shuffleEnabled, repeatMode, positionMs, durationMs, songLink, albumLink, artistLink);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
updateFromState(ctx, title, artist, album, Optional.of(Optional.empty()),
|
updateFromState(ctx, title, artist, album, Optional.empty(),
|
||||||
playing, shuffleEnabled, repeatMode, positionMs, durationMs, songLink, albumLink, artistLink);
|
playing, shuffleEnabled, repeatMode, positionMs, durationMs, songLink, albumLink, artistLink);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import com.cappielloantonio.tempo.R;
|
||||||
|
|
||||||
public final class WidgetViewsFactory {
|
public final class WidgetViewsFactory {
|
||||||
|
|
||||||
static final int PROGRESS_MAX = 1000;
|
public static final int PROGRESS_MAX = 1000;
|
||||||
private static final float ALBUM_ART_CORNER_RADIUS_DP = 6f;
|
private static final float ALBUM_ART_CORNER_RADIUS_DP = 6f;
|
||||||
|
|
||||||
private WidgetViewsFactory() {
|
private WidgetViewsFactory() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue