[Tutorial] Communication between Activity and Service using BroadcastReceiver

  • Replies:2
Nguyen Ba Thanh
  • Forum posts: 14

Apr 8, 2013, 8:26:24 AM via Website

BroadcastRecevier is the one of six component that provide bulding block for your application(Activitis,Services,Content Providers, Intents, Broadcast Receviers, Notifications).They are Intent broadcast consumers. By creating and registering a Broadcast Receiver, your application can listen for broadcast Intents that match specific filter criteria. Broadcast Receivers will automatically start your application to respond to an incoming Intent, making them ideal for event-driven applications.
This tip source is provided by 9android developer at http://www.9android.net/broadcast-receiver/

Here,we will know how to use BroadcastReceiver to communication with Activity and Service,use BroadcastReceiver to listen system broadcast intent. We will create an simple application to listening music from Internet.
advancebroadcast

Create XML Layout activity_main.xml

1<LinearLayout xmlns:android="schemas.android.com/apk/res/android"
2xmlns:tools="schemas.android.com/tools"
3android:id="@+id/LinearLayout1"
4android:layout_width="match_parent"
5android:layout_height="match_parent"
6android:orientation="vertical" >
7<LinearLayout
8android:layout_width="match_parent"
9android:layout_height="wrap_content" >
10<TextView
11android:id="@+id/textView1"
12android:layout_width="wrap_content"
13android:layout_height="wrap_content"
14android:text="Link"
15android:textAppearance="?android:attr/textAppearanceLarge" />
16<EditText
17android:id="@+id/linkfile_edt"
18android:layout_width="wrap_content"
19android:layout_height="wrap_content"
20android:layout_weight="1"
21android:ems="10" >
22<requestFocus />
23</EditText>
24</LinearLayout>
25<ImageView
26android:id="@+id/imageView1"
27android:layout_width="wrap_content"
28android:layout_height="wrap_content"
29android:layout_weight="1"
30android:scaleType="fitXY"
31android:src="@drawable/nine_android_net" />
32<LinearLayout
33android:layout_width="match_parent"
34android:layout_height="wrap_content"
35android:background="@color/white" >
36<TextView
37android:id="@+id/current_time_txt"
38android:layout_width="wrap_content"
39android:layout_height="wrap_content"
40android:layout_marginLeft="5dp"
41android:layout_marginRight="5dp"
42android:gravity="center"
43android:text="0:00"
44android:textAppearance="?android:attr/textAppearanceMedium"
45android:textColor="@color/black"
46android:textStyle="bold" />
47<SeekBar
48android:id="@+id/song_playing_progressbar"
49android:layout_width="match_parent"
50android:layout_height="wrap_content"
51android:layout_weight="1" />
52<TextView
53android:id="@+id/total_time_txt"
54android:layout_width="wrap_content"
55android:layout_height="wrap_content"
56android:layout_marginLeft="5dp"
57android:layout_marginRight="5dp"
58android:gravity="center"
59android:text="0:00"
60android:textAppearance="?android:attr/textAppearanceMedium"
61android:textColor="@color/black"
62android:textStyle="bold" />
63</LinearLayout>
64<LinearLayout
65android:layout_width="match_parent"
66android:layout_height="wrap_content"
67android:layout_gravity="center"
68android:background="@drawable/panel_shape" >
69<ImageView
70android:id="@+id/btn_backward"
71android:layout_width="wrap_content"
72android:layout_height="wrap_content"
73android:layout_gravity="center"
74android:layout_marginLeft="5dp"
75android:layout_marginRight="5dp"
76android:layout_weight="1"
77android:src="@drawable/ic_media_rew" />
78<ImageView
79android:id="@+id/btn_play"
80android:layout_width="wrap_content"
81android:layout_height="wrap_content"
82android:layout_gravity="center"
83android:layout_marginBottom="5dp"
84android:layout_marginTop="5dp"
85android:layout_weight="1"
86android:src="@drawable/ic_media_play" />
87<ImageView
88android:id="@+id/btn_forward"
89android:layout_width="wrap_content"
90android:layout_height="wrap_content"
91android:layout_gravity="center"
92android:layout_marginLeft="5dp"
93android:layout_marginRight="5dp"
94android:layout_weight="1"
95android:src="@drawable/ic_media_ff" />
96</LinearLayout>
97</LinearLayout>

