23
23
import android .content .BroadcastReceiver ;
24
24
import android .content .pm .PackageManager ;
25
25
import android .media .AudioAttributes ;
26
- import android .media .AudioManager ;
27
- import androidx .media .AudioAttributesCompat ;
28
- import androidx .media .AudioManagerCompat ;
29
- import androidx .media .AudioFocusRequestCompat ;
30
26
import android .media .AudioDeviceInfo ;
27
+ import android .media .AudioFocusRequest ;
28
+ import android .media .AudioManager ;
31
29
import android .media .MediaPlayer ;
32
30
import android .media .ToneGenerator ;
33
31
import android .net .Uri ;
37
35
import android .os .Looper ;
38
36
import android .provider .Settings ;
39
37
import androidx .annotation .Nullable ;
40
- import androidx .core .app .ActivityCompat ;
41
- import androidx .core .content .ContextCompat ;
42
38
import android .util .Log ;
43
39
import android .util .SparseArray ;
44
40
import android .view .Display ;
@@ -83,6 +79,7 @@ public class InCallManagerModule extends ReactContextBaseJavaModule implements L
83
79
private AudioManager audioManager ;
84
80
private boolean audioManagerActivated = false ;
85
81
private boolean isAudioFocused = false ;
82
+ //private final Object mAudioFocusLock = new Object();
86
83
private boolean isOrigAudioSetupStored = false ;
87
84
private boolean origIsSpeakerPhoneOn = false ;
88
85
private boolean origIsMicrophoneMute = false ;
@@ -98,6 +95,8 @@ public class InCallManagerModule extends ReactContextBaseJavaModule implements L
98
95
private BroadcastReceiver noisyAudioReceiver ;
99
96
private BroadcastReceiver mediaButtonReceiver ;
100
97
private OnFocusChangeListener mOnFocusChangeListener ;
98
+ private AudioAttributes mAudioAttributes ;
99
+ private AudioFocusRequest mAudioFocusRequest ;
101
100
102
101
// --- same as: RingtoneManager.getActualDefaultRingtoneUri(reactContext, RingtoneManager.TYPE_RINGTONE);
103
102
private Uri defaultRingtoneUri = Settings .System .DEFAULT_RINGTONE_URI ;
@@ -454,6 +453,7 @@ public void stopProximitySensor() {
454
453
}
455
454
456
455
private class OnFocusChangeListener implements AudioManager .OnAudioFocusChangeListener {
456
+ // --- see: https://developer.android.com/reference/android/media/AudioManager
457
457
458
458
@ Override
459
459
public void onAudioFocusChange (final int focusChange ) {
@@ -480,6 +480,9 @@ public void onAudioFocusChange(final int focusChange) {
480
480
case AudioManager .AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK :
481
481
focusChangeStr = "AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK" ;
482
482
break ;
483
+ case AudioManager .AUDIOFOCUS_NONE :
484
+ focusChangeStr = "AUDIOFOCUS_NONE" ;
485
+ break ;
483
486
default :
484
487
focusChangeStr = "AUDIOFOCUS_UNKNOW" ;
485
488
break ;
@@ -612,7 +615,7 @@ public void stop(final String busytoneUriType) {
612
615
forceSpeakerOn = 0 ;
613
616
bluetoothManager .stop ();
614
617
restoreOriginalAudioSetup ();
615
- releaseAudioFocus ();
618
+ abandonAudioFocus ();
616
619
audioManagerActivated = false ;
617
620
}
618
621
wakeLockUtils .releasePartialWakeLock ();
@@ -637,23 +640,66 @@ private void stopEvents() {
637
640
}
638
641
639
642
private void requestAudioFocus () {
640
- if (!isAudioFocused ) {
641
- int result = audioManager .requestAudioFocus (mOnFocusChangeListener , AudioManager .STREAM_VOICE_CALL , AudioManager .AUDIOFOCUS_GAIN );
642
- if (result == AudioManager .AUDIOFOCUS_REQUEST_GRANTED ) {
643
- Log .d (TAG , "AudioFocus granted" );
643
+ if (isAudioFocused ) {
644
+ return ;
645
+ }
646
+
647
+ if (mAudioAttributes == null ) {
648
+ mAudioAttributes = new AudioAttributes .Builder ()
649
+ .setUsage (AudioAttributes .USAGE_VOICE_COMMUNICATION )
650
+ .setContentType (AudioAttributes .CONTENT_TYPE_SPEECH )
651
+ .build ();
652
+ }
653
+
654
+ if (mAudioFocusRequest == null ) {
655
+ mAudioFocusRequest = new AudioFocusRequest .Builder (AudioManager .AUDIOFOCUS_GAIN_TRANSIENT )
656
+ .setAudioAttributes (mAudioAttributes )
657
+ .setAcceptsDelayedFocusGain (false )
658
+ .setWillPauseWhenDucked (false )
659
+ .setOnAudioFocusChangeListener (mOnFocusChangeListener )
660
+ .build ();
661
+ }
662
+
663
+ int requestAudioFocusRes = audioManager .requestAudioFocus (mAudioFocusRequest );
664
+ String requestAudioFocusResStr ;
665
+ switch (requestAudioFocusRes ) {
666
+ case AudioManager .AUDIOFOCUS_REQUEST_FAILED :
667
+ requestAudioFocusResStr = "AUDIOFOCUS_REQUEST_FAILED" ;
668
+ break ;
669
+ case AudioManager .AUDIOFOCUS_REQUEST_GRANTED :
644
670
isAudioFocused = true ;
645
- } else if (result == AudioManager .AUDIOFOCUS_REQUEST_FAILED ) {
646
- Log .d (TAG , "AudioFocus failed" );
647
- isAudioFocused = false ;
648
- }
671
+ requestAudioFocusResStr = "AUDIOFOCUS_REQUEST_GRANTED" ;
672
+ break ;
673
+ case AudioManager .AUDIOFOCUS_REQUEST_DELAYED :
674
+ requestAudioFocusResStr = "AUDIOFOCUS_REQUEST_DELAYED" ;
675
+ break ;
676
+ default :
677
+ requestAudioFocusResStr = "AUDIOFOCUS_REQUEST_UNKNOWN" ;
678
+ break ;
649
679
}
680
+ Log .d (TAG , "requestAudioFocus(): res = " + requestAudioFocusRes + " - " + requestAudioFocusResStr );
650
681
}
651
682
652
- private void releaseAudioFocus () {
653
- if (isAudioFocused ) {
654
- audioManager .abandonAudioFocus (null );
655
- isAudioFocused = false ;
683
+ private void abandonAudioFocus () {
684
+ if (!isAudioFocused || mAudioFocusRequest == null ) {
685
+ return ;
686
+ }
687
+
688
+ int abandonAudioFocusRes = audioManager .abandonAudioFocusRequest (mAudioFocusRequest );
689
+ String abandonAudioFocusResStr ;
690
+ switch (abandonAudioFocusRes ) {
691
+ case AudioManager .AUDIOFOCUS_REQUEST_FAILED :
692
+ abandonAudioFocusResStr = "AUDIOFOCUS_REQUEST_FAILED" ;
693
+ break ;
694
+ case AudioManager .AUDIOFOCUS_REQUEST_GRANTED :
695
+ isAudioFocused = false ;
696
+ abandonAudioFocusResStr = "AUDIOFOCUS_REQUEST_GRANTED" ;
697
+ break ;
698
+ default :
699
+ abandonAudioFocusResStr = "AUDIOFOCUS_REQUEST_UNKNOWN" ;
700
+ break ;
656
701
}
702
+ Log .d (TAG , "abandonAudioFocus(): res = " + abandonAudioFocusRes + " - " + abandonAudioFocusResStr );
657
703
}
658
704
659
705
@ ReactMethod
@@ -832,8 +878,8 @@ public void startRingback(final String ringbackUriType) {
832
878
//data.put("audioStream", AudioManager.STREAM_VOICE_CALL); // --- lagacy
833
879
// --- The ringback doesn't have to be a DTMF.
834
880
// --- Should use VOICE_COMMUNICATION for sound during call or it may be silenced.
835
- data .put ("audioUsage" , AudioAttributesCompat .USAGE_VOICE_COMMUNICATION );
836
- data .put ("audioContentType" , AudioAttributesCompat .CONTENT_TYPE_MUSIC );
881
+ data .put ("audioUsage" , AudioAttributes .USAGE_VOICE_COMMUNICATION );
882
+ data .put ("audioContentType" , AudioAttributes .CONTENT_TYPE_MUSIC );
837
883
838
884
setMediaPlayerEvents ((MediaPlayer )mRingback , "mRingback" );
839
885
@@ -899,8 +945,8 @@ public boolean startBusytone(final String busytoneUriType) {
899
945
data .put ("setLooping" , false );
900
946
//data.put("audioStream", AudioManager.STREAM_VOICE_CALL); // --- lagacy
901
947
// --- Should use VOICE_COMMUNICATION for sound during a call or it may be silenced.
902
- data .put ("audioUsage" , AudioAttributesCompat .USAGE_VOICE_COMMUNICATION );
903
- data .put ("audioContentType" , AudioAttributesCompat .CONTENT_TYPE_SONIFICATION ); // --- CONTENT_TYPE_MUSIC?
948
+ data .put ("audioUsage" , AudioAttributes .USAGE_VOICE_COMMUNICATION );
949
+ data .put ("audioContentType" , AudioAttributes .CONTENT_TYPE_SONIFICATION ); // --- CONTENT_TYPE_MUSIC?
904
950
905
951
setMediaPlayerEvents ((MediaPlayer )mBusytone , "mBusytone" );
906
952
mBusytone .startPlay (data );
@@ -969,8 +1015,8 @@ public void run() {
969
1015
data .put ("setLooping" , true );
970
1016
971
1017
//data.put("audioStream", AudioManager.STREAM_RING); // --- lagacy
972
- data .put ("audioUsage" , AudioAttributesCompat .USAGE_NOTIFICATION_RINGTONE ); // --- USAGE_NOTIFICATION_COMMUNICATION_REQUEST?
973
- data .put ("audioContentType" , AudioAttributesCompat .CONTENT_TYPE_MUSIC );
1018
+ data .put ("audioUsage" , AudioAttributes .USAGE_NOTIFICATION_RINGTONE ); // --- USAGE_NOTIFICATION_COMMUNICATION_REQUEST?
1019
+ data .put ("audioContentType" , AudioAttributes .CONTENT_TYPE_MUSIC );
974
1020
975
1021
setMediaPlayerEvents ((MediaPlayer ) mRingtone , "mRingtone" );
976
1022
0 commit comments