Skip to content

Commit 82980e7

Browse files
committed
Merge branch 'trials/mode_in_communication'
* trials/mode_in_communication: Untested. Overhaul how changing and restoring speaker modes is done. Change where and how often we request and surrender audio focus. Restore audio stream mode when player loses audio focus (jar not included) Switch from MODE_IN_CALL to MODE_IN_COMMUNICATION
2 parents 630b509 + 8f66006 commit 82980e7

2 files changed

Lines changed: 129 additions & 46 deletions

File tree

964 Bytes
Binary file not shown.

android/src/com/kcwdev/audio/MediaPlayerWrapper.java

Lines changed: 129 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import android.content.Context;
1818
import android.content.res.AssetFileDescriptor;
1919
import android.media.AudioManager;
20+
import android.media.AudioManager.OnAudioFocusChangeListener;
2021
import android.media.MediaPlayer;
2122
import android.net.Uri;
2223
import android.webkit.URLUtil;
@@ -63,6 +64,8 @@ public class MediaPlayerWrapper
6364

6465
protected KrollProxy proxy;
6566
protected MediaPlayer mp;
67+
protected AudioManager am;
68+
protected Context context;
6669
protected float volume;
6770
protected boolean speakerphone;
6871
protected boolean playOnResume;
@@ -79,6 +82,9 @@ public MediaPlayerWrapper(KrollProxy proxy) throws IOException
7982
{
8083
this.initialize();
8184
}
85+
86+
context = proxy.getActivity().getBaseContext();
87+
am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
8288
}
8389

