Reputation: 1171
Same as this question and many others from a few years ago: how to turn speaker on/off programmatically in android 4.0
It seems that Android has changed the way it handles this.
Here are the things I tried to make an outgoing call to have a speakerphone programmatically. None of these solutions worked for me on Android Pie, while they seem to work well on Android Nougat and Oreo.
Solution 1.
final static int FOR_MEDIA = 1;
final static int FORCE_NONE = 0;
final static int FORCE_SPEAKER = 1;
Class audioSystemClass = Class.forName("android.media.AudioSystem");
Method setForceUse = audioSystemClass.getMethod("setForceUse", int.class, int.class);
setForceUse.invoke(null, FOR_MEDIA, FORCE_SPEAKER);
AudioManager audioManager = (AudioManager)getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
if (audioManager != null) {
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
audioManager.setSpeakerphoneOn(true);
AudioManager audioManager = (AudioManager)getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
if (audioManager != null) {
audioManager.setMode(AudioManager.MODE_IN_CALL);
audioManager.setSpeakerphoneOn(true);
Thread thread = new Thread() {
@Override
public void run() {
try {
while(true) {
sleep(1000);
audioManager.setMode(AudioManager.MODE_IN_CALL);
if (!audioManager.isSpeakerphoneOn())
audioManager.setSpeakerphoneOn(true);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
The app has the following permissions granted among many others:
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
I have also tried the following solution only for outgoing calls. and it also didn't work.
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.putExtra("speaker", true);
callIntent.setData(Uri.parse("tel:" + number));
context.startActivity(callIntent);
Upvotes: 15
Views: 5949
Reputation: 5943
in my self managed voice calling app I managed by changing connection service audio route like below beside using audioManager,
public void setSpeakerphoneOn(final boolean enabled) {
if (enabled != audioManager.isSpeakerphoneOn()) {
Log.d(TAG, "setSpeakerphoneOn(): " + enabled);
audioManager.setSpeakerphoneOn(enabled);
}
}
and in my connectionservice class,
public void speakerOnOff(String uuid,boolean on) {
Log.d(TAG,"SPEAKER is" + String.valueOf(on));
Connection connection = VoipConnectionService.getConnection(uuid);
if (on) {
connection.setAudioRoute(CallAudioState.ROUTE_SPEAKER);
} else {
connection.setAudioRoute(CallAudioState.ROUTE_EARPIECE);
}
}
or you can change route according to your audio device for output
public void speakerOnOff(String uuid,String device) {
Log.d(TAG,"Device to route is" + device);
Connection connection = VoipConnectionService.getConnection(uuid);
int state = CallAudioState.ROUTE_EARPIECE ;
switch (device){
case "SPEAKER_PHONE":
state = CallAudioState.ROUTE_SPEAKER ;
break;
case "WIRED_HEADSET":
state = CallAudioState.ROUTE_WIRED_HEADSET ;
break;
case "EARPIECE" :
case "NONE" :
state = CallAudioState.ROUTE_EARPIECE ;
break;
case "BLUETOOTH" :
state = CallAudioState.ROUTE_BLUETOOTH ;
break;
}
connection.setAudioRoute(state);
}
Upvotes: 0
Reputation: 190
I am surprised nobody mentioned TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE.
As an intent:
val uri = Uri.fromParts("tel", PHONE_NUMBER, null)
val intentCall = Intent(Intent.ACTION_CALL, uri).apply {
putExtra(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, true)
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
startActivity(intentCall)
Using TelecomManager.placeCall:
val uri = Uri.fromParts("tel", PHONE_NUMBER, null)
val extras = Bundle().apply { putBoolean(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, true) }
val telecomManager = getSystemService(TELECOM_SERVICE) as TelecomManager
telecomManager.placeCall(uri, extras)
The default phone app should handle that extra data and enable the speakers.
Remember to ask for android.permission.CALL_PHONE
permission.
Upvotes: 7
Reputation: 413
In Android Pie, I had the same problem. I resolved it using an InCallService with
setAudioRoute(ROUTE_SPEAKER)
Your app needs to be Default phone app.
Upvotes: 6
Reputation: 48
For this problem please try the following code it is working for me.
AudioManager myAudioManager;
myAudioManager.setMode(AudioManager.MODE_NORMAL);
myAudioManager.setSpeakerphoneOn(true);
Upvotes: -2