Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import android.Manifest;
- import android.annotation.SuppressLint;
- import android.content.ComponentName;
- import android.content.DialogInterface;
- import android.content.Intent;
- import android.content.ServiceConnection;
- import android.content.pm.PackageManager;
- import android.net.Uri;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.IBinder;
- import android.provider.Settings;
- import android.support.annotation.NonNull;
- import android.support.annotation.Nullable;
- import android.support.v4.app.ActivityCompat;
- import android.support.v7.app.AlertDialog;
- import android.support.v7.app.AppCompatActivity;
- import android.text.TextUtils;
- import android.widget.ImageButton;
- import android.widget.TextView;
- import io.reactivex.android.schedulers.AndroidSchedulers;
- import io.reactivex.disposables.Disposable;
- import io.reactivex.schedulers.Schedulers;
- import ru.tinkoff.core.log.Logger;
- import ru.tinkoff.core.onlinecall.call_manager.CallState;
- import ru.tinkoff.core.onlinecall.call_service.OnlineCallService;
- import ru.tinkoff.core.onlinecall.inner.lib.call_manager.inversion_of_controll.OnlineCall;
- /**
- * @author i.s.golovachev
- */
- public abstract class Oncl2 extends AppCompatActivity {
- private static final int APP_SETTINGS_REQUEST = 2;
- private static final int PERMISSIONS_REQUEST_RECORD_AUDIO = 1;
- private static final int CLOSE_DELAY = 500;
- private static final int CLOSE_DELAY_ERROR = 2400;
- private Disposable disposable;
- private OnlineCall onlineCall;
- private ServiceConnection callServiceConnection;
- private TextView statusView;
- private ImageButton endCall;
- private ImageButton microphoneButton;
- private boolean isMicrophoneEnabled = true;
- private ImageButton speakerphoneButton;
- private boolean isSpeakerphoneEnabled = false;
- private Handler handler;
- private boolean isBinded = false;
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- if (requestCode == PERMISSIONS_REQUEST_RECORD_AUDIO) {
- tryStartCall(isRecordAudioGranted());
- }
- }
- @Override
- public void onBackPressed() {
- handler.removeCallbacksAndMessages(null);
- super.onBackPressed();
- }
- @SuppressLint("SetTextI18n")
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- handler = new Handler(getMainLooper());
- setContentView(ru.tinkoff.core.call.R.layout.activity_online_call);
- initViews();
- tryStartCall();
- }
- @Override
- protected void onDestroy() {
- super.onDestroy();
- if (isBinded) {
- unbindService(callServiceConnection);
- isBinded = false;
- }
- }
- abstract protected Class<? extends OnlineCallService> provideServiceClass();
- protected void startService() {
- Class<? extends OnlineCallService> callServiceImplClass = provideServiceClass();
- Intent startIntent = new Intent(this, callServiceImplClass);
- startService(startIntent);
- callServiceConnection = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- if (service.isBinderAlive()) {
- OnlineCallService.CallBinder callBinder = (OnlineCallService.CallBinder) service;
- onlineCall = callBinder.getOnlineCall();
- onlineCall.startCall();
- initCallObserver();
- }
- }
- @Override
- public void onServiceDisconnected(ComponentName name) {
- onlineCall.abortCall();
- }
- };
- bindService(startIntent, callServiceConnection, 0);
- isBinded = true;
- }
- protected void initCallObserver() {
- disposable = onlineCall.subscribeOnStateChanges()
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(
- (this::handleChangeState),
- (this::handleError)
- );
- }
- protected void handleChangeState(CallState status) {
- String statusText = "";
- if (status instanceof CallState.ConnectingState) {
- statusText = getString(ru.tinkoff.core.call.R.string.voip_call_call_status_connecting);
- } else if (status instanceof CallState.AbortState) {
- statusText = getString(ru.tinkoff.core.call.R.string.voip_call_call_status_end);
- finishAfterDelay();
- } else if (status instanceof CallState.TalkingState) {
- statusText = ""; // по хорошему нужен таймер, но это уже логика интегратора
- } else if (status instanceof CallState.ErrorState) {
- Throwable throwable = ((CallState.ErrorState) status).getError();
- statusText = handleError(throwable);
- }
- statusView.setText(statusText);
- }
- protected String handleError(Throwable e) {
- Logger.e("error state call ", e.getMessage());
- String errorMessage = errorMessage(e.getMessage());
- finishAfterDelayError();
- return errorMessage;
- }
- protected final DialogInterface.OnClickListener permissionsDialogListener = (dialog, which) -> {
- if (which == DialogInterface.BUTTON_NEGATIVE) {
- finishAfterDelay();
- } else if (which == DialogInterface.BUTTON_POSITIVE) {
- openAppSystemSettingsForResult();
- }
- };
- private void finishAfterDelay() {
- handler.postDelayed(this::finish, CLOSE_DELAY);
- }
- private void finishAfterDelayError() {
- handler.postDelayed(this::finish, CLOSE_DELAY_ERROR);
- }
- private void initViews() {
- endCall = findViewById(ru.tinkoff.core.call.R.id.end_call_button);
- endCall.setOnClickListener(v -> {
- onlineCall.abortCall();
- finishAfterDelay();
- }
- );
- microphoneButton = findViewById(ru.tinkoff.core.call.R.id.microphone_button);
- microphoneButton.setOnClickListener(v -> switchMicrophone());
- speakerphoneButton = findViewById(ru.tinkoff.core.call.R.id.speakerphone_button);
- speakerphoneButton.setOnClickListener(v -> switchSpeakerphone());
- statusView = findViewById(ru.tinkoff.core.call.R.id.call_status);
- }
- private void switchMicrophone() {
- isMicrophoneEnabled = !isMicrophoneEnabled;
- if (onlineCall != null) {
- onlineCall.setMicrophoneMute(!isMicrophoneEnabled);
- microphoneButton.setImageDrawable(getResources().getDrawable(isMicrophoneEnabled
- ? ru.tinkoff.core.call.R.drawable.ic_mic_white
- : ru.tinkoff.core.call.R.drawable.ic_mic_off_white));
- }
- }
- private void switchSpeakerphone() {
- isSpeakerphoneEnabled = !isSpeakerphoneEnabled;
- if (onlineCall != null) {
- onlineCall.setSpeakerphoneOn(isSpeakerphoneEnabled);
- speakerphoneButton.setImageDrawable(getResources().getDrawable(isSpeakerphoneEnabled
- ? ru.tinkoff.core.call.R.drawable.ic_volume_up_white
- : ru.tinkoff.core.call.R.drawable.ic_volume_down_white));
- }
- }
- private String errorMessage(String error) {
- String errorStatus = getString(ru.tinkoff.core.call.R.string.voip_call_call_status_error);
- if (TextUtils.isEmpty(error)) {
- return errorStatus;
- } else {
- return String.format("%s: %s", errorStatus, error);
- }
- }
- private void tryStartCall() {
- if (isRecordAudioGranted()) {
- startService();
- } else {
- ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, PERMISSIONS_REQUEST_RECORD_AUDIO);
- }
- }
- private void tryStartCall(boolean permissionGranted) {
- if (permissionGranted) {
- startService();
- } else {
- new AlertDialog.Builder(this)
- .setMessage(getString(ru.tinkoff.core.call.R.string.voip_call_record_audio_permission))
- .setPositiveButton(getString(ru.tinkoff.core.call.R.string.voip_call_permission_allow), permissionsDialogListener)
- .setNegativeButton(getString(ru.tinkoff.core.call.R.string.voip_call_permission_cancel), permissionsDialogListener)
- .create()
- .show();
- }
- }
- private boolean isRecordAudioGranted() {
- return ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)
- == PackageManager.PERMISSION_GRANTED;
- }
- private void openAppSystemSettingsForResult() {
- Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
- Uri.parse("package:" + getPackageName()));
- startActivityForResult(intent, APP_SETTINGS_REQUEST);
- }
- }
Add Comment
Please, Sign In to add comment