@@ -18,29 +18,27 @@ Licensed to the Apache Software Foundation (ASF) under one
18
18
*/
19
19
package org .apache .cordova .media ;
20
20
21
- import org .apache .cordova .CallbackContext ;
22
- import org .apache .cordova .CordovaPlugin ;
23
- import org .apache .cordova .CordovaResourceApi ;
24
21
import org .apache .cordova .PermissionHelper ;
25
-
26
- import android .Manifest ;
27
- import android .content .Context ;
28
- import android .content .pm .PackageManager ;
29
- import android .media .AudioManager ;
30
- import android .media .AudioManager .OnAudioFocusChangeListener ;
31
- import android .net .Uri ;
32
- import android .os .Build ;
33
-
34
22
import java .security .Permission ;
23
+
35
24
import java .util .ArrayList ;
25
+ import java .util .HashMap ;
36
26
27
+ import org .apache .cordova .CallbackContext ;
28
+ import org .apache .cordova .CordovaPlugin ;
29
+ import org .apache .cordova .CordovaResourceApi ;
37
30
import org .apache .cordova .LOG ;
38
31
import org .apache .cordova .PluginResult ;
39
32
import org .json .JSONArray ;
40
33
import org .json .JSONException ;
41
34
import org .json .JSONObject ;
42
35
43
- import java .util .HashMap ;
36
+ import android .Manifest ;
37
+ import android .content .Context ;
38
+ import android .content .pm .PackageManager ;
39
+ import android .media .AudioManager ;
40
+ import android .media .AudioManager .OnAudioFocusChangeListener ;
41
+ import android .net .Uri ;
44
42
45
43
/**
46
44
* This class called by CordovaActivity to play and record audio.
@@ -57,8 +55,10 @@ public class AudioHandler extends CordovaPlugin {
57
55
58
56
public static String TAG = "AudioHandler" ;
59
57
HashMap <String , AudioPlayer > players ; // Audio player object
60
- ArrayList <AudioPlayer > pausedForPhone ; // Audio players that were paused when phone call came in
61
- ArrayList <AudioPlayer > pausedForFocus ; // Audio players that were paused when focus was lost
58
+ ArrayList <AudioPlayer > paused ; // Audio players that were paused. Reasons:
59
+ boolean audioFocusLost = false ; // paused when audiofocus was lost
60
+ boolean calling = false ; // paused when calling
61
+ boolean activityFocusLost = false ; // paused when activity got paused
62
62
private int origVolumeStream = -1 ;
63
63
private CallbackContext messageChannel ;
64
64
@@ -77,8 +77,7 @@ public class AudioHandler extends CordovaPlugin {
77
77
*/
78
78
public AudioHandler () {
79
79
this .players = new HashMap <String , AudioPlayer >();
80
- this .pausedForPhone = new ArrayList <AudioPlayer >();
81
- this .pausedForFocus = new ArrayList <AudioPlayer >();
80
+ this .paused = new ArrayList <AudioPlayer >();
82
81
}
83
82
84
83
@@ -129,13 +128,20 @@ else if (action.equals("resumeRecordingAudio")) {
129
128
else if (action .equals ("startPlayingAudio" )) {
130
129
String target = args .getString (1 );
131
130
String fileUriStr ;
131
+ boolean playAudioWhenScreenIsLocked =true ;
132
132
try {
133
133
Uri targetUri = resourceApi .remapUri (Uri .parse (target ));
134
134
fileUriStr = targetUri .toString ();
135
135
} catch (IllegalArgumentException e ) {
136
136
fileUriStr = target ;
137
137
}
138
- this .startPlayingAudio (args .getString (0 ), FileHelper .stripFileProtocol (fileUriStr ));
138
+ try {
139
+ JSONObject playArgs = new JSONObject (args .getString (2 ));
140
+ playAudioWhenScreenIsLocked = playArgs .getBoolean ("playAudioWhenScreenIsLocked" );
141
+ } catch (JSONException e ) {
142
+ playAudioWhenScreenIsLocked = true ;
143
+ }
144
+ this .startPlayingAudio (args .getString (0 ), FileHelper .stripFileProtocol (fileUriStr ),playAudioWhenScreenIsLocked );
139
145
}
140
146
else if (action .equals ("seekToAudio" )) {
141
147
this .seekToAudio (args .getString (0 ), args .getInt (1 ));
@@ -225,21 +231,21 @@ public Object onMessage(String id, Object data) {
225
231
if ("ringing" .equals (data ) || "offhook" .equals (data )) {
226
232
227
233
// Get all audio players and pause them
228
- for (AudioPlayer audio : this .players .values ()) {
229
- if (audio .getState () == AudioPlayer .STATE .MEDIA_RUNNING .ordinal ()) {
230
- this .pausedForPhone .add (audio );
231
- audio .pausePlaying ();
232
- }
233
- }
234
+ calling = true ;
235
+ pauseAll ();
234
236
235
237
}
236
238
237
239
// If phone idle, then resume playing those players we paused
238
240
else if ("idle" .equals (data )) {
239
- for (AudioPlayer audio : this .pausedForPhone ) {
240
- audio .startPlaying (null );
241
- }
242
- this .pausedForPhone .clear ();
241
+ if (!audioFocusLost ){
242
+ if (activityFocusLost ) {
243
+ resumePlayingMarked ();
244
+ }else {
245
+ resumePlayingAll ();
246
+ }
247
+ }
248
+ calling = false ;
243
249
}
244
250
}
245
251
return null ;
@@ -250,14 +256,19 @@ else if ("idle".equals(data)) {
250
256
//--------------------------------------------------------------------------
251
257
252
258
private AudioPlayer getOrCreatePlayer (String id , String file ) {
259
+ return getOrCreatePlayer (id ,file ,true );
260
+ }
261
+
262
+ private AudioPlayer getOrCreatePlayer (String id , String file , boolean playAudioWhenScreenIsLocked ) {
253
263
AudioPlayer ret = players .get (id );
254
264
if (ret == null ) {
255
265
if (players .isEmpty ()) {
256
266
onFirstPlayerCreated ();
257
267
}
258
- ret = new AudioPlayer (this , id , file );
268
+ ret = new AudioPlayer (this , id , file , playAudioWhenScreenIsLocked );
259
269
players .put (id , ret );
260
270
}
271
+ ret .setPlayAudioWhenScreenIsLocked (playAudioWhenScreenIsLocked );
261
272
return ret ;
262
273
}
263
274
@@ -315,8 +326,8 @@ public void resumeRecordingAudio(String id) {
315
326
* @param id The id of the audio player
316
327
* @param file The name of the audio file.
317
328
*/
318
- public void startPlayingAudio (String id , String file ) {
319
- AudioPlayer audio = getOrCreatePlayer (id , file );
329
+ public void startPlayingAudio (String id , String file , boolean playAudioWhenScreenIsLocked ) {
330
+ AudioPlayer audio = getOrCreatePlayer (id , file , playAudioWhenScreenIsLocked );
320
331
audio .startPlaying (file );
321
332
getAudioFocus ();
322
333
}
@@ -400,22 +411,56 @@ else if (output == 1) {
400
411
}
401
412
}
402
413
403
- public void pauseAllLostFocus () {
414
+ /**
415
+ * This method pauses all AudioPlayers.
416
+ * */
417
+ public void pauseAll () {
404
418
for (AudioPlayer audio : this .players .values ()) {
405
419
if (audio .getState () == AudioPlayer .STATE .MEDIA_RUNNING .ordinal ()) {
406
- this .pausedForFocus .add (audio );
420
+ this .paused .add (audio );
407
421
audio .pausePlaying ();
408
422
}
409
423
}
410
424
}
411
425
412
- public void resumeAllGainedFocus () {
413
- for (AudioPlayer audio : this .pausedForFocus ) {
426
+ /**
427
+ * This method pauses all AudioPlayers not marked with isPlayAudioWhenScreenIsLocked.
428
+ * */
429
+ public void pauseAudiosNotMarked () {
430
+ for (AudioPlayer audio : this .players .values ()) {
431
+ if (audio .getState () == AudioPlayer .STATE .MEDIA_RUNNING .ordinal () && !audio .isPlayAudioWhenScreenIsLocked ()) {
432
+ this .paused .add (audio );
433
+ audio .pausePlaying ();
434
+ }
435
+ }
436
+ }
437
+
438
+ /**
439
+ * Resume playing all paused audios
440
+ */
441
+ public void resumePlayingAll () {
442
+ for (AudioPlayer audio : this .paused ) {
414
443
audio .resumePlaying ();
415
444
}
416
- this . pausedForFocus .clear ();
445
+ paused .clear ();
417
446
}
418
447
448
+ /**
449
+ * Resume playing all audios marked with isPlayAudioWhenScreenIsLocked
450
+ */
451
+ public void resumePlayingMarked () {
452
+ ArrayList <AudioPlayer > remove = new ArrayList <AudioPlayer >();
453
+ for (AudioPlayer audio : this .paused ) {
454
+ if (audio .isPlayAudioWhenScreenIsLocked ()){
455
+ audio .resumePlaying ();
456
+ remove .add (audio );
457
+ }
458
+ }
459
+ paused .removeAll (remove );
460
+ }
461
+
462
+
463
+
419
464
/**
420
465
* Get the the audio focus
421
466
*/
@@ -425,10 +470,18 @@ public void onAudioFocusChange(int focusChange) {
425
470
case (AudioManager .AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK ) :
426
471
case (AudioManager .AUDIOFOCUS_LOSS_TRANSIENT ) :
427
472
case (AudioManager .AUDIOFOCUS_LOSS ) :
428
- pauseAllLostFocus ();
473
+ pauseAll ();
474
+ audioFocusLost = true ;
429
475
break ;
430
476
case (AudioManager .AUDIOFOCUS_GAIN ):
431
- resumeAllGainedFocus ();
477
+ if (!calling ) {
478
+ if (activityFocusLost ){
479
+ resumePlayingMarked ();
480
+ }else {
481
+ resumePlayingAll ();
482
+ }
483
+ }
484
+ audioFocusLost = false ;
432
485
break ;
433
486
default :
434
487
break ;
@@ -553,6 +606,22 @@ else if(PermissionHelper.hasPermission(this, permissions[RECORD_AUDIO]))
553
606
554
607
}
555
608
609
+ @ Override
610
+ public void onResume (boolean multitasking ) {
611
+ super .onResume (multitasking );
612
+ if (!(audioFocusLost ||calling )) {
613
+ resumePlayingAll ();
614
+ }
615
+ activityFocusLost = false ;
616
+ }
617
+
618
+ @ Override
619
+ public void onPause (boolean multitasking ) {
620
+ activityFocusLost = true ;
621
+ pauseAudiosNotMarked ();
622
+ super .onPause (multitasking );
623
+ }
624
+
556
625
/**
557
626
* Get current amplitude of recording.
558
627
* @param id The id of the audio player
0 commit comments