Declaration In Menifest

1<manifest xmlns:android="schemas.android.com/apk/res/android"
2package="com.nineandroid.net.broadcastreciverformusicplayingfrominternet"
3android:versionCode="1"
4android:versionName="1.0" >
5<uses-sdk
6android:minSdkVersion="8"
7android:targetSdkVersion="15" />
8<uses-permission android:name="android.permission.INTERNET" />
9<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
10<uses-permission android:name="android.permission.READ_PHONE_STATE" />
11<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
12<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
13<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
14<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
15<application
16android:icon="@drawable/icon"
17android:label="@string/app_name"
18android:theme="@style/AppTheme" >
19<activity
20android:name=".MainActivity"
21android:label="@string/title_activity_main" >
22<intent-filter>
23<action android:name="android.intent.action.MAIN" />
24<category android:name="android.intent.category.LAUNCHER" />
25</intent-filter>
26</activity>
27<service android:name="PlayerService" >
28</service>
29</application>
30</manifest>

BroadcastReceiver to listen Intent.ACTION_HEADSET_PLUG

1/**
2 * The BroadCast Receiver is used to listen system broadcast intent when
3 * headsets gets unplugged. If headset gets unplugged, stop music and
4 * service.
5 */
6 private int headsetSwitch = 1;
7 private BroadcastReceiver headsetReceiver = new BroadcastReceiver() {
8 private boolean headsetConnected = false;
9
10 @Override
11 public void onReceive(Context context, Intent intent) {
12 // TODO Auto-generated method stub
13 // Log.v(TAG, "ACTION_HEADSET_PLUG Intent received");
14 if (intent.hasExtra("state")) {
15 if (headsetConnected && intent.getIntExtra("state", 0) == 0) {
16 headsetConnected = false;
17 headsetSwitch = 0;
18 } else if (!headsetConnected
19 && intent.getIntExtra("state", 0) == 1) {
20 headsetConnected = true;
21 headsetSwitch = 1;
22 }
23
24 }
25 switch (headsetSwitch) {
26 case (0):
27 headsetDisconnected();
28 break;
29 case (1):
30 break;
31 }
32 }
33 };
PlayerService class

