Removed butter knife

This commit is contained in:
h4h13 2018-12-06 14:22:57 +05:30
parent d5f63b91ac
commit 63e3276098
194 changed files with 5984 additions and 7491 deletions

View file

@ -653,7 +653,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
if (PreferenceUtil.getInstance().albumArtOnLockscreen()) {
final Point screenSize = RetroUtil.getScreenSize(MusicService.this);
final BitmapRequestBuilder<?, Bitmap> request = SongGlideRequest.Builder.from(Glide.with(MusicService.this), song)
final BitmapRequestBuilder<?, Bitmap> request = SongGlideRequest.Builder.Companion.from(Glide.with(MusicService.this), song)
.checkIgnoreMediaStore(MusicService.this)
.asBitmap().build();
if (PreferenceUtil.getInstance().blurredAlbumArt()) {

View file

@ -1,161 +0,0 @@
package code.name.monkey.retromusic.service.daydream
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.service.dreams.DreamService
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.transition.TransitionManager
import butterknife.BindView
import butterknife.ButterKnife
import butterknife.Unbinder
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.loaders.SongLoader
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder
import com.bumptech.glide.Glide
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import java.util.*
/**
* Created by hemanths on 25/09/17.
*/
class RetroMusicAlbums : DreamService() {
@BindView(R.id.recycler_view)
internal var mRecyclerView: RecyclerView? = null
@BindView(R.id.title)
internal var mTitle: TextView? = null
@BindView(R.id.text)
internal var mText: TextView? = null
@BindView(R.id.title_container)
internal var mViewGroup: ViewGroup? = null
private val mBroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
if (intent == null) {
return
}
val artist = intent.getStringExtra("artist")
val track = intent.getStringExtra("track")
if (mViewGroup != null) {
mViewGroup!!.visibility = View.VISIBLE
TransitionManager.beginDelayedTransition(mViewGroup!!)
if (mTitle != null) {
mTitle!!.text = track
}
if (mText != null) {
mText!!.text = artist
}
}
}
}
private var unbinder: Unbinder? = null
private var mDisposable: CompositeDisposable? = null
private val playingQueue: Observable<ArrayList<Song>>
get() = Observable.just(MusicPlayerRemote.playingQueue)
override fun onAttachedToWindow() {
super.onAttachedToWindow()
val view = LayoutInflater.from(this).inflate(R.layout.dream_service, null)
setContentView(view)
unbinder = ButterKnife.bind(this, view)
mRecyclerView!!.itemAnimator = DefaultItemAnimator()
val layoutManager = GridLayoutManager(this, 4, RecyclerView.VERTICAL, false)
mRecyclerView!!.layoutManager = layoutManager
mDisposable!!.add(playingQueue
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.flatMap {
return@flatMap Observable.create<ArrayList<Song>> { e ->
if (it.isEmpty()) {
e.onNext(SongLoader.getAllSongs(this@RetroMusicAlbums).blockingFirst())
} else {
e.onNext(it)
}
e.onComplete()
}
}
.subscribe { songs ->
if (songs.size > 0) {
val imagesAdapter = ImagesAdapter(songs)
mRecyclerView!!.adapter = imagesAdapter
}
})
}
override fun onCreate() {
super.onCreate()
isInteractive = true
isFullscreen = true
mDisposable = CompositeDisposable()
val iF = IntentFilter()
iF.addAction("com.android.music.musicservicecommand")
iF.addAction("com.android.music.metachanged")
registerReceiver(mBroadcastReceiver, iF)
}
override fun onDestroy() {
super.onDestroy()
unbinder!!.unbind()
mDisposable!!.clear()
unregisterReceiver(mBroadcastReceiver)
}
internal inner class ImagesAdapter(private val list: ArrayList<Song>) : RecyclerView.Adapter<ImagesAdapter.ViewHolder>() {
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): ViewHolder {
return ViewHolder(LayoutInflater.from(applicationContext)
.inflate(R.layout.image, viewGroup, false))
}
override fun onBindViewHolder(holder: ViewHolder, i: Int) {
val song = list[i]
SongGlideRequest.Builder.from(Glide.with(applicationContext), song)
.checkIgnoreMediaStore(applicationContext)
.generatePalette(applicationContext).build()
.override(400, 400)
.into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onColorReady(color: Int) {
}
})
}
override fun getItemCount(): Int {
return list.size
}
internal inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
override fun onClick(v: View?) {
super.onClick(v)
MusicPlayerRemote.openQueue(list, adapterPosition, true)
}
}
}
}

