woong's

Android service Message 전송하기(서비스 에서 액티비티 호출) 본문

Develop/Android

Android service Message 전송하기(서비스 에서 액티비티 호출)

dlsdnd345 2016. 2. 14. 12:57

Android service Message 전송하기(서비스 에서 액티비티 호출) 


1. 콜백 aidl 작성


Colored By Color Scripter

1
2
3
4
5
package com.handstudio.android.networkaudio.services;
 
interface IMusicServiceCallback {
    void nextMusicCallBack();
}



2. aidl 에 콜백 aidl Import 진행


Colored By Color Scripter

1
2
3
4
5
6
7
8
9
10
package com.handstudio.android.networkaudio.services;
 
import com.handstudio.android.networkaudio.services.IMusicServiceCallback;
 
interface IMusicService {
 
 void registerCallback( IMusicServiceCallback callback );
    void unregisterCallback ( IMusicServiceCallback callback );
    
}

 

 

​콜백 aidl 을 사용하기 위해서는 기존 aidl 에서의 register 와 unregister 가 필요 하다. 

 

​3. 서비스 작성 

 

Colored By Color Scripter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package com.handstudio.android.networkaudio.services;
 
import java.io.IOException;
 
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnSeekCompleteListener;
import android.net.Uri;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
 
public class MusicService extends Service{
 
    private Uri             musicUri;
    private MediaPlayer     music;
    private Boolean         isFromUser;
 
    private RemoteCallbackList<IMusicServiceCallback> callbackList =
            new RemoteCallbackList<IMusicServiceCallback> ();
    
    @Override
    public IBinder onBind(Intent intent) {
        return serviceStub;
    }
 
    /**
     * 서비스가 시작 되었을때 MediaPlayer 시작
     */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        music = new MediaPlayer();
        music.setOnSeekCompleteListener(mOnSeekCompleteListener);
        return startId;
    }
 
    /**
     * 생명 주기 에서 onDestroy 되었을때 MediaPlayer 정지
     */
    @Override
    public void onDestroy (){
        super.onDestroy();
        music.stop();
    }
 
    public IMusicService.Stub serviceStub = new IMusicService.Stub() {
 
        /**
         * MediaPlayer 에 노래를 준비
         */
        @Override
        public void settingMusic(String uriString) throws RemoteException {
            try {
                musicUri = Uri.parse(uriString);
                music.reset();
                //음악 불러오기
                music.setDataSource(MusicService.this, musicUri);
                music.prepare();
            } catch (IllegalArgumentException e1) {
                e1.printStackTrace();
            } catch (SecurityException e1) {
                e1.printStackTrace();
            } catch (IllegalStateException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
 
        /**
         * 음악 재생
         */
        @Override
        public void playMusic() throws RemoteException {
            try {
                music.start();
                music.setLooping(true);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (SecurityException e) {
                e.printStackTrace();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            }  
        }
 
        @Override
        public boolean isPlaying() throws RemoteException {
            //상태 체크
            return music.isPlaying();
        }
        @Override
        public void pauseMusic() throws RemoteException {
            //상태 정지
            music.pause();
        }
        @Override
        public int getDuration() throws RemoteException {
            //음악 시간
            return music.getDuration();
        }
        @Override
        public void seekTo(int progress) throws RemoteException {
            // 음악 이동
            music.seekTo(progress);
        }
        @Override
        public void getFromUser(boolean isFormuserData) throws RemoteException {
            // 시크바 터치 상태
            isFromUser = isFormuserData;
        }
        @Override
        public int getCurrentPosition() throws RemoteException {
            // 음악의 현재 시간
            return music.getCurrentPosition();
        }
        @Override
        public void registerCallback(IMusicServiceCallback callback)throws RemoteException {
            callbackList.register(callback);
        }
        @Override
        public void unregisterCallback(IMusicServiceCallback callback)throws RemoteException {
            callbackList.unregister(callback);
        }
    };
    
    /**
     * MediaPlayer 노래 시간이 끝났을 경우 불리는 Listener
     */
    OnSeekCompleteListener mOnSeekCompleteListener = new OnSeekCompleteListener(){
        @Override
        public void onSeekComplete(MediaPlayer music) {
            // 노래가 끝나는 시점 분기친이유는 onSeekComplete 가 시크바 터치시에도 동작때문
            if(!isFromUser){
                int cnt = callbackList.beginBroadcast();
                for (int i = 0 ; i < cnt ; i++ ){
                    try {
                        callbackList.getBroadcastItem(i).nextMusicCallBack();
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
                callbackList.finishBroadcast();
            }
        }
    };
 
}



빨간색 코드가 핵심 코드 이다 . 



3. 액티비티 코드


Colored By Color Scripter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
    /**
     * Bind 되는 시점에 호출
     */
    private ServiceConnection conn = new ServiceConnection (){
        public void onServiceDisconnected(ComponentName name){}
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            musicService = IMusicService.Stub.asInterface(service);
            try{
                musicService.registerCallback(callback);
            }
            catch ( Exception ex ) {} 
            //노래 셋팅
            musicPlayerService.settingMusic(musicService,musicUri);
            seekBarInit();
        }
    };
 
/**
     * MusicService 쪽에서 Music onSeekComplete 가 호출 되는 시점에 Callback 메서드가 호출된다
     * 즉 , 노래가 끝났을때 onSeekComplete 가 호출되어 아래 하단의 Callback 메서드에서 
     * 다음 곡으로 전환해준다.
     */
    private IMusicServiceCallback callback = new IMusicServiceCallback.Stub() 
    {
        @Override
        public void nextMusicCallBack() throws RemoteException {
            nextMusic();
        }
    };
 
@Override
    public void onDestroy() {
        super.onDestroy();
        try{// 콜백 해제
            musicService.unregisterCallback(callback);
        }
        catch ( Exception ex ) {}
        //서비스 해제
        unbindService(conn);
        stopService(serviceIntent);
        super.onDestroy();
    }
 

 

 

​서비스가 바인드 되는 시점에 콜백 aidl 을 등록 한다 . 

등록이 완료 되면 서비스에서 nextMusicCallBack​ 이 호출 되면 callback 메서드가 호출된다 .


마지막으로 서비스가 종료 되는 시점인 Destroy 에서 콜백 aidl 을 해지 시켜 주면 된다.


Comments