remove empty song placeholder and fix related null errors

This commit is contained in:
dkanada 2021-05-19 02:05:08 +09:00
commit 8f3ee30399
11 changed files with 84 additions and 60 deletions

View file

@ -90,7 +90,7 @@ public abstract class AbsOffsetSongAdapter extends SongAdapter {
@Override
protected Song getSong() {
// return empty song just to be safe
if (getItemViewType() == OFFSET_ITEM) return Song.EMPTY;
if (getItemViewType() == OFFSET_ITEM) return null;
return dataSet.get(getBindingAdapterPosition() - 1);
}

View file

@ -15,6 +15,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.dkanada.gramophone.databinding.FragmentMiniPlayerBinding;
import com.dkanada.gramophone.model.Song;
import com.kabouzeid.appthemehelper.ThemeStore;
import com.kabouzeid.appthemehelper.util.ATHUtil;
import com.dkanada.gramophone.R;
@ -69,7 +70,10 @@ public class MiniPlayerFragment extends AbsMusicServiceFragment implements Music
}
private void updateSongTitle() {
binding.miniPlayerTitle.setText(MusicPlayerRemote.getCurrentSong().title);
Song song = MusicPlayerRemote.getCurrentSong();
if (song != null) {
binding.miniPlayerTitle.setText(song.title);
}
}
@Override

View file

