|
@@ -57,7 +57,7 @@ import java.util.Set;
|
57
|
57
|
* Before a call has started and after it has ended the
|
58
|
58
|
* {@code AudioModeModule.DEFAULT} mode should be used.
|
59
|
59
|
*/
|
60
|
|
-class AudioModeModule extends ReactContextBaseJavaModule {
|
|
60
|
+class AudioModeModule extends ReactContextBaseJavaModule implements AudioManager.OnAudioFocusChangeListener {
|
61
|
61
|
/**
|
62
|
62
|
* Constants representing the audio mode.
|
63
|
63
|
* - DEFAULT: Used before and after every call. It represents the default
|
|
@@ -97,6 +97,11 @@ class AudioModeModule extends ReactContextBaseJavaModule {
|
97
|
97
|
*/
|
98
|
98
|
static final String TAG = MODULE_NAME;
|
99
|
99
|
|
|
100
|
+ /**
|
|
101
|
+ * Indicator that we have lost audio focus.
|
|
102
|
+ */
|
|
103
|
+ private boolean audioFocusLost = false;
|
|
104
|
+
|
100
|
105
|
/**
|
101
|
106
|
* {@link AudioManager} instance used to interact with the Android audio
|
102
|
107
|
* subsystem.
|
|
@@ -345,6 +350,36 @@ class AudioModeModule extends ReactContextBaseJavaModule {
|
345
|
350
|
});
|
346
|
351
|
}
|
347
|
352
|
|
|
353
|
+ /**
|
|
354
|
+ * {@link AudioManager.OnAudioFocusChangeListener} interface method. Called
|
|
355
|
+ * when the audio focus of the system is updated.
|
|
356
|
+ *
|
|
357
|
+ * @param focusChange - The type of focus change.
|
|
358
|
+ */
|
|
359
|
+ @Override
|
|
360
|
+ public void onAudioFocusChange(int focusChange) {
|
|
361
|
+ switch (focusChange) {
|
|
362
|
+ case AudioManager.AUDIOFOCUS_GAIN: {
|
|
363
|
+ Log.d(TAG, "Audio focus gained");
|
|
364
|
+ // Some other application potentially stole our audio focus
|
|
365
|
+ // temporarily. Restore our mode.
|
|
366
|
+ if (audioFocusLost) {
|
|
367
|
+ updateAudioRoute(mode);
|
|
368
|
+ }
|
|
369
|
+ audioFocusLost = false;
|
|
370
|
+ break;
|
|
371
|
+ }
|
|
372
|
+ case AudioManager.AUDIOFOCUS_LOSS:
|
|
373
|
+ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
|
|
374
|
+ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: {
|
|
375
|
+ Log.d(TAG, "Audio focus lost");
|
|
376
|
+ audioFocusLost = true;
|
|
377
|
+ break;
|
|
378
|
+ }
|
|
379
|
+
|
|
380
|
+ }
|
|
381
|
+ }
|
|
382
|
+
|
348
|
383
|
/**
|
349
|
384
|
* Sets the user selected audio device as the active audio device.
|
350
|
385
|
*
|
|
@@ -495,8 +530,9 @@ class AudioModeModule extends ReactContextBaseJavaModule {
|
495
|
530
|
Log.d(TAG, "Update audio route for mode: " + mode);
|
496
|
531
|
|
497
|
532
|
if (mode == DEFAULT) {
|
|
533
|
+ audioFocusLost = false;
|
498
|
534
|
audioManager.setMode(AudioManager.MODE_NORMAL);
|
499
|
|
- audioManager.abandonAudioFocus(null);
|
|
535
|
+ audioManager.abandonAudioFocus(this);
|
500
|
536
|
audioManager.setSpeakerphoneOn(false);
|
501
|
537
|
setBluetoothAudioRoute(false);
|
502
|
538
|
selectedDevice = null;
|
|
@@ -509,7 +545,7 @@ class AudioModeModule extends ReactContextBaseJavaModule {
|
509
|
545
|
audioManager.setMicrophoneMute(false);
|
510
|
546
|
|
511
|
547
|
if (audioManager.requestAudioFocus(
|
512
|
|
- null,
|
|
548
|
+ this,
|
513
|
549
|
AudioManager.STREAM_VOICE_CALL,
|
514
|
550
|
AudioManager.AUDIOFOCUS_GAIN)
|
515
|
551
|
== AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
|