1public class PlayerService extends Service implements OnCompletionListener,
2 OnSeekBarChangeListener, OnClickListener, OnErrorListener,
3 OnPreparedListener, OnBufferingUpdateListener, OnSeekCompleteListener,
4 OnInfoListener {
5
6 private WeakReference btnPlay, btnForward, btnBackward;
7 private WeakReference songProgressBar;
8 private WeakReference songCurrentDurationLabel;
9 private WeakReference songTotalDurationLabel;
10 public static MediaPlayer mp;
11 // Handler to update UI timer, progress bar etc,.
12 private Handler mHandler = new Handler();;
13 // private SongsManager songManager;
14 private Utilities utils;
15 private int seekForwardTime = 5000; // 5000 milliseconds
16 private int seekBackwardTime = 5000; // 5000 milliseconds
17 public static int currentSongIndex = -1;
18 public static int songindexForPause = 0;
19 // Set up broadcast identifier and intent
20 public static final String BROADCAST_BUFFER = "com.9android.net.broadcastbuffer";
21 Intent bufferIntent;
22
23 private boolean isPausedInCall = false;
24 private PhoneStateListener phoneStateListener;
25 private TelephonyManager telephonyManager;
26 private static final String TAG = "TELEPHONESERVICE";
27
28 /**
29 * The BroadCast Receiver is used to listen system broadcast intent when
30 * headsets gets unplugged. If headset gets unplugged, stop music and
31 * service.
32 */
33 private int headsetSwitch = 1;
34 private BroadcastReceiver headsetReceiver = new BroadcastReceiver() {
35 private boolean headsetConnected = false;
36
37 @Override
38 public void onReceive(Context context, Intent intent) {
39 // TODO Auto-generated method stub
40 // Log.v(TAG, "ACTION_HEADSET_PLUG Intent received");
41 if (intent.hasExtra("state")) {
42 if (headsetConnected && intent.getIntExtra("state", 0) == 0) {
43 headsetConnected = false;
44 headsetSwitch = 0;
45 } else if (!headsetConnected
46 && intent.getIntExtra("state", 0) == 1) {
47 headsetConnected = true;
48 headsetSwitch = 1;
49 }
50
51 }
52 switch (headsetSwitch) {
53 case (0):
54 headsetDisconnected();
55 break;
56 case (1):
57 break;
58 }
59 }
60 };
61
62 @Override
63 public void onCreate() {
64 // TODO Auto-generated method stub
65 mp = new MediaPlayer();
66 mp.setOnCompletionListener(this);
67 mp.setOnErrorListener(this);
68 mp.setOnPreparedListener(this);
69 mp.setOnBufferingUpdateListener(this);
70 mp.setOnSeekCompleteListener(this);
71 mp.setOnInfoListener(this);
72 mp.reset();
73 mp.setAudioStreamType(AudioManager.STREAM_MUSIC);//
74 utils = new Utilities();
75 // Instantiate bufferIntent to communicate with Activity for progress
76 // dialogue
77 bufferIntent = new Intent(BROADCAST_BUFFER);
78 // Register headset receiver
79 registerReceiver(headsetReceiver, new IntentFilter(
80 Intent.ACTION_HEADSET_PLUG));
81 super.onCreate();
82
83 }
84
85 // --------------onStartCommand-------------------------------------------------------------------------//
86 @Override
87 public int onStartCommand(Intent intent, int flags, int startId) {
88 initUI();
89 String songLink = intent.getExtras().getString("songLink");
90 Log.d("SongLink", "SongLink = " + songLink);
91 if (songLink.compareTo("") != 0)
92 playSong(songLink);
93 // Manage incoming phone calls during playback. Pause mp on incoming,
94 // resume on hangup.
95 // Get the telephony manager
96 telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
97 phoneStateListener = new PhoneStateListener() {
98 @Override
99 public void onCallStateChanged(int state, String incomingNumber) {
100 // String stateString = "N/A";
101 Log.v(TAG, "Starting CallStateChange");
102 switch (state) {
103 case TelephonyManager.CALL_STATE_OFFHOOK:
104 case TelephonyManager.CALL_STATE_RINGING:// incoming call
105 if (mp != null) {
106 pauseMedia();
107 isPausedInCall = true;
108 }
109 break;
110 case TelephonyManager.CALL_STATE_IDLE:// call finish
111 // Phone idle. Start playing.
112 if (mp != null) {
113 if (isPausedInCall) {
114 isPausedInCall = false;
115 playMedia();
116 }
117 }
118 break;
119 }
120 }
121 };
122 // Register the listener with the telephony manager
123 telephonyManager.listen(phoneStateListener,
124 PhoneStateListener.LISTEN_CALL_STATE);
125
126 super.onStart(intent, startId);
127 return START_STICKY;
128 }
129
130 /**
131 * @author 9Android.net
132 */
133 private void initUI() {
134 songCurrentDurationLabel = new WeakReference(
135 MainActivity.songCurrentDurationLabel);
136 songTotalDurationLabel = new WeakReference(
137 MainActivity.songTotalDurationLabel);
138
139 btnPlay = new WeakReference(MainActivity.btnPlay);
140 btnForward = new WeakReference(MainActivity.btnForward);
141 btnBackward = new WeakReference(MainActivity.btnBackward);
142
143 btnPlay.get().setOnClickListener(this);
144 btnForward.get().setOnClickListener(this);
145 btnBackward.get().setOnClickListener(this);
146
147 songProgressBar = new WeakReference(
148 MainActivity.songProgressBar);
149 songProgressBar.get().setOnSeekBarChangeListener(this);
150 }
151
152 // Send a message to Activity that audio is being prepared and buffering
153 // started.
154 private void sendBufferingBroadcast() {
155 // Log.v(TAG, "BufferStartedSent");
156 bufferIntent.putExtra("buffering", "1");
157 sendBroadcast(bufferIntent);
158 }
159
160 // Send a message to Activity that audio is prepared and ready to start
161 // playing.
162 private void sendBufferCompleteBroadcast() {
163 bufferIntent.putExtra("buffering", "0");
164 sendBroadcast(bufferIntent);
165 }
166
167 // -------------------------------------------------------------------------//
168 @Override
169 public void onClick(View v) {
170 // TODO Auto-generated method stub
171 switch (v.getId()) {
172 case R.id.btn_play:
173 if (mp.isPlaying()) {
174 if (mp != null) {
175 mp.pause();
176 // Changing button image to play button
177 btnPlay.get().setImageResource(R.drawable.ic_media_play);
178 Log.d("Player Service", "Pause");
179
180 }
181 } else {
182 // Resume song
183 if (mp != null) {
184 mp.start();
185 // Changing button image to pause button
186 btnPlay.get().setImageResource(R.drawable.ic_media_pause);
187 }
188 }
189 break;
190
191 case R.id.btn_forward:
192
193 // get current song position
194 int currentPosition = mp.getCurrentPosition();
195 // check if seekForward time is lesser than song duration
196 if (currentPosition + seekForwardTime <= mp.getDuration()) { // forward song mp.seekTo(currentPosition + seekForwardTime); } else { // forward to end position mp.seekTo(mp.getDuration()); } break; case R.id.btn_backward: // get current song position int currentPosition2 = mp.getCurrentPosition(); // check if seekBackward time is greater than 0 sec if (currentPosition2 - seekBackwardTime >= 0) {
197 // forward song
198 mp.seekTo(currentPosition2 - seekBackwardTime);
199 } else {
200 // backward to starting position
201 mp.seekTo(0);
202 }
203 break;
204
205 }
206 }
207
208 // -------------------------------------------------------------//
209 public void playSong(String songPath) {
210 mHandler.removeCallbacks(mUpdateTimeTask);
211 mp.reset();
212 if (!mp.isPlaying()) {
213 try {
214 mp.setDataSource(songPath);
215 // Send message to Activity to display progress dialogue
216 sendBufferingBroadcast();
217 mp.prepareAsync();
218 // Changing Button Image to pause image
219 btnPlay.get().setImageResource(R.drawable.ic_media_pause);
220 // set Progress bar values
221 songProgressBar.get().setProgress(0);
222 songProgressBar.get().setMax(100);
223 } catch (IllegalArgumentException e) {
224 e.printStackTrace();
225 } catch (IllegalStateException e) {
226 e.printStackTrace();
227 } catch (IOException e) {
228 e.printStackTrace();
229 }
230 }
231
232 }
233
234 // Called when the media file is ready for playback.--------------------//
235 public void onPrepared(MediaPlayer mp) {
236 // Send a message to activity to end progress dialogue
237 sendBufferCompleteBroadcast();
238 playMedia();
239 }
240
241 public void playMedia() {
242 if (!mp.isPlaying()) {
243 mp.start();
244 updateProgressBar();
245 }
246 }
247
248 // Add for Telephony Manager
249 public void pauseMedia() {
250 // Log.v(TAG, "Pause Media");
251 if (mp.isPlaying()) {
252 mp.pause();
253 }
254
255 }
256
257 public void stopMedia() {
258 if (mp.isPlaying()) {
259 mp.stop();
260 }
261 }
262
263 /**
264 * Update timer on seekbar
265 * */
266 public void updateProgressBar() {
267 mHandler.postDelayed(mUpdateTimeTask, 100);
268 }
269
270 /**
271 * Background Runnable thread
272 * */
273 private Runnable mUpdateTimeTask = new Runnable() {
274 public void run() {
275 long totalDuration = 0;
276 try {
277 totalDuration = mp.getDuration();
278 } catch (IllegalStateException e) {
279 e.printStackTrace();
280 }
281 long currentDuration = 0;
282 try {
283 currentDuration = mp.getCurrentPosition();
284 } catch (IllegalStateException e) {
285 e.printStackTrace();
286 }
287 // Displaying Total Duration time
288 songTotalDurationLabel.get().setText(
289 "" + utils.milliSecondsToTimer(totalDuration));
290 // Displaying time completed playing
291 songCurrentDurationLabel.get().setText(
292 "" + utils.milliSecondsToTimer(currentDuration));
293
294 // Updating progress bar
295 int progress = (int) (utils.getProgressPercentage(currentDuration,
296 totalDuration));
297 // Log.d("Progress", ""+progress);
298 songProgressBar.get().setProgress(progress);
299 // Running this thread after 100 milliseconds
300 mHandler.postDelayed(this, 100);
301
302 }
303 };
304
305 /**
306 * onProgressChanged
307 */
308 @Override
309 public void onProgressChanged(SeekBar seekBar, int progress,
310 boolean fromTouch) {
311 }
312
313 /**
314 * When user starts moving the progress handler
315 * */
316 @Override
317 public void onStartTrackingTouch(SeekBar seekBar) {
318 // remove message Handler from updating progress bar
319 mHandler.removeCallbacks(mUpdateTimeTask);
320 }
321
322 /**
323 * When user stops moving the progress hanlder
324 * */
325 @Override
326 public void onStopTrackingTouch(SeekBar seekBar) {
327 mHandler.removeCallbacks(mUpdateTimeTask);
328 int totalDuration = mp.getDuration();
329 int currentPosition = utils.progressToTimer(seekBar.getProgress(),
330 totalDuration);
331
332 // forward or backward to certain seconds
333 mp.seekTo(currentPosition);
334 // update timer progress again
335 updateProgressBar();
336 }
337
338 /**
339 * On Song Playing completed if repeat is ON play same song again if shuffle
340 * is ON play random song
341 * */
342 @Override
343 public void onCompletion(MediaPlayer arg0) {
344 mp.stop();
345 mp.release();
346 }
347
348 @Override
349 public void onDestroy() {
350 super.onDestroy();
351 currentSongIndex = -1;
352 mHandler.removeCallbacks(mUpdateTimeTask);
353 Log.d("Player Service", "Player Service Stopped");
354 if (mp != null) {
355 if (mp.isPlaying()) {
356 mp.stop();
357 }
358 mp.release();
359 }
360
361 if (phoneStateListener != null) {
362 telephonyManager.listen(phoneStateListener,
363 PhoneStateListener.LISTEN_NONE);
364 }
365 // --Unregister headsetReceiver
366 unregisterReceiver(headsetReceiver);
367
368 }
369
370 // Media Listener
371 @Override
372 public boolean onInfo(MediaPlayer mp, int what, int extra) {
373 // TODO Auto-generated method stub
374 return false;
375 }
376
377 @Override
378 public void onSeekComplete(MediaPlayer mp) {
379 // TODO Auto-generated method stub
380
381 }
382
383 @Override
384 public void onBufferingUpdate(MediaPlayer mp, int percent) {
385 // TODO Auto-generated method stub
386 }
387
388 @Override
389 public boolean onError(MediaPlayer mp, int what, int extra) {
390 // TODO Auto-generated method stub
391 return false;
392 }
393
394 private void headsetDisconnected() {
395 pauseMedia();
396
397 }
398
399 @Override
400 public IBinder onBind(Intent intent) {
401 // TODO Auto-generated method stub
402 return null;
403 }
404
405}