View file

@ -1,82 +0,0 @@
package code.name.monkey.retromusic.service.notification;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.os.Build;
import androidx.annotation.RequiresApi;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.service.MusicService;
import static android.content.Context.NOTIFICATION_SERVICE;
public abstract class PlayingNotification {
protected static final float NOTIFICATION_CONTROLS_SIZE_MULTIPLIER = 1.0f;
static final String NOTIFICATION_CHANNEL_ID = "playing_notification";
private static final int NOTIFICATION_ID = 1;
private static final int NOTIFY_MODE_FOREGROUND = 1;
private static final int NOTIFY_MODE_BACKGROUND = 0;
protected MusicService service;
boolean stopped;
private int notifyMode = NOTIFY_MODE_BACKGROUND;
private NotificationManager notificationManager;
public synchronized void init(MusicService service) {
this.service = service;
notificationManager = (NotificationManager) service.getSystemService(NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel();
}
}
public abstract void update();
public synchronized void stop() {
stopped = true;
service.stopForeground(true);
notificationManager.cancel(NOTIFICATION_ID);
}
void updateNotifyModeAndPostNotification(Notification notification) {
int newNotifyMode;
if (service.isPlaying()) {
newNotifyMode = NOTIFY_MODE_FOREGROUND;
} else {
newNotifyMode = NOTIFY_MODE_BACKGROUND;
}
if (notifyMode != newNotifyMode && newNotifyMode == NOTIFY_MODE_BACKGROUND) {
service.stopForeground(false);
}
if (newNotifyMode == NOTIFY_MODE_FOREGROUND) {
service.startForeground(NOTIFICATION_ID, notification);
} else if (newNotifyMode == NOTIFY_MODE_BACKGROUND) {
notificationManager.notify(NOTIFICATION_ID, notification);
}
notifyMode = newNotifyMode;
}
@RequiresApi(26)
private void createNotificationChannel() {
NotificationChannel notificationChannel = notificationManager
.getNotificationChannel(NOTIFICATION_CHANNEL_ID);
if (notificationChannel == null) {
notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
service.getString(R.string.playing_notification_name),
NotificationManager.IMPORTANCE_LOW);
notificationChannel
.setDescription(service.getString(R.string.playing_notification_description));
notificationChannel.enableLights(false);
notificationChannel.enableVibration(false);
notificationChannel.setShowBadge(false);
notificationManager.createNotificationChannel(notificationChannel);
}
}
}

View file

@ -0,0 +1,83 @@
package code.name.monkey.retromusic.service.notification
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context.NOTIFICATION_SERVICE
import android.os.Build
import androidx.annotation.RequiresApi
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.service.MusicService
abstract class PlayingNotification {
protected lateinit var service: MusicService
protected var stopped: Boolean = false
private var notifyMode = NOTIFY_MODE_BACKGROUND
private var notificationManager: NotificationManager? = null
@Synchronized
fun init(service: MusicService) {
this.service = service
notificationManager = service.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel()
}
}
abstract fun update()
@Synchronized
fun stop() {
stopped = true
service.stopForeground(true)
notificationManager!!.cancel(NOTIFICATION_ID)
}
internal fun updateNotifyModeAndPostNotification(notification: Notification) {
val newNotifyMode: Int = if (service.isPlaying) {
NOTIFY_MODE_FOREGROUND
} else {
NOTIFY_MODE_BACKGROUND
}
if (notifyMode != newNotifyMode && newNotifyMode == NOTIFY_MODE_BACKGROUND) {
service.stopForeground(false)
}
if (newNotifyMode == NOTIFY_MODE_FOREGROUND) {
service.startForeground(NOTIFICATION_ID, notification)
} else if (newNotifyMode == NOTIFY_MODE_BACKGROUND) {
notificationManager!!.notify(NOTIFICATION_ID, notification)
}
notifyMode = newNotifyMode
}
@RequiresApi(26)
private fun createNotificationChannel() {
var notificationChannel: NotificationChannel? = notificationManager!!
.getNotificationChannel(NOTIFICATION_CHANNEL_ID)
if (notificationChannel == null) {
notificationChannel = NotificationChannel(NOTIFICATION_CHANNEL_ID,
service.getString(R.string.playing_notification_name),
NotificationManager.IMPORTANCE_LOW)
notificationChannel.description = service.getString(R.string.playing_notification_description)
notificationChannel.enableLights(false)
notificationChannel.enableVibration(false)
notificationChannel.setShowBadge(false)
notificationManager!!.createNotificationChannel(notificationChannel)
}
}
companion object {
const val NOTIFICATION_CONTROLS_SIZE_MULTIPLIER = 1.0f
internal const val NOTIFICATION_CHANNEL_ID = "playing_notification"
private const val NOTIFICATION_ID = 1
private const val NOTIFY_MODE_FOREGROUND = 1
private const val NOTIFY_MODE_BACKGROUND = 0
}
}

