마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

뮤직플레이어 앱을 만들고있습니다. service관련 질문드립니다..

0 추천
뮤직플레이어 앱을 만들고있습니다.

service를 실행하고 바인딩도 했습니다.

service에 mediaPlayer를 통해 음악을 재생하고, notification을 띄우고 startForground도 실행하여서

 

음악이 재생될때 앱을 홈버튼옆에 앱리스트에서 종료해도 노래가 나오게는 했습니다.

 

문제는 앱을 다시시작했을 때 종료전에 실행시킨 mediaPlayer객체에 접근을 하고싶은데

어떻게 해야할지 모르겠습니디다.

 

이것을 해결하기위해서 ActivityManager가 사용자가만든 service정보를 가져올수있다고 알게되어 해봣는데

 ActivityManager를 통해서 service를 가져올수있나 싶었는데 정보만 가져올수있고, 객체자체는 주지 않더군요....

 

앱스토에어 출시된 음악재생앱들은 제가 구현하고자 하는 기능들이 구현되있던데

어떻게 해야할까요 제발 힌트라도 주시면 정말 감사하겠습니다.
사란 (810 포인트) 님이 2019년 4월 9일 질문

2개의 답변

+1 추천
 
채택된 답변

제대로 구현하는 방법은 있겠지만 

저같은 경우는 MyApplication을 사용해서 전역변수식으로 사용하는 방법을 사용해보고 있습니다.

==================================================================

MyApplication.java

public static ArrayList<MediaPlayer> arr_player = new ArrayList<>();

==================================================================

알고계신 부분이시겠지만 링크해둡니다, 사용법에 따라 메모리 누수의 원인이 되기도 하지만

잘 사용하면 매우 편리합니다. 안드로이드 OS 버젼이 올라갈수록 보안 이슈나 엄격해진 권한 관리로 

사용자개발 앱의 제한이 워낙 심해지다보니 여러모로 고민해볼것들이 많아지네요.

MyApplication 사용법

http://theeye.pe.kr/archives/1314

포스코 (1,490 포인트) 님이 2019년 4월 9일 답변
사란님이 2019년 4월 10일 채택됨
이미... 저도 해놨다는 ㅠㅠ..
class BaseApplication : Application(){

    val BC_READY_FOR_BOTTOM_PLAYER = "com.example.musicplayer.ready_for_bottom_player"
    val BC_BOTTOM_ICON_PUASE = "com.example.musicplayer.bottom_icon_puase"
    val BC_BOTTOM_ICON_PLAY = "com.example.musicplayer.bottom_icon_play"

    lateinit var mpService : MusicPlayerService
    var mBound : Boolean = false

    val mConnection : ServiceConnection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            Log.i("TEST","onServiceConnected")
            val mpBinder : MusicPlayerService.MusicPlayerBinder = service as MusicPlayerService.MusicPlayerBinder
            mpService = mpBinder.getService()
            mBound = true
        }

        override fun onServiceDisconnected(name: ComponentName?) {
            Log.i("TEST","onServiceDisconnected")
            mBound = false
        }
    }

}
앱을 재실행할때 MainActivity에서 재생중인 음악을 Stop해서

unbindService(connection);
 stopService(service);

를 해도 기존 실행중인 노래가 종료가 되지 않던가요?

코틀린으로 작성하고 계시군요 ㅎㅎ 저도 언젠가 넘어가야하는데

게을러서... ㅠ,ㅠ
재실행해서 다시시작하는 순간 접근할수없으니까 stop도 안되요 ㅠ..
물론! 앱을끌때 unbind, stop은 잘되요 ㅎ;;

코틀린 많이 헷갈리는데 점점 좋아지는것 같아요 ㅋ;;; 소스가 짧아지거나.. 생성자 시점을 조절이 가능한다던가,, 널포인트 신경안쓰게 선언해버린다던가.등등...이건 여담이였습니다..
저같은 경우는 MainActivity에서 버튼을 스톱 또는 시작을 누르면

서비스 클래스 내에서
1) public void onDestroy()에서 미디어 객체를 다루는 stopSong();을 호출하고

2) onStartCommand에서 startSong을 호출합니다.
@Override public int onStartCommand(Intent intent, int flags, int startId) {
         startSong();
        return START_STICKY;
    }


기존 재생중인 음악을 종료하는 부분이
정상적으로 동작되는지부터 점검해보시면 좋겠네요.
포스코님 늦게나마 감사말씀드립니다.
application에 MediaPlayer를 등록해놓고 하니 됬습니다.
문제는 제가 코틀린을 이용하다보니 초기화 선언에서 혼동이 있었고
그로인해서 안됬던것 이였습니다. 감사하고 덕분에 앱을 완성할 수 있을 것같습니다. 다시한번 감사드립니다.
0 추천
안녕하세요

로컬에 있는 파일을 Play하는 것인가요?

그럼 sharedPreference에 Play중이었던 곡 이름(혹은 id..)와 재생정보(Play되었던 위치)를 저장하고 구동 시 이 정

보를 통해 다시 플레이 하면 되지 않을까요?
지나가는 나그네 님이 2019년 4월 9일 답변
먼저 답변감사드립니다.
로컬에있는 파일 맞습니다.
설명이 조금 부족했던 것같습니다 . 노래가 이미 흘러나오고있고, 그상태에서 앱을 중지해도 노래는 계속나옵니다. 그상태에서 앱을 실행했을때 지금 나오고 있는 노래에 mediaplay객체를 컨틀롤 할수(노래를 중단한다던가, 현재 나오는 지점을 알아낸다던가..) 있어야합니다. 말씀해주신대로 하면 똑같은 id라도 다른객체로 인식되서 이미 나오던 나오는 노래는 계속나오고, 새로 시작할 노래는 새롭게 되어 노래가 중복되어서 흘러나옵니다 ㅠ.. 그래도 의견감사합니다.
혹시모르니까 말씀해주신방법도 적어놧다가 구현해보겠습니다 ㅠ.
음.. 다시보니. Notification이 살아있고 노래가 Play중인걸로 봐서는 service가 살아 있는 것 같은데, service에 mediaPlayer 관련 정보가 없는 상태 인가요????
앱을 완전종료해도 service가 실행되있는 상황일때, 다시 앱을 실행했을 때 종료전실행 했던 service에 접근을 어떻게하냐가 질문내용이였습니다. (말을 잘 정리를 못해서 죄송합니다.) 물론 service를 접근하기위해 bind하긴합니다. 하지만 종료와 함께 바인딩은 풀리기 때문에 질문을 하게되었습니다....

결론적으로 오늘 해결했습니다. 포스코님 말씀처럼 application 클래스에 미디어 객체를 올려두고, 서비스는 앱실행때마다 새로 실행시키지만, 서비스에서 호출하는 미디어객체는 application에 등록해서 사용했습니다.

다시한번 정리하자면 application, service 이두가지의 생명주기를 알아야 해결가능한 문제였습니다.. 댓글과관심에 감사드립니다..
...