MainActivity

1public class MainActivity extends Activity implements OnClickListener {
2 public final static String MUSIC_LINK = "fcmeditech.com/projects/AudioStreaming/files/xotxa.mp3";
3
4 public static ImageView btnPlay, btnForward, btnBackward;
5 public static SeekBar songProgressBar;
6 public static TextView songCurrentDurationLabel, songTotalDurationLabel;
7 private EditText linkFileEdt;
8 private Intent playerService;
9
10 @Override
11 public void onCreate(Bundle savedInstanceState) {
12 super.onCreate(savedInstanceState);
13 setContentView(R.layout.activity_main);
14 initViews();
15 playerService = new Intent(MainActivity.this, PlayerService.class);
16 if (linkFileEdt.getText().toString().compareTo("") != 0) {
17 playerService
18 .putExtra("songLink", linkFileEdt.getText().toString());
19 } else {
20 playerService.putExtra("songLink", MUSIC_LINK);
21 linkFileEdt.setText(MUSIC_LINK);
22 }
23 startService(playerService);
24 }
25
26 /**
27 * @author 9Android.net
28 */
29 private void initViews() {
30 btnPlay = (ImageView) findViewById(R.id.btn_play);
31 btnForward = (ImageView) findViewById(R.id.btn_forward);
32 btnBackward = (ImageView) findViewById(R.id.btn_backward);
33 songProgressBar = (SeekBar) findViewById(R.id.song_playing_progressbar);
34 songCurrentDurationLabel = (TextView) findViewById(R.id.current_time_txt);
35 songTotalDurationLabel = (TextView) findViewById(R.id.total_time_txt);
36
37 btnPlay.setOnClickListener(this);
38 btnForward.setOnClickListener(this);
39 btnBackward.setOnClickListener(this);
40 songProgressBar.setOnClickListener(this);
41 songCurrentDurationLabel.setOnClickListener(this);
42 songTotalDurationLabel.setOnClickListener(this);
43 linkFileEdt = (EditText) findViewById(R.id.linkfile_edt);
44 }
45
46 // Handle Progress Dialog between PlayerService and PlayerActivity
47 // Handle progress dialogue for buffering...
48 private ProgressDialog pdBuff = null;
49 boolean mBufferBroadcastIsRegistered;
50 // Set up BroadcastReceiver
51 private BroadcastReceiver broadcastBufferReceiver = new BroadcastReceiver() {
52 @Override
53 public void onReceive(Context context, Intent bufferIntent) {
54 showPD(bufferIntent);
55 }
56 };
57
58 private void showPD(Intent bufferIntent) {
59 String bufferValue = bufferIntent.getStringExtra("buffering");
60 int bufferIntValue = Integer.parseInt(bufferValue);
61 // When the broadcasted "buffering" value is 1, show "Buffering"
62 // progress dialogue.
63 // When the broadcasted "buffering" value is 0, dismiss the progress
64 // dialogue.
65
66 switch (bufferIntValue) {
67 case 0:
68 if (pdBuff != null) {
69 pdBuff.dismiss();
70 }
71 break;
72
73 case 1:
74 BufferDialogue();
75 break;
76 }
77 }
78
79 /**
80 * @author 9Android.net
81 */
82 private void BufferDialogue() {
83
84 pdBuff = ProgressDialog.show(this, "Buffering...", "Loading data...",
85 true);
86 pdBuff.setCancelable(true);
87 }
88
89 // -- onResume register broadcast receiver. To improve, retrieve saved
90 // screen data
91 @Override
92 protected void onResume() {
93 // Register broadcast receiver
94 if (!mBufferBroadcastIsRegistered) {
95 registerReceiver(broadcastBufferReceiver, new IntentFilter(
96 PlayerService.BROADCAST_BUFFER));
97 mBufferBroadcastIsRegistered = true;
98 }
99 super.onResume();
100 }
101
102 // -- onPause, unregister broadcast receiver. To improve, also save screen
103 // data
104 @Override
105 protected void onPause() {
106 // Unregister broadcast receiver
107 if (mBufferBroadcastIsRegistered) {
108 unregisterReceiver(broadcastBufferReceiver);
109 mBufferBroadcastIsRegistered = false;
110 }
111 super.onPause();
112 }
113
114 @Override
115 protected void onDestroy() {
116 // TODO Auto-generated method stub
117 super.onDestroy();
118 if (!PlayerService.mp.isPlaying()) {
119 stopService(playerService);
120 }
121
122 }
123
124 @Override
125 public boolean onCreateOptionsMenu(Menu menu) {
126 getMenuInflater().inflate(R.menu.activity_main, menu);
127 return true;
128 }
129
130 public void onClick(View v) {
131 // TODO Auto-generated method stub
132
133 }
134
135}

— modified on Apr 15, 2013, 7:00:38 AM

Reply
Hrishi Deshpande
  • Forum posts: 1

Jun 12, 2013, 9:19:47 PM via Website

Hey I am using Broadcast receiver for telephony it works fine I just want to do one thing I want my caller to listen to a song while m speaking with him is that possible please let me know

Reply
kevinv wallace
  • Forum posts: 12

Jun 20, 2013, 11:13:02 AM via Website

Thank you so much for your post.example given here is very helpful to android developer.

Reply