View file

@ -1,225 +0,0 @@
package code.name.monkey.retromusic.service.notification;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.view.View;
import android.widget.RemoteViews;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.target.Target;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import code.name.monkey.appthemehelper.util.ColorUtil;
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.glide.SongGlideRequest;
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.service.MusicService;
import code.name.monkey.retromusic.ui.activities.MainActivity;
import code.name.monkey.retromusic.util.PreferenceUtil;
import code.name.monkey.retromusic.util.RetroColorUtil;
import code.name.monkey.retromusic.util.RetroUtil;
import static code.name.monkey.retromusic.Constants.ACTION_QUIT;
import static code.name.monkey.retromusic.Constants.ACTION_REWIND;
import static code.name.monkey.retromusic.Constants.ACTION_SKIP;
import static code.name.monkey.retromusic.Constants.ACTION_TOGGLE_PAUSE;
import static code.name.monkey.retromusic.util.RetroUtil.createBitmap;
public class PlayingNotificationImpl extends PlayingNotification {
private Target<BitmapPaletteWrapper> target;
@Override
public synchronized void update() {
stopped = false;
final Song song = service.getCurrentSong();
final boolean isPlaying = service.isPlaying();
final RemoteViews notificationLayout = new RemoteViews(service.getPackageName(),
R.layout.notification);
final RemoteViews notificationLayoutBig = new RemoteViews(service.getPackageName(),
R.layout.notification_big);
if (TextUtils.isEmpty(song.getTitle()) && TextUtils.isEmpty(song.getArtistName())) {
notificationLayout.setViewVisibility(R.id.media_titles, View.INVISIBLE);
} else {
notificationLayout.setViewVisibility(R.id.media_titles, View.VISIBLE);
notificationLayout.setTextViewText(R.id.title, song.getTitle());
notificationLayout.setTextViewText(R.id.text, song.getArtistName());
}
if (TextUtils.isEmpty(song.getTitle()) && TextUtils.isEmpty(song.getArtistName()) && TextUtils
.isEmpty(song.getAlbumName())) {
notificationLayoutBig.setViewVisibility(R.id.media_titles, View.INVISIBLE);
} else {
notificationLayoutBig.setViewVisibility(R.id.media_titles, View.VISIBLE);
notificationLayoutBig.setTextViewText(R.id.title, song.getTitle());
notificationLayoutBig.setTextViewText(R.id.text, song.getArtistName());
notificationLayoutBig.setTextViewText(R.id.text2, song.getAlbumName());
}
linkButtons(notificationLayout, notificationLayoutBig);
Intent action = new Intent(service, MainActivity.class);
action.putExtra("expand", true);
action.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
final PendingIntent clickIntent = PendingIntent
.getActivity(service, 0, action, PendingIntent.FLAG_UPDATE_CURRENT);
final PendingIntent deleteIntent = buildPendingIntent(service, ACTION_QUIT, null);
final Notification notification = new NotificationCompat.Builder(service,
NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setContentIntent(clickIntent)
.setDeleteIntent(deleteIntent)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setContent(notificationLayout)
.setCustomBigContentView(notificationLayoutBig)
.setOngoing(isPlaying)
.build();
final int bigNotificationImageSize = service.getResources()
.getDimensionPixelSize(R.dimen.notification_big_image_size);
service.runOnUiThread(new Runnable() {
@Override
public void run() {
if (target != null) {
Glide.clear(target);
}
target = SongGlideRequest.Builder.from(Glide.with(service), song)
.checkIgnoreMediaStore(service)
.generatePalette(service).build()
.into(new SimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize,
bigNotificationImageSize) {
@Override
public void onResourceReady(BitmapPaletteWrapper resource,
GlideAnimation<? super BitmapPaletteWrapper> glideAnimation) {
update(resource.getBitmap(),
PreferenceUtil.getInstance().isDominantColor() ?
RetroColorUtil.getDominantColor(resource.getBitmap(), Color.TRANSPARENT) :
RetroColorUtil.getColor(resource.getPalette(), Color.TRANSPARENT));
}
@Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
super.onLoadFailed(e, errorDrawable);
update(null, Color.WHITE);
}
private void update(@Nullable Bitmap bitmap, int bgColor) {
if (bitmap != null) {
notificationLayout.setImageViewBitmap(R.id.image, bitmap);
notificationLayoutBig.setImageViewBitmap(R.id.image, bitmap);
} else {
notificationLayout.setImageViewResource(R.id.image, R.drawable.default_album_art);
notificationLayoutBig
.setImageViewResource(R.id.image, R.drawable.default_album_art);
}
if (!PreferenceUtil.getInstance().coloredNotification()) {
bgColor = Color.WHITE;
}
setBackgroundColor(bgColor);
setNotificationContent(ColorUtil.isColorLight(bgColor));
if (stopped) {
return; // notification has been stopped before loading was finished
}
updateNotifyModeAndPostNotification(notification);
}
private void setBackgroundColor(int color) {
notificationLayout.setInt(R.id.root, "setBackgroundColor", color);
notificationLayoutBig.setInt(R.id.root, "setBackgroundColor", color);
}
private void setNotificationContent(boolean dark) {
int primary = MaterialValueHelper.getPrimaryTextColor(service, dark);
int secondary = MaterialValueHelper.getSecondaryTextColor(service, dark);
Bitmap close = createBitmap(
RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_close_white_24dp, primary),
1.5f);
Bitmap prev = createBitmap(
RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp,
primary), 1.5f);
Bitmap next = createBitmap(
RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp,
primary), 1.5f);
Bitmap playPause = createBitmap(RetroUtil.getTintedVectorDrawable(service,
isPlaying ? R.drawable.ic_pause_white_24dp
: R.drawable.ic_play_arrow_white_24dp, primary), 1.5f);
notificationLayout.setTextColor(R.id.title, primary);
notificationLayout.setTextColor(R.id.text, secondary);
notificationLayout.setImageViewBitmap(R.id.action_prev, prev);
notificationLayout.setImageViewBitmap(R.id.action_next, next);
notificationLayout.setImageViewBitmap(R.id.action_play_pause, playPause);
notificationLayoutBig.setTextColor(R.id.title, primary);
notificationLayoutBig.setTextColor(R.id.text, secondary);
notificationLayoutBig.setTextColor(R.id.text2, secondary);
notificationLayoutBig.setImageViewBitmap(R.id.action_quit, close);
notificationLayoutBig.setImageViewBitmap(R.id.action_prev, prev);
notificationLayoutBig.setImageViewBitmap(R.id.action_next, next);
notificationLayoutBig.setImageViewBitmap(R.id.action_play_pause, playPause);
}
});
}
});
}
private void linkButtons(final RemoteViews notificationLayout,
final RemoteViews notificationLayoutBig) {
PendingIntent pendingIntent;
final ComponentName serviceName = new ComponentName(service, MusicService.class);
// Previous track
pendingIntent = buildPendingIntent(service, ACTION_REWIND, serviceName);
notificationLayout.setOnClickPendingIntent(R.id.action_prev, pendingIntent);
notificationLayoutBig.setOnClickPendingIntent(R.id.action_prev, pendingIntent);
// Play and pause
pendingIntent = buildPendingIntent(service, ACTION_TOGGLE_PAUSE, serviceName);
notificationLayout.setOnClickPendingIntent(R.id.action_play_pause, pendingIntent);
notificationLayoutBig.setOnClickPendingIntent(R.id.action_play_pause, pendingIntent);
// Next track
pendingIntent = buildPendingIntent(service, ACTION_SKIP, serviceName);
notificationLayout.setOnClickPendingIntent(R.id.action_next, pendingIntent);
notificationLayoutBig.setOnClickPendingIntent(R.id.action_next, pendingIntent);
// Close
pendingIntent = buildPendingIntent(service, ACTION_QUIT, serviceName);
notificationLayoutBig.setOnClickPendingIntent(R.id.action_quit, pendingIntent);
}
private PendingIntent buildPendingIntent(Context context, final String action,
final ComponentName serviceName) {
Intent intent = new Intent(action);
intent.setComponent(serviceName);
return PendingIntent.getService(context, 0, intent, 0);
}
}