@ -143,6 +143,8 @@ public class CardPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
@Override
public void onServiceConnected() {
if (MusicPlayerRemote.getCurrentSong() == null) return;
updateQueue();
updateCurrentSong();
updateIsFavorite();
@ -150,6 +152,8 @@ public class CardPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
@Override
public void onPlayMetadataChanged() {
if (MusicPlayerRemote.getCurrentSong() == null) return;
updateCurrentSong();
updateIsFavorite();
updateQueuePosition();
@ -329,6 +333,7 @@ public class CardPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
void setUpPanelAndAlbumCoverHeight();
}
@SuppressWarnings("ConstantConditions")
private static abstract class BaseImpl implements Impl {
protected CardPlayerFragment fragment;
protected FragmentCardPlayerBinding binding;
@ -341,7 +346,6 @@ public class CardPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
public AnimatorSet createDefaultColorChangeAnimatorSet(int newColor) {
Animator backgroundAnimator;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// noinspection ConstantConditions
int x = (int) (fragment.playbackControlsFragment.binding.playerPlayPauseFab.getX() + fragment.playbackControlsFragment.binding.playerPlayPauseFab.getWidth() / 2 + fragment.playbackControlsFragment.getView().getX());
int y = (int) (fragment.playbackControlsFragment.binding.playerPlayPauseFab.getY() + fragment.playbackControlsFragment.binding.playerPlayPauseFab.getHeight() / 2 + fragment.playbackControlsFragment.getView().getY() + fragment.playbackControlsFragment.binding.playerProgressSlider.getHeight());
float startRadius = Math.max(fragment.playbackControlsFragment.binding.playerPlayPauseFab.getWidth() / 2, fragment.playbackControlsFragment.binding.playerPlayPauseFab.getHeight() / 2);
@ -378,7 +382,7 @@ public class CardPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
@SuppressWarnings("ConstantConditions")
private static class PortraitImpl extends BaseImpl {
MediaEntryViewHolder currentSongViewHolder;
Song currentSong = Song.EMPTY;
Song currentSong;
public PortraitImpl(CardPlayerFragment fragment, FragmentCardPlayerBinding binding) {
super(fragment, binding);
@ -394,7 +398,6 @@ public class CardPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
currentSongViewHolder.image.setColorFilter(ATHUtil.resolveColor(fragment.getActivity(), R.attr.iconColor, ThemeStore.textColorSecondary(fragment.getActivity())), PorterDuff.Mode.SRC_IN);
currentSongViewHolder.image.setImageResource(R.drawable.ic_volume_up_white_24dp);
currentSongViewHolder.itemView.setOnClickListener(v -> {
// toggle the panel
if (binding.playerSlidingLayout.getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) {
binding.playerSlidingLayout.setPanelState(SlidingUpPanelLayout.PanelState.EXPANDED);
} else if (binding.playerSlidingLayout.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) {

View file

@ -143,6 +143,8 @@ public class FlatPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
@Override
public void onServiceConnected() {
if (MusicPlayerRemote.getCurrentSong() == null) return;
updateQueue();
updateCurrentSong();
updateIsFavorite();
@ -150,6 +152,8 @@ public class FlatPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
@Override
public void onPlayMetadataChanged() {
if (MusicPlayerRemote.getCurrentSong() == null) return;
updateCurrentSong();
updateIsFavorite();
updateQueuePosition();
@ -225,8 +229,8 @@ public class FlatPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
Drawable drawable = ImageUtil.getTintedVectorDrawable(requireActivity(), res, color);
binding.playerToolbar.getMenu().findItem(R.id.action_toggle_favorite)
.setIcon(drawable)
.setTitle(favorite ? getString(R.string.action_remove_from_favorites) : getString(R.string.action_add_to_favorites));
.setIcon(drawable)
.setTitle(favorite ? getString(R.string.action_remove_from_favorites) : getString(R.string.action_add_to_favorites));
}
@Override
@ -366,7 +370,7 @@ public class FlatPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
@SuppressWarnings("ConstantConditions")
private static class PortraitImpl extends BaseImpl {
MediaEntryViewHolder currentSongViewHolder;
Song currentSong = Song.EMPTY;
Song currentSong;
public PortraitImpl(FlatPlayerFragment fragment, FragmentFlatPlayerBinding binding) {
super(fragment, binding);
@ -382,13 +386,13 @@ public class FlatPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
currentSongViewHolder.image.setColorFilter(ATHUtil.resolveColor(fragment.getActivity(), R.attr.iconColor, ThemeStore.textColorSecondary(fragment.getActivity())), PorterDuff.Mode.SRC_IN);
currentSongViewHolder.image.setImageResource(R.drawable.ic_volume_up_white_24dp);
currentSongViewHolder.itemView.setOnClickListener(v -> {
// toggle the panel
if (binding.playerSlidingLayout.getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) {
binding.playerSlidingLayout.setPanelState(SlidingUpPanelLayout.PanelState.EXPANDED);
} else if (binding.playerSlidingLayout.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) {
binding.playerSlidingLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
}
});
currentSongViewHolder.menu.setOnClickListener(new SongMenuHelper.OnClickSongMenu((AppCompatActivity) fragment.getActivity()) {
@Override
public Song getSong() {
@ -417,10 +421,11 @@ public class FlatPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
@Override
public void setUpPanelAndAlbumCoverHeight() {
WidthFitSquareLayout albumCoverContainer = fragment.getView().findViewById(R.id.album_cover_container);
final WidthFitSquareLayout albumCoverContainer = fragment.getView().findViewById(R.id.album_cover_container);
final int availablePanelHeight = binding.playerSlidingLayout.getHeight() - fragment.getView().findViewById(R.id.player_content).getHeight();
final int minPanelHeight = (int) ViewUtil.convertDpToPixel(8 + 72 + 24, fragment.getResources()) + fragment.getResources().getDimensionPixelSize(R.dimen.progress_container_height) + fragment.getResources().getDimensionPixelSize(R.dimen.media_controller_container_height);
if (availablePanelHeight < minPanelHeight) {
albumCoverContainer.getLayoutParams().height = albumCoverContainer.getHeight() - (minPanelHeight - availablePanelHeight);
albumCoverContainer.forceSquare(false);

View file

@ -186,7 +186,7 @@ public class MusicPlayerRemote {
return musicService.getCurrentSong();
}
return Song.EMPTY;
return null;
}
public static int getPosition() {

View file

@ -16,8 +16,6 @@ import java.util.UUID;
@Entity(tableName = "songs")
public class Song implements Parcelable {
public static final Song EMPTY = new Song();
@NonNull
@PrimaryKey
public String id;

View file

@ -177,13 +177,13 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
switch (command) {
case AppWidgetClassic.NAME:
appWidgetClassic.performUpdate(MusicService.this, ids);
appWidgetClassic.notifyChange(MusicService.this, META_CHANGED, ids);
break;
case AppWidgetAlbum.NAME:
appWidgetAlbum.performUpdate(MusicService.this, ids);
appWidgetAlbum.notifyChange(MusicService.this, META_CHANGED, ids);
break;
case AppWidgetCard.NAME:
appWidgetCard.performUpdate(MusicService.this, ids);
appWidgetCard.notifyChange(MusicService.this, META_CHANGED, ids);
break;
}
}
@ -515,8 +515,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
private void openCurrent() {
synchronized (this) {
// current song title will be null when queue is cleared
if (getCurrentSong().title == null) return;
if (getCurrentSong() == null) return;
playback.setDataSource(getCurrentSong());
}
@ -529,6 +528,8 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
private void prepareNextImpl() {
synchronized (this) {
if (getCurrentSong() == null) return;
nextPosition = getNextPosition(false);
playback.queueDataSource(getSongAt(nextPosition));
}
@ -549,37 +550,37 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
}
public void updateNotification() {
if (playingNotification != null && getCurrentSong().title != null) {
if (playingNotification != null && getCurrentSong() != null) {
playingNotification.update();
}
}
private void updateMediaSessionState() {
mediaSession.setPlaybackState(
new PlaybackStateCompat.Builder()
.setActions(MEDIA_SESSION_ACTIONS)
.setState(isPlaying() ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED, getSongProgressMillis(), 1)
.build());
new PlaybackStateCompat.Builder()
.setActions(MEDIA_SESSION_ACTIONS)
.setState(isPlaying() ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED, getSongProgressMillis(), 1)
.build());
}
@SuppressLint("CheckResult")
private void updateMediaSessionMetadata() {
final Song song = getCurrentSong();
if (song.title == null) {
if (song == null) {
mediaSession.setMetadata(null);
return;
}
final MediaMetadataCompat.Builder metaData = new MediaMetadataCompat.Builder()
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, song.artistName)
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ARTIST, song.artistName)
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, song.albumName)
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, song.title)
.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, song.duration)
.putLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER, getPosition() + 1)
.putLong(MediaMetadataCompat.METADATA_KEY_YEAR, song.year)
.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, null);
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, song.artistName)
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ARTIST, song.artistName)
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, song.albumName)
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, song.title)
.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, song.duration)
.putLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER, getPosition() + 1)
.putLong(MediaMetadataCompat.METADATA_KEY_YEAR, song.year)
.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, null);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
metaData.putLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS, getPlayingQueue().size());
@ -588,8 +589,8 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
if (PreferenceUtil.getInstance(this).getShowAlbumCover()) {
final Point screenSize = Util.getScreenSize(MusicService.this);
final RequestBuilder<Bitmap> request = CustomGlideRequest.Builder
.from(MusicService.this, song.primary, song.blurHash)
.bitmap().build();
.from(MusicService.this, song.primary, song.blurHash)
.bitmap().build();
if (PreferenceUtil.getInstance(this).getBlurAlbumCover()) {
request.transform(new BlurTransformation.Builder(MusicService.this).build());
@ -638,9 +639,9 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
public Song getSongAt(int position) {
if (position >= 0 && position < getPlayingQueue().size()) {
return getPlayingQueue().get(position);
} else {
return Song.EMPTY;
}
return null;
}
public int getNextPosition(boolean force) {
@ -978,9 +979,9 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
private void sendChangeInternal(final String what) {
sendBroadcast(new Intent(what));
appWidgetAlbum.notifyChange(this, what);
appWidgetClassic.notifyChange(this, what);
appWidgetCard.notifyChange(this, what);
appWidgetAlbum.notifyChange(this, what, null);
appWidgetClassic.notifyChange(this, what, null);
appWidgetCard.notifyChange(this, what, null);
}
private void handleChangeInternal(@NonNull final String what) {
@ -1245,6 +1246,9 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
@Override
public void handleMessage(@NonNull final Message msg) {
Song song = mService.get().getCurrentSong();
if (song == null) return;
switch (msg.what) {
case TRACK_STARTED:
onStart();
@ -1277,19 +1281,22 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
public void onProgress() {
PlaybackProgressInfo progressInfo = new PlaybackProgressInfo();
Song current = mService.get().getCurrentSong();
String user = App.getApiClient().getCurrentUserId();
Date time = new Date(System.currentTimeMillis());
if (current == null) {
return;
}
// TODO these cause a wrong thread error
long progress = mService.get().getSongProgressMillis();
double duration = mService.get().getSongDurationMillis();
if (progress / duration > 0.9) {
Song current = mService.get().getCurrentSong();
String user = App.getApiClient().getCurrentUserId();
Date time = new Date(System.currentTimeMillis());
App.getApiClient().MarkPlayedAsync(current.id, user, time, new Response<>());
}
progressInfo.setItemId(mService.get().getCurrentSong().id);
progressInfo.setItemId(current.id);
progressInfo.setPositionTicks(progress * 10000);
progressInfo.setVolumeLevel(mService.get().playback.getVolume());
progressInfo.setIsPaused(!mService.get().playback.isPlaying());

View file

@ -53,6 +53,7 @@ public class AppWidgetAlbum extends BaseAppWidget {
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
@Override
protected void defaultAppWidget(final Context context, final int[] appWidgetIds) {
final RemoteViews appWidgetView = new RemoteViews(context.getPackageName(), R.layout.app_widget_album);
@ -66,6 +67,7 @@ public class AppWidgetAlbum extends BaseAppWidget {
pushUpdate(context, appWidgetIds, appWidgetView);
}
@Override
public void performUpdate(final MusicService service, final int[] appWidgetIds) {
final RemoteViews appWidgetView = new RemoteViews(service.getPackageName(), R.layout.app_widget_album);

View file

@ -51,6 +51,7 @@ public class AppWidgetCard extends BaseAppWidget {
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
@Override
protected void defaultAppWidget(final Context context, final int[] appWidgetIds) {
final RemoteViews appWidgetView = new RemoteViews(context.getPackageName(), R.layout.app_widget_card);
@ -64,6 +65,7 @@ public class AppWidgetCard extends BaseAppWidget {
pushUpdate(context, appWidgetIds, appWidgetView);
}
@Override
public void performUpdate(final MusicService service, final int[] appWidgetIds) {
final RemoteViews appWidgetView = new RemoteViews(service.getPackageName(), R.layout.app_widget_card);

View file

@ -51,6 +51,7 @@ public class AppWidgetClassic extends BaseAppWidget {
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
@Override
protected void defaultAppWidget(final Context context, final int[] appWidgetIds) {
final RemoteViews appWidgetView = new RemoteViews(context.getPackageName(), R.layout.app_widget_classic);
@ -64,6 +65,7 @@ public class AppWidgetClassic extends BaseAppWidget {
pushUpdate(context, appWidgetIds, appWidgetView);
}
@Override
public void performUpdate(final MusicService service, final int[] appWidgetIds) {
final RemoteViews appWidgetView = new RemoteViews(service.getPackageName(), R.layout.app_widget_classic);

View file

@ -48,16 +48,24 @@ public abstract class BaseAppWidget extends AppWidgetProvider {
context.sendBroadcast(updateIntent);
}
public void notifyChange(final MusicService service, final String what) {
if (hasInstances(service)) {
if (MusicService.META_CHANGED.equals(what) || MusicService.STATE_CHANGED.equals(what)) {
performUpdate(service, null);
}
public void notifyChange(final MusicService service, final String what, int[] appWidgetIds) {
final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(service);
final ComponentName componentName = new ComponentName(service, getClass());
// will only find widgets for the current class to avoid updating other styles
if (appWidgetIds == null) {
appWidgetIds = appWidgetManager.getAppWidgetIds(componentName);
}
Song song = service.getCurrentSong();
if (song != null && (what.equals(MusicService.STATE_CHANGED) || what.equals(MusicService.META_CHANGED))) {
performUpdate(service, appWidgetIds);
}
}
protected void pushUpdate(final Context context, final int[] appWidgetIds, final RemoteViews views) {
final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
if (appWidgetIds != null) {
appWidgetManager.updateAppWidget(appWidgetIds, views);
} else {
@ -65,13 +73,6 @@ public abstract class BaseAppWidget extends AppWidgetProvider {
}
}
protected boolean hasInstances(final Context context) {
final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
final int[] mAppWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, getClass()));
return mAppWidgetIds.length > 0;
}
protected PendingIntent buildPendingIntent(Context context, final String action, final ComponentName serviceName) {
Intent intent = new Intent(action);
@ -83,7 +84,7 @@ public abstract class BaseAppWidget extends AppWidgetProvider {
}
}
protected static Bitmap createRoundedBitmap(Bitmap bitmap, int width, int height, float tl, float tr, float bl, float br) {
protected Bitmap createRoundedBitmap(Bitmap bitmap, int width, int height, float tl, float tr, float bl, float br) {
Bitmap rounded = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(rounded);
Paint paint = new Paint();
@ -96,7 +97,7 @@ public abstract class BaseAppWidget extends AppWidgetProvider {
return rounded;
}
protected static Bitmap createRoundedBitmap(Drawable drawable, int width, int height, float tl, float tr, float bl, float br) {
protected Bitmap createRoundedBitmap(Drawable drawable, int width, int height, float tl, float tr, float bl, float br) {
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
@ -106,7 +107,7 @@ public abstract class BaseAppWidget extends AppWidgetProvider {
return createRoundedBitmap(bitmap, width, height, tl, tr, bl, br);
}
protected static Path composeRoundedRectPath(RectF rect, float tl, float tr, float bl, float br) {
protected Path composeRoundedRectPath(RectF rect, float tl, float tr, float bl, float br) {
Path path = new Path();
tl = tl < 0 ? 0 : tl;
tr = tr < 0 ? 0 : tr;
@ -129,7 +130,7 @@ public abstract class BaseAppWidget extends AppWidgetProvider {
abstract protected void defaultAppWidget(final Context context, final int[] appWidgetIds);
abstract public void performUpdate(final MusicService service, final int[] appWidgetIds);
abstract protected void performUpdate(final MusicService service, final int[] appWidgetIds);
protected Drawable getAlbumArtDrawable(final Resources resources, final Bitmap bitmap) {
if (bitmap == null) {