8490
protected void initialize()
@@ -89,7 +95,6 @@ protected void initialize()
8995
mp = new MediaPlayer();
9096
String url = TiConvert.toString(proxy.getProperty(TiC.PROPERTY_URL));
9197
if (URLUtil.isAssetUrl(url)) {
92-
Context context = proxy.getActivity().getApplicationContext();
9398
String path = url.substring(TiConvert.ASSET_URL.length());
9499
AssetFileDescriptor afd = null;
95100
try {
@@ -179,6 +184,8 @@ public void pause()
179184
{
180185
try {
181186
if (mp != null) {
187+
am.setMode(AudioManager.USE_DEFAULT_STREAM_TYPE);
188+
am.setSpeakerphoneOn(true);
182189
if(mp.isPlaying()) {
183190
if (DBG) {
184191
Log.d(LCAT,"audio is playing, pause");
@@ -208,6 +215,46 @@ public void play()
208215
if (DBG) {
209216
Log.d(LCAT, "Play: Volume set to " + volume);
210217
}
218+
219+
OnAudioFocusChangeListener focusChangeListener =
220+
new OnAudioFocusChangeListener() {
221+
public void onAudioFocusChange(int focusChange) {
222+
switch (focusChange) {
223+
224+
case (AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) :
225+
// Lower the volume while ducking.
226+
mp.setVolume(0.2f, 0.2f);
227+
break;
228+
case (AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) :
229+
pause();
230+
break;
231+
232+
case (AudioManager.AUDIOFOCUS_LOSS) :
233+
stop();
234+
break;
235+
236+
case (AudioManager.AUDIOFOCUS_GAIN) :
237+
// Return the volume to normal and resume if paused.
238+
mp.setVolume(1f, 1f);
239+
play();
240+
break;
241+
242+
default:
243+
// Nothing
244+
break;
245+
}
246+
}
247+
};
248+
249+
am.requestAudioFocus(focusChangeListener, (speakerphone) ? AudioManager.STREAM_MUSIC : AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN);
250+
251+
if(!speakerphone) {
252+
am.setMode(AudioManager.STREAM_VOICE_CALL);
253+
am.setSpeakerphoneOn(false);
254+
} else {
255+
am.setSpeakerphoneOn(true);
256+
}
257+
211258
mp.start();
212259
setState(STATE_PLAYING);
213260
paused = false;
@@ -259,8 +306,6 @@ public void release()
259306
* Restore default stream type
260307
*/
261308
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.KITKAT) {
262-
Context context = proxy.getActivity().getBaseContext();
263-
AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
264309
am.setMode(AudioManager.USE_DEFAULT_STREAM_TYPE);
265310
am.setSpeakerphoneOn(true);
266311
}
@@ -353,31 +398,30 @@ public void setTime(int position)
353398
proxy.setProperty(TiC.PROPERTY_TIME, position);
354399
}
355400

401+
/**
402+
* Sets the speaker mode. This can only be called once per instance of the player (i.e. when
403+
* it is initializing).
404+
*/
356405
public void setSpeakerphoneOn() {
357406
if (mp != null) {
358407

359-
Context context = proxy.getActivity().getBaseContext();
360-
AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
361-
362408
speakerphone = true;
363409
if(proxy.hasProperty("speakerphone")) {
364410
speakerphone = TiConvert.toBoolean(proxy.getProperty("speakerphone"));
365411
}
366412

367-
if(speakerphone) {
413+
if(speakerphone)
414+
{
368415
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
369-
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.KITKAT) {
370-
am.setMode(AudioManager.STREAM_MUSIC);
371-
am.setSpeakerphoneOn(true);
372-
}
373-
374-
} else {
416+
am.setMode(AudioManager.USE_DEFAULT_STREAM_TYPE);
417+
am.setSpeakerphoneOn(true);
418+
}
419+
420+
else
421+
{
375422
mp.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
376-
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.KITKAT) {
377-
am.setMode(AudioManager.MODE_IN_CALL);
378-
am.setSpeakerphoneOn(false);
379-
}
380-
423+
am.setMode(AudioManager.STREAM_VOICE_CALL);
424+
am.setSpeakerphoneOn(false);
381425
}
382426
}
383427
}
@@ -387,7 +431,8 @@ private void setState(int state)
387431
proxy.setProperty("state", state);
388432
String stateDescription = "";
389433

390-
switch(state) {
434+
switch(state)
435+
{
391436
case STATE_BUFFERING :
392437
stateDescription = STATE_BUFFERING_DESC;
393438
break;
@@ -418,7 +463,8 @@ private void setState(int state)
418463
}
419464

420465
proxy.setProperty("stateDescription", stateDescription);
421-
if (DBG) {
466+
if (DBG)
467+
{
422468
Log.d(LCAT, "Audio state changed: " + stateDescription);
423469
}
424470

@@ -431,33 +477,49 @@ private void setState(int state)
431477

432478
public void stop()
433479
{
434-
try {
435-
if (mp != null) {
480+
try
481+
{
482+
if (mp != null)
483+
{
436484

437-
if (mp.isPlaying() || isPaused()) {
438-
if (DBG) {
485+
if (mp.isPlaying() || isPaused())
486+
{
487+
if (DBG)
488+
{
439489
Log.d(LCAT, "audio is playing, stop()");
440490
}
441491
setState(STATE_STOPPING);
442492
mp.stop();
493+
494+
am.setMode(AudioManager.USE_DEFAULT_STREAM_TYPE);
495+
am.setSpeakerphoneOn(true);
496+
443497
setState(STATE_STOPPED);
444498
//if (remote) {
445499
stopProgressTimer();
446500
//}
447-
try {
501+
try
502+
{
448503
mp.prepare();
449-
} catch (IOException e) {
504+
}
505+
catch (IOException e)
506+
{
450507
Log.e(LCAT,"Error while preparing audio after stop(). Ignoring.");
451-
} catch (IllegalStateException e) {
508+
}
509+
catch (IllegalStateException e)
510+
{
452511
Log.w(LCAT, "Error while preparing audio after stop(). Ignoring.");
453512
}
454513
}
455514

456-
if(isPaused()) {
515+
if(isPaused())
516+
{
457517
paused = false;
458518
}
459519
}
460-
} catch (Throwable t) {
520+
}
521+
catch (Throwable t)
522+
{
461523
Log.e(LCAT, "Error : " , t);
462524
}
463525
}
@@ -466,6 +528,8 @@ public void stop()
466528
public void onCompletion(MediaPlayer mp)
467529
{
468530
proxy.fireEvent(EVENT_COMPLETE, null);
531+
am.setMode(AudioManager.USE_DEFAULT_STREAM_TYPE);
532+
am.setSpeakerphoneOn(true);
469533
stop();
470534
}
471535

@@ -474,7 +538,8 @@ public boolean onInfo(MediaPlayer mp, int what, int extra)
474538
{
475539
String msg = "OnInfo Unknown media issue.";
476540

477-
switch(what) {
541+
switch(what)
542+
{
478543
case MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING :
479544
msg = "Stream not interleaved or interleaved improperly.";
480545
break;
@@ -506,7 +571,8 @@ public boolean onError(MediaPlayer mp, int what, int extra)
506571
{
507572
int code = 0;
508573
String msg = "Unknown media error.";
509-
if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
574+
if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED)
575+
{
510576
msg = "Media server died";
511577
}
512578
release();
@@ -522,7 +588,8 @@ public boolean onError(MediaPlayer mp, int what, int extra)
522588
@Override
523589
public void onBufferingUpdate(MediaPlayer mp, int percent)
524590
{
525-
if (DBG) {
591+
if (DBG)
592+
{
526593
Log.d(LCAT, "Buffering: " + percent + "%");
527594
}
528595

@@ -531,31 +598,41 @@ public void onBufferingUpdate(MediaPlayer mp, int percent)
531598
proxy.fireEvent(EVENT_BUFFERING, data);
532599
}
533600

534-
public int getCurrentPosition() {
535-
if (mp != null) {
601+
public int getCurrentPosition()
602+
{
603+
if (mp != null)
604+
{
536605
return mp.getCurrentPosition();
537-
} else {
606+
}
607+
else
608+
{
538609
return 0;
539610
}
540611
}
541612

542613

543614
private void startProgressTimer()
544615
{
545-
if (progressTimer == null) {
616+
if (progressTimer == null)
617+
{
546618
progressTimer = new Timer(true);
547-
} else {
619+
}
620+
else
621+
{
548622
progressTimer.cancel();
549623
progressTimer = new Timer(true);
550624
}
551625

552626
progressTimer.schedule(new TimerTask()
553627
{
554628
@Override
555-
public void run() {
556-
if (mp != null && mp.isPlaying()) {
629+
public void run()
630+
{
631+
if (mp != null && mp.isPlaying())
632+
{
557633
int position = mp.getCurrentPosition();
558-
if (DBG) {
634+
if (DBG)
635+
{
559636
Log.d(LCAT, "Progress: " + position);
560637
}
561638
KrollDict event = new KrollDict();
@@ -568,15 +645,17 @@ public void run() {
568645

569646
private void stopProgressTimer()
570647
{
571-
if (progressTimer != null) {
648+
if (progressTimer != null)
649+
{
572650
progressTimer.cancel();
573651
progressTimer = null;
574652
}
575653
}
576654

577655
public void onDestroy()
578656
{
579-
if (mp != null) {
657+
if (mp != null)
658+
{
580659
mp.release();
581660
mp = null;
582661
}
@@ -585,8 +664,10 @@ public void onDestroy()
585664

586665
public void onPause()
587666
{
588-
if (mp != null) {
589-
if (isPlaying()) {
667+
if (mp != null)
668+
{
669+
if (isPlaying())
670+
{
590671
pause();
591672
playOnResume = true;
592673
}
@@ -595,8 +676,10 @@ public void onPause()
595676

596677
public void onResume()
597678
{
598-
if (mp != null) {
599-
if (playOnResume) {
679+
if (mp != null)
680+
{
681+
if (playOnResume)
682+
{
600683
play();
601684
playOnResume = false;
602685
}

0 commit comments

Comments
 (0)