View file

@ -0,0 +1,219 @@
package code.name.monkey.retromusic.service.notification
import android.app.PendingIntent
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.text.TextUtils
import android.view.View
import android.widget.RemoteViews
import androidx.core.app.NotificationCompat
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.Constants.ACTION_QUIT
import code.name.monkey.retromusic.Constants.ACTION_REWIND
import code.name.monkey.retromusic.Constants.ACTION_SKIP
import code.name.monkey.retromusic.Constants.ACTION_TOGGLE_PAUSE
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.ui.activities.MainActivity
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroColorUtil
import code.name.monkey.retromusic.util.RetroUtil
import code.name.monkey.retromusic.util.RetroUtil.createBitmap
import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target
class PlayingNotificationImpl : PlayingNotification() {
private var target: Target<BitmapPaletteWrapper>? = null
@Synchronized
override fun update() {
stopped = false
val song = service.currentSong
val isPlaying = service.isPlaying
val notificationLayout = RemoteViews(service.packageName,
R.layout.notification)
val notificationLayoutBig = RemoteViews(service.packageName,
R.layout.notification_big)
if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) {
notificationLayout.setViewVisibility(R.id.media_titles, View.INVISIBLE)
} else {
notificationLayout.setViewVisibility(R.id.media_titles, View.VISIBLE)
notificationLayout.setTextViewText(R.id.title, song.title)
notificationLayout.setTextViewText(R.id.text, song.artistName)
}
if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName) && TextUtils
.isEmpty(song.albumName)) {
notificationLayoutBig.setViewVisibility(R.id.media_titles, View.INVISIBLE)
} else {
notificationLayoutBig.setViewVisibility(R.id.media_titles, View.VISIBLE)
notificationLayoutBig.setTextViewText(R.id.title, song.title)
notificationLayoutBig.setTextViewText(R.id.text, song.artistName)
notificationLayoutBig.setTextViewText(R.id.text2, song.albumName)
}
linkButtons(notificationLayout, notificationLayoutBig)
val action = Intent(service, MainActivity::class.java)
action.putExtra("expand", true)
action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
val clickIntent = PendingIntent
.getActivity(service, 0, action, PendingIntent.FLAG_UPDATE_CURRENT)
val deleteIntent = buildPendingIntent(service, ACTION_QUIT, null)
val notification = NotificationCompat.Builder(service,
PlayingNotification.NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setContentIntent(clickIntent)
.setDeleteIntent(deleteIntent)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setContent(notificationLayout)
.setCustomBigContentView(notificationLayoutBig)
.setOngoing(isPlaying)
.build()
val bigNotificationImageSize = service.resources
.getDimensionPixelSize(R.dimen.notification_big_image_size)
service.runOnUiThread {
if (target != null) {
Glide.clear(target!!)
}
target = SongGlideRequest.Builder.from(Glide.with(service), song)
.checkIgnoreMediaStore(service)
.generatePalette(service).build()
.into(object : SimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize,
bigNotificationImageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper,
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
update(resource.bitmap,
if (PreferenceUtil.getInstance().isDominantColor)
RetroColorUtil.getDominantColor(resource.bitmap, Color.TRANSPARENT)
else
RetroColorUtil.getColor(resource.palette, Color.TRANSPARENT))
}
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
update(null, Color.WHITE)
}
private fun update(bitmap: Bitmap?, bgColor: Int) {
var bgColorFinal = bgColor
if (bitmap != null) {
notificationLayout.setImageViewBitmap(R.id.image, bitmap)
notificationLayoutBig.setImageViewBitmap(R.id.image, bitmap)
} else {
notificationLayout.setImageViewResource(R.id.image, R.drawable.default_album_art)
notificationLayoutBig
.setImageViewResource(R.id.image, R.drawable.default_album_art)
}
if (!PreferenceUtil.getInstance().coloredNotification()) {
bgColorFinal = Color.WHITE
}
setBackgroundColor(bgColorFinal)
setNotificationContent(ColorUtil.isColorLight(bgColorFinal))
if (stopped) {
return // notification has been stopped before loading was finished
}
updateNotifyModeAndPostNotification(notification)
}
private fun setBackgroundColor(color: Int) {
notificationLayout.setInt(R.id.root, "setBackgroundColor", color)
notificationLayoutBig.setInt(R.id.root, "setBackgroundColor", color)
}
private fun setNotificationContent(dark: Boolean) {
val primary = MaterialValueHelper.getPrimaryTextColor(service, dark)
val secondary = MaterialValueHelper.getSecondaryTextColor(service, dark)
val close = createBitmap(
RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_close_white_24dp, primary)!!,
1.5f)
val prev = createBitmap(
RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp,
primary)!!, 1.5f)
val next = createBitmap(
RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp,
primary)!!, 1.5f)
val playPause = createBitmap(RetroUtil.getTintedVectorDrawable(service,
if (isPlaying)
R.drawable.ic_pause_white_24dp
else
R.drawable.ic_play_arrow_white_24dp, primary)!!, 1.5f)
notificationLayout.setTextColor(R.id.title, primary)
notificationLayout.setTextColor(R.id.text, secondary)
notificationLayout.setImageViewBitmap(R.id.action_prev, prev)
notificationLayout.setImageViewBitmap(R.id.action_next, next)
notificationLayout.setImageViewBitmap(R.id.action_play_pause, playPause)
notificationLayoutBig.setTextColor(R.id.title, primary)
notificationLayoutBig.setTextColor(R.id.text, secondary)
notificationLayoutBig.setTextColor(R.id.text2, secondary)
notificationLayoutBig.setImageViewBitmap(R.id.action_quit, close)
notificationLayoutBig.setImageViewBitmap(R.id.action_prev, prev)
notificationLayoutBig.setImageViewBitmap(R.id.action_next, next)
notificationLayoutBig.setImageViewBitmap(R.id.action_play_pause, playPause)
}
})
}
}
private fun linkButtons(notificationLayout: RemoteViews,
notificationLayoutBig: RemoteViews) {
var pendingIntent: PendingIntent
val serviceName = ComponentName(service, MusicService::class.java)
// Previous track
pendingIntent = buildPendingIntent(service, ACTION_REWIND, serviceName)
notificationLayout.setOnClickPendingIntent(R.id.action_prev, pendingIntent)
notificationLayoutBig.setOnClickPendingIntent(R.id.action_prev, pendingIntent)
// Play and pause
pendingIntent = buildPendingIntent(service, ACTION_TOGGLE_PAUSE, serviceName)
notificationLayout.setOnClickPendingIntent(R.id.action_play_pause, pendingIntent)
notificationLayoutBig.setOnClickPendingIntent(R.id.action_play_pause, pendingIntent)
// Next track
pendingIntent = buildPendingIntent(service, ACTION_SKIP, serviceName)
notificationLayout.setOnClickPendingIntent(R.id.action_next, pendingIntent)
notificationLayoutBig.setOnClickPendingIntent(R.id.action_next, pendingIntent)
// Close
pendingIntent = buildPendingIntent(service, ACTION_QUIT, serviceName)
notificationLayoutBig.setOnClickPendingIntent(R.id.action_quit, pendingIntent)
}
private fun buildPendingIntent(context: Context, action: String,
serviceName: ComponentName?): PendingIntent {
val intent = Intent(action)
intent.component = serviceName
return PendingIntent.getService(context, 0, intent, 0)
}
}

