알림바 추가
제가 작성한 tistory글의 마이그레이션입니다.
도입
이번 포스팅에서는 지난 포스팅에 이어 음악 플레이어에 알림바를 추가하는 실습을 할 예정이다.
알림바를 컨트롤 하는 것은 참 어렵다.......
알림바 추가의 데이터 흐름
이번 포스팅에서는 Service로 전달 받은 선택된 음악의 정보(Title, Artist, Album, Picture)를 Notification에게 전달해 알림바를 구현할 것이다.
문제점 및 해결
- 알림바 버튼 터치에 따른 버튼 아이콘 변경
알림바는 버튼이 터치되면 Pending Intent를 통해 자기 자신이 다시 호출된다. 버튼 아이콘의 모양은 현재 음악 플레이어의 상태에 따라 설정된다. 그래서 Next 버튼이나 Prev 버튼이 클릭되면 Pause, Play 버튼 모양이 Next, Prev 버튼 모양으로 변경된다.
원인은
1. Notification의 버튼이 클릭되었을 때 Pending Intent를 통해 재귀 함수처럼 Service 자신을 호출
2. 현재 상태를 기반으로 버튼의 상태가 결정된다.
// 알림바 버튼 생성
builder.addAction(makeButtonInNotification(Const.ACTION_MUSIC_PREV));
builder.addAction(makeButtonInNotification(currentStatus));
builder.addAction(makeButtonInNotification(Const.ACTION_MUSIC_NEXT));
때문이다.
그래서 코드를 다음과 같이 변경했다.
public class PlayerService extends Service implements SeekbarThread.IObserver {
switch (currentStatus) {
case Const.ACTION_MUSIC_SET:
currentMusic = intent.getParcelableExtra("currentMusic");
setMusic();
play();
currentStatus = Const.ACTION_MUSIC_PLAY;
break;
case Const.ACTION_MUSIC_PLAY:
play();
break;
case Const.ACTION_MUSIC_PAUSE:
pause();
break;
case Const.ACTION_MUSIC_NEXT:
next();
// 버튼을 위해
currentStatus = Const.ACTION_MUSIC_PLAY;
break;
case Const.ACTION_MUSIC_PREV:
prev();
// 버튼을 위해
currentStatus = Const.ACTION_MUSIC_PLAY;
break;
}
}
코드
public class PlayerService extends Service {
// ...
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
currentStatus = intent.getAction();
switch (currentStatus) {
case Const.ACTION_MUSIC_SET:
currentMusic = intent.getParcelableExtra("currentMusic");
setMusic();
play();
currentStatus = Const.ACTION_MUSIC_PLAY;
break;
case Const.ACTION_MUSIC_PLAY:
play();
break;
case Const.ACTION_MUSIC_PAUSE:
pause();
break;
case Const.ACTION_MUSIC_NEXT:
next();
// Notification 버튼을 위해
currentStatus = Const.ACTION_MUSIC_PLAY;
break;
case Const.ACTION_MUSIC_PREV:
prev();
// Notification 버튼을 위해
currentStatus = Const.ACTION_MUSIC_PLAY;
break;
}
startForeground(11, makeNotification());
return super.onStartCommand(intent, flags, startId);
}
// 알림바 생성 메소드
private Notification makeNotification() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
// Notification LargeIcon 설정
Bitmap largeIcon = null;
try {
largeIcon
= MediaStore.Images.Media.getBitmap
(getContentResolver(), currentMusic.getAlbumUri());
} catch (IOException e) {
e.printStackTrace();
}
builder .setSmallIcon(R.mipmap.ic_launcher_round)
.setContentTitle(currentMusic.getTitle())
.setContentText(currentMusic.getArtist())
.setLargeIcon(largeIcon);
builder.addAction(makeButtonInNotification(Const.ACTION_MUSIC_PREV));
builder.addAction(makeButtonInNotification(currentStatus));
builder.addAction(makeButtonInNotification(Const.ACTION_MUSIC_NEXT));
// 알람바 프로그래스바 추가
Log.i("heepie", CLASSNAME + currentMusic.getSecDuration());
builder.setProgress(currentMusic.getSecDuration()*1000, 0, false);
return builder.build();
}
// 알림바 버튼 생성 메소드(Prev, Play, Pause, Next)
private NotificationCompat.Action makeButtonInNotification(String action) {
int iconId = 0;
// 현재 액션 후 다음 클릭 시 다음 액션 설정
// 임의의 버튼 아이콘 등록
switch (action) {
case Const.ACTION_MUSIC_PLAY:
iconId = android.R.drawable.ic_media_pause;
action = Const.ACTION_MUSIC_PAUSE;
break;
case Const.ACTION_MUSIC_PAUSE:
iconId = android.R.drawable.ic_media_play;
action = Const.ACTION_MUSIC_PLAY;
break;
case Const.ACTION_MUSIC_NEXT:
iconId = android.R.drawable.ic_media_next;
break;
case Const.ACTION_MUSIC_PREV:
iconId = android.R.drawable.ic_media_previous;
break;
}
// PendingIntent로 등록될 Intent 생성
Intent intent = new Intent(getBaseContext(), PlayerService.class);
// Intent로 전달될 액션 설정
intent.setAction(action);
// PendingIntent 생성
PendingIntent pendingIntent
= PendingIntent.getService(getBaseContext(), 1, intent, 0);
// 버튼 타이틀 등록
String btnTitle = action;
// 해당 버튼 액션 설정
NotificationCompat.Action notifAction
= new NotificationCompat.Action.Builder
(iconId, btnTitle, pendingIntent).build();
return notifAction;
}
private void setMusic() {
// Uri로 Player 설정
playerController.setMusic(currentMusic.getMusicUri());
}
private void play() {
playerController.play();
currentStatus = Const.ACTION_MUSIC_PLAY;
}
private void pause() {
playerController.pause();
currentStatus = Const.ACTION_MUSIC_PAUSE;
}
private void next() {
playerController.next();
}
private void prev() {
playerController.prev();
}
}
스크린샷
스크린 샷처럼 알림바의 버튼 동작하지만 알림바 버튼 동작에 따른 PlayMainViewActivity의 버튼은 동작하지 않는다. 이러한 문제점은 다음 포스팅에서 처리할 예정이다.
Author And Source
이 문제에 관하여(알림바 추가), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@heepie/알림바-추가저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)