public class MediaService extends Service {
public static MediaPlayer mediaPlayer;
ScheduledExecutorService timer;
public static Intent playPauseIntent, nextMusicIntent, prevMusicIntent;
MediaSessionCompat mediaSession;
MediaMetadataCompat.Builder metadataBuilder = new MediaMetadataCompat.Builder();
final PlaybackStateCompat.Builder stateBuilder = new PlaybackStateCompat.Builder()
.setActions(
PlaybackStateCompat.ACTION_PLAY
| PlaybackStateCompat.ACTION_STOP
| PlaybackStateCompat.ACTION_PAUSE
| PlaybackStateCompat.ACTION_PLAY_PAUSE
| PlaybackStateCompat.ACTION_SKIP_TO_NEXT
| PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS
| PlaybackStateCompat.ACTION_SEEK_TO);
Drawable drawablePausePlay;
public static final int NOTIFICATION_ID = 1;
public MediaService() {
}
public class MusicBinder extends Binder {
MediaService getService() {
return MediaService.this;
}
}
private final IBinder binder = new MusicBinder();
@Override
public IBinder onBind(Intent intent) {
return binder;
}
@Override
public void onCreate() {
super.onCreate();
mediaPlayer = new MediaPlayer();
mediaSession = new MediaSessionCompat(getApplication(), "TAG");
mediaSession.setFlags(
MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS
| MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mediaSession.setCallback(new MediaSessionCompat.Callback() {
@Override
public void onSeekTo(long pos) {
if (mediaPlayer != null) {
mediaPlayer.seekTo((int) pos);
FragmentPlayer.seekBarProgress.setProgress((int)pos);
updateMediaPlaybackState((int) pos, PlaybackStateCompat.STATE_PLAYING);
Log.d("qwerty","seek");
if (!mediaPlayer.isPlaying()) playOrPause();
}
}
});
mediaSession.setActive(true);
drawablePausePlay = getDrawable(R.drawable.icon_play_notif);
playPauseIntent = new Intent(this, MediaService.class);
playPauseIntent.setAction("PlayPause");
nextMusicIntent = new Intent(this, MediaService.class);
nextMusicIntent.setAction("NextMusic");
prevMusicIntent = new Intent(this, MediaService.class);
prevMusicIntent.setAction("PrevMusic");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction() != null)
{
switch (intent.getAction().toString())
{
case "PlayPause" : playOrPause(); break;
case "NextMusic" : changeMusic(1); break;
case "PrevMusic" : changeMusic(-1); break;
}
}
return Service.START_STICKY;
}
public void updateDataMusic(ItemMusic music) {
if (music.getImage() != null)
{
if(music.getImage() == MainActivity.defaultIcon) FragmentPlayer.playerLayout.setBackground(getApplication().getDrawable(R.color.border_black_medium));
else FragmentPlayer.playerLayout.setBackground(new BitmapDrawable(MainActivity.BlurImage(music.getImage(),getApplication())));
}
else
{
music.setImage(MainActivity.defaultIcon);
FragmentPlayer.playerLayout.setBackground(getApplication().getDrawable(R.color.border_black_medium));
}
MainActivity.adapterMusic.notifyDataSetChanged();
MainActivity.tvCurTitle.setText(music.getTitle());
MainActivity.ivCurMusic.setImageBitmap(music.getImage());
FragmentPlayer.imageMusic.setImageBitmap(music.getImage());
FragmentPlayer.tvTitle.setText(music.getTitle());
FragmentPlayer.tvAuthor.setText(music.getAuthor());
FragmentPlayer.tvTotalTime.setText(MainActivity.convertToMMSS(music.getDuration()));
FragmentPlayer.seekBarProgress.setProgress(0);
}
public Notification createNotification(Context context, ItemMusic music, int iconPlayPause) {
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// Создание PendingIntents для действий кнопок.
PendingIntent piPlayPause = PendingIntent.getService(context, 0, playPauseIntent,PendingIntent.FLAG_UPDATE_CURRENT); // PendingIntent для Play/Pause
PendingIntent piNext = PendingIntent.getService(context, 0, nextMusicIntent,PendingIntent.FLAG_UPDATE_CURRENT);; // PendingIntent для Next
PendingIntent piPrevious = PendingIntent.getService(context, 0, prevMusicIntent,PendingIntent.FLAG_UPDATE_CURRENT);; // PendingIntent для Previous
// Создание канала уведомления для Android O и выше
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
"CHANNEL_ID", "Channel Name", NotificationManager.IMPORTANCE_LOW);
notificationManager.createNotificationChannel(channel);
}
metadataBuilder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, mediaPlayer.getDuration());
mediaSession.setMetadata(metadataBuilder.build());
mediaSession.setActive(true);
// Создание билдера уведомлений
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, "CHANNEL_ID")
.setSmallIcon(R.drawable.icon_music_select) // Иконка уведомления
.setContentTitle(music.getTitle()) // Название трека
.setContentText(music.getAuthor()) // Исполнитель
.setLargeIcon(music.getImage()) // Обложка альбома
.setOnlyAlertOnce(true) // Не обновлять при изменении
.setShowWhen(false) // Не показывать время уведомления
.addAction(R.drawable.icon_left_notif, "Previous", piPrevious) // Кнопка пред. трека
.addAction(iconPlayPause, "PlayPause", piPlayPause) // Кнопка плей/пауза
.addAction(R.drawable.icon_right_notif, "Next", piNext) // Кнопка след. трека
.setStyle(new androidx.media.app.NotificationCompat.MediaStyle()
.setMediaSession(mediaSession.getSessionToken()));
// Запуск уведомления
Notification notification = notificationBuilder.build();
notificationManager.notify(NOTIFICATION_ID, notification);
return notification;
}
public void updateMediaPlaybackState(long currentPos, int currentState) {
stateBuilder
.setState(
currentState,
currentPos,
1.0F
)
.setBufferedPosition(currentPos);
mediaSession.setPlaybackState(stateBuilder.build());
}
@SuppressLint("ForegroundServiceType")
public void playOrPause() {
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
FragmentPlayer.ibPlay.setBackgroundResource(R.drawable.icon_stop);
FragmentPlayer.plate.clearAnimation();
startForeground(1, createNotification(getApplication(),MainActivity.musics.get(MainActivity.currentIndexMusic), R.drawable.icon_stop_notif));
updateMediaPlaybackState(mediaPlayer.getCurrentPosition(), PlaybackStateCompat.STATE_PAUSED);
Log.d("qwerty","pause");
timer.shutdown();
} else {
mediaPlayer.start();
FragmentPlayer.ibPlay.setBackgroundResource(R.drawable.icon_play);
FragmentPlayer.plate.startAnimation(AnimationUtils.loadAnimation(this, R.anim.anim_plate));
updateMediaPlaybackState(mediaPlayer.getCurrentPosition(),PlaybackStateCompat.STATE_PLAYING);
startForeground(1, createNotification(getApplication(),MainActivity.musics.get(MainActivity.currentIndexMusic), R.drawable.icon_play_notif));
Log.d("qwerty",mediaSession.getController().getPlaybackState().toString());
timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
if (!FragmentPlayer.seekBarProgress.isPressed()) {
FragmentPlayer.seekBarProgress.setProgress(mediaPlayer.getCurrentPosition());
}
}
}, 10, 10, TimeUnit.MILLISECONDS);
}
Toast.makeText(getApplication(), mediaSession.getController().getPlaybackState().toString(),Toast.LENGTH_LONG).show();
}
}
public void createMediaPlayer(String path){
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioAttributes(
new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build()
);
try {
mediaPlayer.setDataSource(path);
mediaPlayer.prepare();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
changeMusic(1);
}
});
} catch (IOException e){
}
updateMediaPlaybackState(mediaPlayer.getCurrentPosition(),PlaybackStateCompat.STATE_PLAYING);
}
public void changeMusic(int dif) {
if (MainActivity.currentIndexMusic == -1) return;
MainActivity.currentIndexMusic += dif;
if (MainActivity.currentIndexMusic < 0 || MainActivity.currentIndexMusic > MainActivity.musics.size() - 1 ) MainActivity.currentIndexMusic = 0;
ItemMusic music = MainActivity.musics.get(MainActivity.currentIndexMusic);
updateDataMusic(music);
releaseMediaPlayer();
createMediaPlayer(music.getPath());
FragmentPlayer.seekBarProgress.setMax(MediaService.mediaPlayer.getDuration());
updateMediaPlaybackState(mediaPlayer.getCurrentPosition(), PlaybackStateCompat.STATE_PLAYING);
playOrPause();
}
public void updatePlayingTime(){
if (mediaPlayer != null) FragmentPlayer.tvCurrentTime.setText(MainActivity.convertToMMSS(String.valueOf(mediaPlayer.getCurrentPosition())));
}
public void seekMediaPlayer(){
if (mediaPlayer != null) {
mediaPlayer.seekTo(FragmentPlayer.seekBarProgress.getProgress());
updateMediaPlaybackState(mediaPlayer.getCurrentPosition(),PlaybackStateCompat.STATE_PLAYING);
}
}
public void releaseMediaPlayer(){
if (timer != null) {
timer.shutdown();
}
if (mediaPlayer != null) {
mediaPlayer.release();
mediaSession.release();
mediaPlayer = null;
}
FragmentPlayer.seekBarProgress.setMax(100);
FragmentPlayer.seekBarProgress.setProgress(0);
}
@Override
public void onDestroy() {
super.onDestroy();
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}
mediaPlayer.release();
mediaSession.release();
mediaPlayer = null;
}
}
}
I'm asking a question with a translator, so I'm sorry for the spelling. I am creating a music player application and notifications for it. I searched for a long time how to add a slider to the notification and such an error came out that when I pause the player and turn it on again, the slider in the notification stops moving, otherwise everything works. Thank you in advance for your help! Задаю вопрос с переводчиком так что за орфографию извините. Я создаю приложение музыкальный плеер а также для него уведомления долго рыскал как добавить к уведомлению ползунок и вылезла такая ошибка что когда я ставлю плеер на паузу и снова его включаю ползунок в уведомлении перестает двигаться в остальном все работает. Заранее благодарю за помощь!