View file

@ -1,143 +0,0 @@
package code.name.monkey.retromusic.service.notification;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Html;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
import androidx.core.app.NotificationCompat;
import androidx.media.app.NotificationCompat.MediaStyle;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.glide.SongGlideRequest;
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.service.MusicService;
import code.name.monkey.retromusic.ui.activities.MainActivity;
import code.name.monkey.retromusic.util.PreferenceUtil;
import code.name.monkey.retromusic.util.RetroColorUtil;
import static code.name.monkey.retromusic.Constants.ACTION_QUIT;
import static code.name.monkey.retromusic.Constants.ACTION_REWIND;
import static code.name.monkey.retromusic.Constants.ACTION_SKIP;
import static code.name.monkey.retromusic.Constants.ACTION_TOGGLE_PAUSE;
public class PlayingNotificationImpl24 extends PlayingNotification {
@Override
public synchronized void update() {
stopped = false;
final Song song = service.getCurrentSong();
final boolean isPlaying = service.isPlaying();
final int playButtonResId = isPlaying ? R.drawable.ic_pause_white_24dp :
R.drawable.ic_play_arrow_white_24dp;
Intent action = new Intent(service, MainActivity.class);
action.putExtra("expand", true);
action.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
final PendingIntent clickIntent = PendingIntent
.getActivity(service, 0, action, PendingIntent.FLAG_UPDATE_CURRENT);
final ComponentName serviceName = new ComponentName(service, MusicService.class);
Intent intent = new Intent(ACTION_QUIT);
intent.setComponent(serviceName);
final PendingIntent deleteIntent = PendingIntent.getService(service, 0, intent, 0);
final int bigNotificationImageSize = service.getResources()
.getDimensionPixelSize(R.dimen.notification_big_image_size);
service.runOnUiThread(() -> SongGlideRequest.Builder.from(Glide.with(service), song)
.checkIgnoreMediaStore(service)
.generatePalette(service).build()
.into(new SimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize,
bigNotificationImageSize) {
@Override
public void onResourceReady(BitmapPaletteWrapper resource,
GlideAnimation<? super BitmapPaletteWrapper> glideAnimation) {
update(resource.getBitmap(),
PreferenceUtil.getInstance().isDominantColor() ?
RetroColorUtil.getDominantColor(resource.getBitmap(), Color.TRANSPARENT) :
RetroColorUtil.getColor(resource.getPalette(), Color.TRANSPARENT));
}
@Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
update(null, Color.TRANSPARENT);
}
void update(Bitmap bitmap, int color) {
if (bitmap == null) {
bitmap = BitmapFactory
.decodeResource(service.getResources(), R.drawable.default_album_art);
}
NotificationCompat.Action playPauseAction = new NotificationCompat.Action(
playButtonResId,
service.getString(R.string.action_play_pause),
retrievePlaybackAction(ACTION_TOGGLE_PAUSE));
NotificationCompat.Action closeAction = new NotificationCompat.Action(
R.drawable.ic_close_white_24dp,
service.getString(R.string.close_notification),
retrievePlaybackAction(ACTION_QUIT));
NotificationCompat.Action previousAction = new NotificationCompat.Action(
R.drawable.ic_skip_previous_white_24dp,
service.getString(R.string.action_previous),
retrievePlaybackAction(ACTION_REWIND));
NotificationCompat.Action nextAction = new NotificationCompat.Action(
R.drawable.ic_skip_next_white_24dp,
service.getString(R.string.action_next),
retrievePlaybackAction(ACTION_SKIP));
NotificationCompat.Builder builder = new NotificationCompat.Builder(service,
NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setLargeIcon(bitmap)
.setContentIntent(clickIntent)
.setDeleteIntent(deleteIntent)
.setContentTitle(Html.fromHtml("<b>" + song.getTitle() + "</b>"))
.setContentText(song.getArtistName())
.setSubText(Html.fromHtml("<b>" + song.getAlbumName() + "</b>"))
.setOngoing(isPlaying)
.setShowWhen(false)
.addAction(previousAction)
.addAction(playPauseAction)
.addAction(nextAction)
.addAction(closeAction);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setStyle(new MediaStyle()
.setMediaSession(service.getMediaSession().getSessionToken())
.setShowActionsInCompactView(0, 1, 2, 3, 4))
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O &&
PreferenceUtil.getInstance().coloredNotification()) {
builder.setColor(color);
}
}
if (stopped) {
return; // notification has been stopped before loading was finished
}
updateNotifyModeAndPostNotification(builder.build());
}
}));
}
private PendingIntent retrievePlaybackAction(final String action) {
final ComponentName serviceName = new ComponentName(service, MusicService.class);
Intent intent = new Intent(action);
intent.setComponent(serviceName);
return PendingIntent.getService(service, 0, intent, 0);
}
}

