Created
December 21, 2019 09:42
-
-
Save mohsenk/ced7528bc5b0ec81d17269deb8364a2b to your computer and use it in GitHub Desktop.
Homa App Call Activity
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package mobi.homa.app.activities; | |
import android.Manifest; | |
import android.app.Activity; | |
import android.content.Intent; | |
import android.content.pm.PackageManager; | |
import android.media.RingtoneManager; | |
import android.net.Uri; | |
import android.os.Bundle; | |
import android.support.v4.app.ActivityCompat; | |
import android.support.v4.content.ContextCompat; | |
import android.util.Log; | |
import android.view.View; | |
import android.view.Window; | |
import android.view.WindowManager; | |
import android.widget.ImageButton; | |
import android.widget.ImageView; | |
import android.widget.TextView; | |
import android.widget.Toast; | |
import com.google.gson.JsonParser; | |
import com.squareup.picasso.Picasso; | |
import org.apache.commons.lang3.StringUtils; | |
import org.threeten.bp.LocalTime; | |
import org.threeten.bp.format.DateTimeFormatter; | |
import org.webrtc.PeerConnection; | |
import java.text.SimpleDateFormat; | |
import java.util.Timer; | |
import java.util.TimerTask; | |
import io.kavenegar.sdk.call.enums.Environment; | |
import io.kavenegar.sdk.call.log.DefaultLogger; | |
import io.kavenegar.sdk.call.log.RemoteLogger; | |
import mobi.homa.app.MyApplication; | |
import mobi.homa.app.R; | |
import mobi.homa.app.audio.HomaAudioManager; | |
import mobi.homa.app.utils.CircleTransform; | |
import mobi.homa.app.utils.TimeUtils; | |
import io.kavenegar.sdk.call.Call; | |
import io.kavenegar.sdk.call.CallEventListener; | |
import io.kavenegar.sdk.call.KavenegarCall; | |
import io.kavenegar.sdk.call.core.JoinCallback; | |
import io.kavenegar.sdk.call.core.KavenegarException; | |
import io.kavenegar.sdk.call.enums.CallDirection; | |
import io.kavenegar.sdk.call.enums.CallFinishedReason; | |
import io.kavenegar.sdk.call.enums.CallStatus; | |
import io.kavenegar.sdk.call.enums.JoinStatus; | |
import io.kavenegar.sdk.call.enums.MediaState; | |
import io.kavenegar.sdk.call.enums.MessagingState; | |
import io.kavenegar.sdk.call.log.Logger; | |
import io.kavenegar.sdk.call.messaging.MediaStateChangedEvent; | |
import io.kavenegar.sdk.call.messaging.MessagingStateChangedEvent; | |
import io.kavenegar.sdk.call.webrtc.models.LocalMediaStateChangedEvent; | |
/** | |
* Created by mohsen on 2/27/2018 AD. | |
*/ | |
public class CallActivity extends Activity implements CallEventListener, JoinCallback { | |
static final String TAG = "CallActivity"; | |
TextView statusText; | |
TextView usernameText; | |
ImageButton acceptButton; | |
ImageButton rejectButton; | |
ImageButton hangupButton; | |
ImageButton speakerButton; | |
ImageButton muteButton; | |
ImageView avatarImage; | |
HomaAudioManager audioManager; | |
Call nativeCall; | |
mobi.homa.app.models.Call call; | |
Logger logger; | |
Timer timer = new Timer(); | |
CallFinishedReason endType; | |
TextView mediaStatusText; | |
TextView remoteMediaStatusText; | |
TextView messagingStatusText; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
try { | |
super.onCreate(savedInstanceState); | |
getWindow().requestFeature(Window.FEATURE_NO_TITLE); | |
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); | |
setContentView(R.layout.activity_call); | |
hangupButton = findViewById(R.id.hangup_button); | |
statusText = findViewById(R.id.status_text); | |
usernameText = findViewById(R.id.username_text); | |
acceptButton = findViewById(R.id.accept_button); | |
rejectButton = findViewById(R.id.reject_button); | |
speakerButton = findViewById(R.id.speaker_button); | |
muteButton = findViewById(R.id.mute_button); | |
avatarImage = findViewById(R.id.avatar_image); | |
mediaStatusText = findViewById(R.id.media_status_text); | |
messagingStatusText = findViewById(R.id.messaging_status_text); | |
remoteMediaStatusText = findViewById(R.id.remote_media_status_text); | |
acceptButton.setOnClickListener(view -> acceptClick()); | |
rejectButton.setOnClickListener(view -> rejectClick()); | |
hangupButton.setOnClickListener(view -> hangupClick()); | |
speakerButton.setEnabled(false); | |
muteButton.setEnabled(false); | |
speakerButton.setOnClickListener(view -> speakerClick()); | |
muteButton.setOnClickListener(view -> muteClick()); | |
audioManager = new HomaAudioManager(this, R.raw.connected, R.raw.disconnected); | |
this.setInitUI(); | |
if (!hasAudioPermission()) { | |
requestAudioPermission(); | |
} else { | |
this.start(); | |
} | |
if (!hasReadPhoneStatePermission()) { | |
requestReadPhoneStatePermission(); | |
} | |
if (KavenegarCall.getInstance().getEnvironment() == Environment.PRODUCTION) { | |
// mediaStatusText.setVisibility(View.GONE); | |
// messagingStatusText.setVisibility(View.GONE); | |
// remoteMediaStatusText.setVisibility(View.GONE); | |
} | |
timer.schedule(new TimerTask() { | |
@Override | |
public void run() { | |
if (nativeCall != null && nativeCall.getStatus() == CallStatus.CONVERSATION) { | |
CallActivity.this.updateDuration(); | |
} | |
} | |
}, 0, 1000); | |
} catch (Exception ex) { | |
ex.printStackTrace(); | |
} | |
} | |
void updateDuration() { | |
runOnUiThread(() -> { | |
if (nativeCall.getStatus() == CallStatus.CONVERSATION && nativeCall.getCallerMediaState() == MediaState.CONNECTED && nativeCall.getReceptorMediaState() == MediaState.CONNECTED) { | |
LocalTime t = LocalTime.MIDNIGHT.plusSeconds(this.nativeCall.getDuration() / 1000); | |
String formatted = DateTimeFormatter.ofPattern("m:ss").format(t); | |
statusText.setText(formatted); | |
} | |
}); | |
} | |
public void start() { | |
try { | |
String accessToken = getIntent().getStringExtra("access_token"); | |
String callId = getIntent().getStringExtra("call_id"); | |
String callPayload = getIntent().getStringExtra("call"); | |
MyApplication.setCurrentCallId(callId); | |
Logger logger; | |
if (KavenegarCall.getInstance().getEnvironment() == Environment.PRODUCTION) { | |
logger = new DefaultLogger(); | |
} else { | |
//logger = new RemoteLogger(Log.INFO, callId, accessToken, Environment.DEVELOPMENT); | |
logger = new DefaultLogger(); | |
} | |
this.logger = logger; | |
KavenegarCall.getInstance().initCall(callId, accessToken, logger, this, this); | |
this.call = new mobi.homa.app.models.Call(new JsonParser().parse(callPayload).getAsJsonObject()); | |
} catch (Exception ex) { | |
logger.error(TAG, "Messaging start has exception ", ex); | |
} | |
} | |
@Override | |
public void onResult(JoinStatus status, Call call) { | |
runOnUiThread(() -> { | |
try { | |
if (status == JoinStatus.SUCCESS) { | |
try { | |
this.nativeCall = call; | |
call.setMessagingStateChangedHandler(this::messagingSateChanged); | |
call.setMediaStateChangedEventHandler(this::peerConnectionStateChanged); | |
audioManager.initializeAudioForCall(); | |
if (nativeCall.getDirection() == CallDirection.OUTBOUND) { | |
logger.info(TAG, "Call to " + nativeCall.getReceptor() + ", id : " + nativeCall.getId() + "==============================================================="); | |
initOutgoingCall(); | |
} else { | |
logger.info(TAG, "Receive call from : " + nativeCall.getCaller() + " , id : " + nativeCall.getId() + " ==============================================================="); | |
initIncomingCall(); | |
} | |
} catch (Exception ex) { | |
logger.error(TAG, "Messaging start callback", ex); | |
Toast.makeText(CallActivity.this, "Messaging start has error : " + ex.getLocalizedMessage(), Toast.LENGTH_LONG).show(); | |
this.endType = CallFinishedReason.UNKNOWN; | |
this.finish(); | |
} | |
} else { | |
Toast.makeText(CallActivity.this, "Messaging start result : " + status, Toast.LENGTH_LONG).show(); | |
logger.warn(TAG, "Messaging start result is not success : " + status.toString()); | |
this.endType = CallFinishedReason.UNKNOWN; | |
this.finish(); | |
} | |
} catch (Exception ex) { | |
logger.error(TAG, "Messaging start has exception ", ex); | |
} | |
}); | |
} | |
private void initIncomingCall() throws KavenegarException { | |
try { | |
statusText.setText("Incoming"); | |
this.nativeCall.ringing(); | |
usernameText.setText(call.getCaller().getFullName()); | |
loadAvatar(call.getCaller().getAvatarURL()); | |
Uri ringtone = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE); | |
audioManager.startIncomingRinger(ringtone, false); | |
} catch (Exception ex) { | |
logger.error(TAG, "", ex); | |
} | |
setAnswerUI(); | |
} | |
private void initOutgoingCall() { | |
try { | |
statusText.setText("Calling"); | |
usernameText.setText(call.getReceptor().getFullName()); | |
loadAvatar(call.getReceptor().getAvatarURL()); | |
setCallUI(); | |
Uri dataUri = Uri.parse("android.resource://" + this.getPackageName() + "/" + R.raw.outring); | |
audioManager.startOutgoingRinger(dataUri, false); | |
} catch (Exception ex) { | |
logger.error(TAG, "", ex); | |
} | |
} | |
void loadAvatar(String avatarURL) { | |
Picasso.get().load(avatarURL) | |
.placeholder(R.drawable.ic_user) | |
.error(R.drawable.ic_user) | |
.transform(new CircleTransform()).into(avatarImage); | |
} | |
// Kavenegar Call State Change Events ==================================================================== | |
private void peerConnectionStateChanged(LocalMediaStateChangedEvent event) { | |
this.runOnUiThread(() -> { | |
PeerConnection.IceConnectionState old = event.getOldState(); | |
PeerConnection.IceConnectionState current = event.getNewState(); | |
if ((old == PeerConnection.IceConnectionState.COMPLETED || old == PeerConnection.IceConnectionState.CONNECTED) && current == PeerConnection.IceConnectionState.DISCONNECTED) { | |
nativeCall.setStatus(CallStatus.PAUSED, true); | |
} | |
mediaStatusText.setText("Media: " + old.name().toLowerCase() + " => " + current.name().toLowerCase()); | |
}); | |
} | |
private void messagingSateChanged(MessagingStateChangedEvent event) { | |
this.runOnUiThread(() -> { | |
MessagingState old = event.getOldState(); | |
MessagingState current = event.getNewState(); | |
messagingStatusText.setText("Messaging: " + old.name().toLowerCase() + " => " + current.name().toLowerCase()); | |
}); | |
} | |
// UI Methods ============================================================================================ | |
public void setInitUI() { | |
acceptButton.setVisibility(View.GONE); | |
rejectButton.setVisibility(View.GONE); | |
hangupButton.setVisibility(View.GONE); | |
speakerButton.setVisibility(View.GONE); | |
muteButton.setVisibility(View.GONE); | |
} | |
public void setCallUI() { | |
speakerButton.setEnabled(true); | |
muteButton.setEnabled(true); | |
acceptButton.setVisibility(View.GONE); | |
rejectButton.setVisibility(View.GONE); | |
hangupButton.setVisibility(View.VISIBLE); | |
speakerButton.setVisibility(View.VISIBLE); | |
muteButton.setVisibility(View.VISIBLE); | |
} | |
public void setAnswerUI() { | |
speakerButton.setEnabled(true); | |
muteButton.setEnabled(true); | |
hangupButton.setVisibility(View.GONE); | |
acceptButton.setVisibility(View.VISIBLE); | |
rejectButton.setVisibility(View.VISIBLE); | |
speakerButton.setVisibility(View.VISIBLE); | |
muteButton.setVisibility(View.VISIBLE); | |
} | |
private void setCommunicationUI() { | |
speakerButton.setEnabled(true); | |
muteButton.setEnabled(true); | |
acceptButton.setVisibility(View.GONE); | |
rejectButton.setVisibility(View.GONE); | |
hangupButton.setVisibility(View.VISIBLE); | |
} | |
// UI Events ================================================================================================= | |
public void acceptClick() { | |
try { | |
this.nativeCall.accept(); | |
setCommunicationUI(); | |
} catch (Exception ex) { | |
logger.error(TAG, "", ex); | |
} | |
} | |
public void rejectClick() { | |
try { | |
this.nativeCall.reject(); | |
} catch (Exception ex) { | |
logger.error(TAG, "", ex); | |
} | |
} | |
public void hangupClick() { | |
try { | |
this.nativeCall.hangup(); | |
} catch (Exception ex) { | |
logger.error(TAG, "", ex); | |
} | |
} | |
public void muteClick() { | |
Uri dataUri = Uri.parse("android.resource://" + this.getPackageName() + "/" + R.raw.reconnecting); | |
if (audioManager.isMicrophoneMute()) { | |
audioManager.setMicrophoneMute(false); | |
muteButton.setBackground(ContextCompat.getDrawable(this, R.drawable.circle_button_with_border)); | |
} else { | |
audioManager.setMicrophoneMute(true); | |
muteButton.setBackground(ContextCompat.getDrawable(this, R.drawable.gray_button_background)); | |
} | |
} | |
public void speakerClick() { | |
if (audioManager.isSpeakerOn()) { | |
audioManager.setSpeakerOn(false); | |
speakerButton.setBackground(ContextCompat.getDrawable(this, R.drawable.circle_button_with_border)); | |
} else { | |
audioManager.setSpeakerOn(true); | |
speakerButton.setBackground(ContextCompat.getDrawable(this, R.drawable.gray_button_background)); | |
} | |
} | |
// ============================================================================================================== // | |
@Override | |
public void finish() { | |
if (this.nativeCall != null) { | |
try { | |
this.nativeCall.dispose(); | |
audioManager.stop(false); | |
} catch (Exception ex) { | |
logger.error(KavenegarCall.TAG, "Exception in dispose call", ex); | |
} | |
logger.info(TAG, "Finish call with id : " + nativeCall.getId()); | |
Intent returnIntent = new Intent(); | |
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); | |
returnIntent.putExtra("callerId", call.getCallerId()); | |
returnIntent.putExtra("receptorId", call.getReceptorId()); | |
returnIntent.putExtra("createdAt", TimeUtils.toISOFormat(call.getCreatedAt())); | |
returnIntent.putExtra("startedAt", nativeCall.getStartedAt() != null ? dateFormat.format(nativeCall.getStartedAt()) : ""); | |
returnIntent.putExtra("finishedAt", nativeCall.getFinishedAt() != null ? dateFormat.format(nativeCall.getFinishedAt()) : ""); | |
returnIntent.putExtra("endType", endType); | |
returnIntent.putExtra("remoteId", nativeCall.getId()); | |
returnIntent.putExtra("callId", call.getId()); | |
returnIntent.putExtra("duration", nativeCall.getDuration()); | |
setResult(200, returnIntent); | |
MyApplication.setCurrentCallId(null); | |
super.finish(); | |
} else { | |
super.finish(); | |
} | |
} | |
// Call events =============================================================================================== // | |
@Override | |
public void onMediaStateChanged(MediaStateChangedEvent event) { | |
runOnUiThread(() -> { | |
remoteMediaStatusText.setText("Caller Media =" + nativeCall.getCallerMediaState().toString() + " , Receptor Media =" + nativeCall.getReceptorMediaState().toString()); | |
// //Toast.makeText(this, event.toString(), Toast.LENGTH_LONG).show(); | |
// if (nativeCall.getStatus() == CallStatus.CONVERSATION && nativeCall.getCallerMediaState() == MediaState.CONNECTED && nativeCall.getReceptorMediaState() == MediaState.CONNECTED) { | |
// } | |
}); | |
} | |
@Override | |
public void onCallFinished(CallFinishedReason reason) { | |
logger.info(TAG, "Call finished with reason :" + reason.name()); | |
this.endType = reason; | |
this.finish(); | |
} | |
@Override | |
public void onCallStateChanged(CallStatus state, boolean isLocalChange) { | |
runOnUiThread(() -> { | |
setCallStatus(state); | |
switch (state) { | |
case NEW: { | |
break; | |
} | |
case TRYING: { | |
break; | |
} | |
case RINGING: { | |
break; | |
} | |
case ACCEPTED: { | |
audioManager.stop(false); | |
break; | |
} | |
case CONVERSATION: { | |
setCommunicationUI(); | |
audioManager.startCommunication(false); | |
break; | |
} | |
case PAUSED: { | |
Uri dataUri = Uri.parse("android.resource://" + this.getPackageName() + "/" + R.raw.reconnecting); | |
audioManager.startBeepRinger(dataUri, false); | |
} | |
case FINISHED: { | |
break; | |
} | |
} | |
}); | |
} | |
void setCallStatus(CallStatus status) { | |
String text = ""; | |
switch (status) { | |
case TRYING: { | |
break; | |
} | |
case RINGING: { | |
text = "Ringing"; | |
break; | |
} | |
case ACCEPTED: { | |
text = "Connecting"; | |
break; | |
} | |
case CONVERSATION: { | |
text = "Connecting"; | |
break; | |
} | |
case PAUSED: { | |
text = "Reconnecting"; | |
break; | |
} | |
case FINISHED: { | |
text = "Finished"; | |
break; | |
} | |
} | |
statusText.setText(StringUtils.capitalize(text)); | |
} | |
// Permissions =============================================================================================== // | |
boolean hasAudioPermission() { | |
return ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED; | |
} | |
boolean hasReadPhoneStatePermission() { | |
return ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED; | |
} | |
void requestReadPhoneStatePermission() { | |
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 0); | |
} | |
void requestAudioPermission() { | |
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 0); | |
} | |
@Override | |
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { | |
switch (requestCode) { | |
case 0: { | |
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { | |
this.start(); | |
} else { | |
Toast.makeText(this, "Failed to access the microphone.\nclick allow when asked for permission.", Toast.LENGTH_SHORT).show(); | |
} | |
break; | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package mobi.homa.app.audio; | |
import android.content.Context; | |
import android.media.AudioManager; | |
import android.media.SoundPool; | |
import android.net.Uri; | |
import android.os.Build; | |
import android.util.Log; | |
public class HomaAudioManager implements AudioManager.OnAudioFocusChangeListener { | |
private static final String TAG = "AudioManager"; | |
private final Context context; | |
private final IncomingRinger incomingRinger; | |
private final OutgoingRinger outgoingRinger; | |
private final OutgoingRinger beepRinger; | |
private final SoundPool soundPool; | |
private final int connectedSoundId; | |
private final int disconnectedSoundId; | |
public HomaAudioManager(Context context, Integer connectedSound, Integer disconnectedSound) { | |
this.context = context.getApplicationContext(); | |
this.incomingRinger = new IncomingRinger(context); | |
this.outgoingRinger = new OutgoingRinger(context); | |
this.beepRinger = new OutgoingRinger(context); | |
this.soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0); | |
this.connectedSoundId = this.soundPool.load(context, connectedSound, 1); | |
this.disconnectedSoundId = this.soundPool.load(context, disconnectedSound, 1); | |
} | |
public static AudioManager getAudioManager(Context context) { | |
return (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); | |
} | |
public void initializeAudioForCall() { | |
AudioManager audioManager = getAudioManager(context); | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | |
audioManager.requestAudioFocus(this, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE); | |
} else { | |
audioManager.requestAudioFocus(this, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN); | |
} | |
} | |
public void startIncomingRinger(Uri ringtoneUri, boolean vibrate) { | |
AudioManager audioManager = getAudioManager(context); | |
boolean speaker = !audioManager.isWiredHeadsetOn() && !audioManager.isBluetoothScoOn(); | |
audioManager.setMode(AudioManager.MODE_RINGTONE); | |
audioManager.setMicrophoneMute(false); | |
audioManager.setSpeakerphoneOn(speaker); | |
incomingRinger.start(ringtoneUri, vibrate); | |
} | |
public void startOutgoingRinger(Uri type, boolean speakerOff) { | |
AudioManager audioManager = getAudioManager(context); | |
audioManager.setMicrophoneMute(false); | |
if (speakerOff) { | |
audioManager.setSpeakerphoneOn(false); | |
} | |
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); | |
outgoingRinger.start(type); | |
} | |
public void startBeepRinger(Uri type, boolean speakerOff) { | |
outgoingRinger.stop(); | |
incomingRinger.stop(); | |
AudioManager audioManager = getAudioManager(context); | |
audioManager.setMicrophoneMute(false); | |
if (speakerOff) { | |
audioManager.setSpeakerphoneOn(false); | |
} | |
audioManager.setMode(AudioManager.MODE_RINGTONE); | |
beepRinger.start(type); | |
} | |
public void silenceIncomingRinger() { | |
incomingRinger.stop(); | |
} | |
public void startCommunication(boolean preserveSpeakerphone) { | |
AudioManager audioManager = getAudioManager(context); | |
incomingRinger.stop(); | |
outgoingRinger.stop(); | |
beepRinger.stop(); | |
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); | |
if (!preserveSpeakerphone) { | |
audioManager.setSpeakerphoneOn(false); | |
} | |
soundPool.play(connectedSoundId, 1.0f, 1.0f, 0, 0, 1.0f); | |
} | |
public void stop(boolean playDisconnected) { | |
AudioManager audioManager = getAudioManager(context); | |
incomingRinger.stop(); | |
outgoingRinger.stop(); | |
beepRinger.stop(); | |
if (playDisconnected) { | |
soundPool.play(disconnectedSoundId, 1.0f, 1.0f, 0, 0, 1.0f); | |
} | |
if (audioManager.isBluetoothScoOn()) { | |
audioManager.setBluetoothScoOn(false); | |
audioManager.stopBluetoothSco(); | |
} | |
audioManager.setSpeakerphoneOn(false); | |
audioManager.setMicrophoneMute(false); | |
audioManager.setMode(AudioManager.MODE_NORMAL); | |
audioManager.abandonAudioFocus(null); | |
} | |
@Override | |
public void onAudioFocusChange(int focusChange) { | |
Log.i(TAG, "Audio Focus Changed , " + focusChange); | |
} | |
public boolean isSpeakerOn() { | |
AudioManager audioManager = getAudioManager(context); | |
return audioManager.isSpeakerphoneOn(); | |
} | |
public void setSpeakerOn(boolean status) { | |
AudioManager audioManager = getAudioManager(context); | |
audioManager.setSpeakerphoneOn(status); | |
if (status && audioManager.isBluetoothScoOn()) { | |
audioManager.stopBluetoothSco(); | |
audioManager.setBluetoothScoOn(false); | |
} | |
} | |
public void setMicrophoneMute(boolean on) { | |
AudioManager audioManager = getAudioManager(context); | |
audioManager.setMicrophoneMute(on); | |
} | |
public boolean isMicrophoneMute() { | |
AudioManager audioManager = getAudioManager(context); | |
return audioManager.isMicrophoneMute(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment