Guest User

Untitled

a guest
Dec 12th, 2018
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.88 KB | None | 0 0
  1. import android.Manifest;
  2. import android.annotation.SuppressLint;
  3. import android.content.ComponentName;
  4. import android.content.DialogInterface;
  5. import android.content.Intent;
  6. import android.content.ServiceConnection;
  7. import android.content.pm.PackageManager;
  8. import android.net.Uri;
  9. import android.os.Bundle;
  10. import android.os.Handler;
  11. import android.os.IBinder;
  12. import android.provider.Settings;
  13. import android.support.annotation.NonNull;
  14. import android.support.annotation.Nullable;
  15. import android.support.v4.app.ActivityCompat;
  16. import android.support.v7.app.AlertDialog;
  17. import android.support.v7.app.AppCompatActivity;
  18. import android.text.TextUtils;
  19. import android.widget.ImageButton;
  20. import android.widget.TextView;
  21.  
  22. import io.reactivex.android.schedulers.AndroidSchedulers;
  23. import io.reactivex.disposables.Disposable;
  24. import io.reactivex.schedulers.Schedulers;
  25. import ru.tinkoff.core.log.Logger;
  26. import ru.tinkoff.core.onlinecall.call_manager.CallState;
  27. import ru.tinkoff.core.onlinecall.call_service.OnlineCallService;
  28. import ru.tinkoff.core.onlinecall.inner.lib.call_manager.inversion_of_controll.OnlineCall;
  29.  
  30. /**
  31. * @author i.s.golovachev
  32. */
  33. public abstract class Oncl2 extends AppCompatActivity {
  34.  
  35. private static final int APP_SETTINGS_REQUEST = 2;
  36. private static final int PERMISSIONS_REQUEST_RECORD_AUDIO = 1;
  37. private static final int CLOSE_DELAY = 500;
  38. private static final int CLOSE_DELAY_ERROR = 2400;
  39. private Disposable disposable;
  40. private OnlineCall onlineCall;
  41. private ServiceConnection callServiceConnection;
  42. private TextView statusView;
  43. private ImageButton endCall;
  44. private ImageButton microphoneButton;
  45. private boolean isMicrophoneEnabled = true;
  46. private ImageButton speakerphoneButton;
  47. private boolean isSpeakerphoneEnabled = false;
  48. private Handler handler;
  49. private boolean isBinded = false;
  50.  
  51.  
  52. @Override
  53. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
  54. if (requestCode == PERMISSIONS_REQUEST_RECORD_AUDIO) {
  55. tryStartCall(isRecordAudioGranted());
  56. }
  57. }
  58.  
  59. @Override
  60. public void onBackPressed() {
  61. handler.removeCallbacksAndMessages(null);
  62. super.onBackPressed();
  63. }
  64.  
  65. @SuppressLint("SetTextI18n")
  66. @Override
  67. protected void onCreate(@Nullable Bundle savedInstanceState) {
  68. super.onCreate(savedInstanceState);
  69. handler = new Handler(getMainLooper());
  70. setContentView(ru.tinkoff.core.call.R.layout.activity_online_call);
  71. initViews();
  72. tryStartCall();
  73. }
  74.  
  75. @Override
  76. protected void onDestroy() {
  77. super.onDestroy();
  78. if (isBinded) {
  79. unbindService(callServiceConnection);
  80. isBinded = false;
  81. }
  82. }
  83.  
  84. abstract protected Class<? extends OnlineCallService> provideServiceClass();
  85.  
  86. protected void startService() {
  87. Class<? extends OnlineCallService> callServiceImplClass = provideServiceClass();
  88. Intent startIntent = new Intent(this, callServiceImplClass);
  89. startService(startIntent);
  90. callServiceConnection = new ServiceConnection() {
  91.  
  92. @Override
  93. public void onServiceConnected(ComponentName name, IBinder service) {
  94. if (service.isBinderAlive()) {
  95. OnlineCallService.CallBinder callBinder = (OnlineCallService.CallBinder) service;
  96. onlineCall = callBinder.getOnlineCall();
  97. onlineCall.startCall();
  98. initCallObserver();
  99. }
  100. }
  101.  
  102. @Override
  103. public void onServiceDisconnected(ComponentName name) {
  104. onlineCall.abortCall();
  105. }
  106. };
  107.  
  108. bindService(startIntent, callServiceConnection, 0);
  109. isBinded = true;
  110. }
  111.  
  112. protected void initCallObserver() {
  113. disposable = onlineCall.subscribeOnStateChanges()
  114. .subscribeOn(Schedulers.io())
  115. .observeOn(AndroidSchedulers.mainThread())
  116. .subscribe(
  117. (this::handleChangeState),
  118. (this::handleError)
  119. );
  120. }
  121.  
  122. protected void handleChangeState(CallState status) {
  123.  
  124. String statusText = "";
  125.  
  126. if (status instanceof CallState.ConnectingState) {
  127. statusText = getString(ru.tinkoff.core.call.R.string.voip_call_call_status_connecting);
  128. } else if (status instanceof CallState.AbortState) {
  129. statusText = getString(ru.tinkoff.core.call.R.string.voip_call_call_status_end);
  130. finishAfterDelay();
  131. } else if (status instanceof CallState.TalkingState) {
  132. statusText = ""; // по хорошему нужен таймер, но это уже логика интегратора
  133. } else if (status instanceof CallState.ErrorState) {
  134. Throwable throwable = ((CallState.ErrorState) status).getError();
  135. statusText = handleError(throwable);
  136. }
  137.  
  138. statusView.setText(statusText);
  139. }
  140.  
  141. protected String handleError(Throwable e) {
  142. Logger.e("error state call ", e.getMessage());
  143. String errorMessage = errorMessage(e.getMessage());
  144. finishAfterDelayError();
  145. return errorMessage;
  146. }
  147.  
  148.  
  149. protected final DialogInterface.OnClickListener permissionsDialogListener = (dialog, which) -> {
  150. if (which == DialogInterface.BUTTON_NEGATIVE) {
  151. finishAfterDelay();
  152. } else if (which == DialogInterface.BUTTON_POSITIVE) {
  153. openAppSystemSettingsForResult();
  154. }
  155. };
  156.  
  157. private void finishAfterDelay() {
  158. handler.postDelayed(this::finish, CLOSE_DELAY);
  159. }
  160.  
  161. private void finishAfterDelayError() {
  162. handler.postDelayed(this::finish, CLOSE_DELAY_ERROR);
  163. }
  164.  
  165. private void initViews() {
  166.  
  167. endCall = findViewById(ru.tinkoff.core.call.R.id.end_call_button);
  168. endCall.setOnClickListener(v -> {
  169. onlineCall.abortCall();
  170. finishAfterDelay();
  171. }
  172. );
  173.  
  174. microphoneButton = findViewById(ru.tinkoff.core.call.R.id.microphone_button);
  175. microphoneButton.setOnClickListener(v -> switchMicrophone());
  176.  
  177. speakerphoneButton = findViewById(ru.tinkoff.core.call.R.id.speakerphone_button);
  178. speakerphoneButton.setOnClickListener(v -> switchSpeakerphone());
  179.  
  180. statusView = findViewById(ru.tinkoff.core.call.R.id.call_status);
  181. }
  182.  
  183. private void switchMicrophone() {
  184. isMicrophoneEnabled = !isMicrophoneEnabled;
  185. if (onlineCall != null) {
  186. onlineCall.setMicrophoneMute(!isMicrophoneEnabled);
  187. microphoneButton.setImageDrawable(getResources().getDrawable(isMicrophoneEnabled
  188. ? ru.tinkoff.core.call.R.drawable.ic_mic_white
  189. : ru.tinkoff.core.call.R.drawable.ic_mic_off_white));
  190. }
  191. }
  192.  
  193. private void switchSpeakerphone() {
  194. isSpeakerphoneEnabled = !isSpeakerphoneEnabled;
  195. if (onlineCall != null) {
  196. onlineCall.setSpeakerphoneOn(isSpeakerphoneEnabled);
  197. speakerphoneButton.setImageDrawable(getResources().getDrawable(isSpeakerphoneEnabled
  198. ? ru.tinkoff.core.call.R.drawable.ic_volume_up_white
  199. : ru.tinkoff.core.call.R.drawable.ic_volume_down_white));
  200. }
  201. }
  202.  
  203. private String errorMessage(String error) {
  204. String errorStatus = getString(ru.tinkoff.core.call.R.string.voip_call_call_status_error);
  205. if (TextUtils.isEmpty(error)) {
  206. return errorStatus;
  207. } else {
  208. return String.format("%s: %s", errorStatus, error);
  209. }
  210. }
  211.  
  212. private void tryStartCall() {
  213. if (isRecordAudioGranted()) {
  214. startService();
  215. } else {
  216. ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, PERMISSIONS_REQUEST_RECORD_AUDIO);
  217. }
  218. }
  219.  
  220. private void tryStartCall(boolean permissionGranted) {
  221. if (permissionGranted) {
  222. startService();
  223. } else {
  224. new AlertDialog.Builder(this)
  225. .setMessage(getString(ru.tinkoff.core.call.R.string.voip_call_record_audio_permission))
  226. .setPositiveButton(getString(ru.tinkoff.core.call.R.string.voip_call_permission_allow), permissionsDialogListener)
  227. .setNegativeButton(getString(ru.tinkoff.core.call.R.string.voip_call_permission_cancel), permissionsDialogListener)
  228. .create()
  229. .show();
  230. }
  231. }
  232.  
  233. private boolean isRecordAudioGranted() {
  234. return ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)
  235. == PackageManager.PERMISSION_GRANTED;
  236. }
  237.  
  238. private void openAppSystemSettingsForResult() {
  239. Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
  240. Uri.parse("package:" + getPackageName()));
  241. startActivityForResult(intent, APP_SETTINGS_REQUEST);
  242. }
  243.  
  244. }
Add Comment
Please, Sign In to add comment