View file

@ -0,0 +1,138 @@
package code.name.monkey.retromusic.service.notification
import android.app.PendingIntent
import android.content.ComponentName
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Build
import android.text.Html
import androidx.core.app.NotificationCompat
import androidx.media.app.NotificationCompat.MediaStyle
import code.name.monkey.retromusic.Constants.ACTION_QUIT
import code.name.monkey.retromusic.Constants.ACTION_REWIND
import code.name.monkey.retromusic.Constants.ACTION_SKIP
import code.name.monkey.retromusic.Constants.ACTION_TOGGLE_PAUSE
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.ui.activities.MainActivity
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroColorUtil
import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
class PlayingNotificationImpl24 : PlayingNotification() {
@Synchronized
override fun update() {
stopped = false
val song = service.currentSong
val isPlaying = service.isPlaying
val playButtonResId = if (isPlaying)
R.drawable.ic_pause_white_24dp
else
R.drawable.ic_play_arrow_white_24dp
val action = Intent(service, MainActivity::class.java)
action.putExtra("expand", true)
action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
val clickIntent = PendingIntent
.getActivity(service, 0, action, PendingIntent.FLAG_UPDATE_CURRENT)
val serviceName = ComponentName(service, MusicService::class.java)
val intent = Intent(ACTION_QUIT)
intent.component = serviceName
val deleteIntent = PendingIntent.getService(service, 0, intent, 0)
val bigNotificationImageSize = service.resources
.getDimensionPixelSize(R.dimen.notification_big_image_size)
service.runOnUiThread {
SongGlideRequest.Builder.from(Glide.with(service), song)
.checkIgnoreMediaStore(service)
.generatePalette(service).build()
.into(object : SimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize, bigNotificationImageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
update(resource.bitmap, when {
PreferenceUtil.getInstance().isDominantColor -> RetroColorUtil.getDominantColor(resource.bitmap, Color.TRANSPARENT)
else -> RetroColorUtil.getColor(resource.palette, Color.TRANSPARENT)
})
}
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
update(null, Color.TRANSPARENT)
}
fun update(bitmap: Bitmap?, color: Int) {
var bitmapFinal = bitmap
if (bitmapFinal == null) {
bitmapFinal = BitmapFactory.decodeResource(service.resources, R.drawable.default_album_art)
}
val playPauseAction = NotificationCompat.Action(
playButtonResId,
service.getString(R.string.action_play_pause),
retrievePlaybackAction(ACTION_TOGGLE_PAUSE))
val closeAction = NotificationCompat.Action(
R.drawable.ic_close_white_24dp,
service.getString(R.string.close_notification),
retrievePlaybackAction(ACTION_QUIT))
val previousAction = NotificationCompat.Action(
R.drawable.ic_skip_previous_white_24dp,
service.getString(R.string.action_previous),
retrievePlaybackAction(ACTION_REWIND))
val nextAction = NotificationCompat.Action(
R.drawable.ic_skip_next_white_24dp,
service.getString(R.string.action_next),
retrievePlaybackAction(ACTION_SKIP))
val builder = NotificationCompat.Builder(service,
PlayingNotification.NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setLargeIcon(bitmapFinal)
.setContentIntent(clickIntent)
.setDeleteIntent(deleteIntent)
.setContentTitle(Html.fromHtml("<b>" + song.title + "</b>"))
.setContentText(song.artistName)
.setSubText(Html.fromHtml("<b>" + song.albumName + "</b>"))
.setOngoing(isPlaying)
.setShowWhen(false)
.addAction(previousAction)
.addAction(playPauseAction)
.addAction(nextAction)
.addAction(closeAction)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setStyle(MediaStyle()
.setMediaSession(service.mediaSession.sessionToken)
.setShowActionsInCompactView(0, 1, 2, 3, 4))
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O && PreferenceUtil.getInstance().coloredNotification()) {
builder.color = color
}
}
if (stopped) {
return // notification has been stopped before loading was finished
}
updateNotifyModeAndPostNotification(builder.build())
}
})
}
}
private fun retrievePlaybackAction(action: String): PendingIntent {
val serviceName = ComponentName(service, MusicService::class.java)
val intent = Intent(action)
intent.component = serviceName
return PendingIntent.getService(service, 0, intent, 0)
}
}

View file

@ -87,7 +87,7 @@ class PlayingNotificationOreo : PlayingNotification() {
val bigNotificationImageSize = service.resources
.getDimensionPixelSize(R.dimen.notification_big_image_size)
service.runOnUiThread(Runnable {
service.runOnUiThread {
if (target != null) {
Glide.clear(target!!)
}
@ -179,7 +179,7 @@ class PlayingNotificationOreo : PlayingNotification() {
}
})
})
}
if (stopped) {
return // notification has been stopped before loading was finished