package io.rong.callkit;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.os.Vibrator;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import io.rong.calllib.IRongCallListener;
import io.rong.calllib.RongCallCommon;
import io.rong.calllib.RongCallSession;
import io.rong.common.RLog;
import io.rong.imkit.RongContext;
import io.rong.imkit.manager.AudioPlayManager;
import io.rong.imkit.manager.AudioRecordManager;
import io.rong.imkit.utilities.PermissionCheckUtil;
import io.rong.imkit.utils.NotificationUtil;
/**
* Created by weiqinxiao on 16/3/9.
*/
public class BaseCallActivity extends Activity implements IRongCallListener,PickupDetector.PickupDetectListener {
private static final String TAG = "BaseCallActivity";
private final static long DELAY_TIME = 1000;
static final int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 100;
private static final String SYSTEM_DIALOG_REASON_KEY = "reason";
private static final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
private MediaPlayer mMediaPlayer;
private Vibrator mVibrator;
private int time = 0;
private Runnable updateTimeRunnable;
private boolean shouldShowFloat;
private boolean shouldRestoreFloat;
protected Handler handler;
private BroadcastReceiver mHomeKeyReceiver;
protected boolean isFinishing;
protected PickupDetector pickupDetector;
protected PowerManager powerManager;
protected PowerManager.WakeLock wakeLock;
static final String[] VIDEO_CALL_PERMISSIONS = {Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA};
static final String[] AUDIO_CALL_PERMISSIONS = {Manifest.permission.RECORD_AUDIO};
public static final int CALL_NOTIFICATION_ID = 4000;
public void setShouldShowFloat(boolean shouldShowFloat) {
this.shouldShowFloat = shouldShowFloat;
}
public void showShortToast(String text) {
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
}
public void postRunnableDelay(Runnable runnable) {
handler.postDelayed(runnable, DELAY_TIME);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RLog.d(TAG, "BaseCallActivity onCreate");
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
shouldRestoreFloat = true;
PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
boolean isScreenOn = pm.isScreenOn();
if (!isScreenOn) {
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK, "bright");
wl.acquire();
wl.release();
}
handler = new Handler();
mHomeKeyReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
if (SYSTEM_DIALOG_REASON_HOME_KEY.equals(reason) && shouldShowFloat) {
finish();
}
}
}
};
try {
registerReceiver(mHomeKeyReceiver, new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
} catch (Exception e) {
e.printStackTrace();
}
isFinishing = false;
RongCallProxy.getInstance().setCallListener(this);
AudioPlayManager.getInstance().stopPlay();
AudioRecordManager.getInstance().destroyRecord();
}
@Override
protected void onStart() {
super.onStart();
Intent intent = getIntent();
Bundle bundle = intent.getBundleExtra("floatbox");
if (shouldRestoreFloat && bundle != null){
onRestoreFloatBox(bundle);
}
}
public void onOutgoingCallRinging() {
mMediaPlayer = MediaPlayer.create(this, R.raw.voip_outgoing_ring);
mMediaPlayer.setLooping(true);
mMediaPlayer.start();
}
public void onIncomingCallRinging() {
int ringerMode = NotificationUtil.getRingerMode(this);
if(ringerMode != AudioManager.RINGER_MODE_SILENT){
if(ringerMode == AudioManager.RINGER_MODE_VIBRATE){
mVibrator = (Vibrator) RongContext.getInstance().getSystemService(Context.VIBRATOR_SERVICE);
mVibrator.vibrate(new long[] {500, 1000}, 0);
} else {
Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
mMediaPlayer = new MediaPlayer();
try {
mMediaPlayer.setDataSource(this, uri);
mMediaPlayer.setLooping(true);
mMediaPlayer.prepare();
mMediaPlayer.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void setupTime(final TextView timeView) {
if(updateTimeRunnable != null) {
handler.removeCallbacks(updateTimeRunnable);
}
updateTimeRunnable = new UpdateTimeRunnable(timeView);
handler.post(updateTimeRunnable);
}
public int getTime() {
return time;
}
public void stopRing() {
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer = null;
}
if(mVibrator != null){
mVibrator.cancel();
mVibrator = null;
}
}
@Override
public void onCallOutgoing(RongCallSession callProfile, SurfaceView localVideo) {
}
@Override
public void onRemoteUserRinging(String userId) {
}
@Override
public void onCallDisconnected(RongCallSession callProfile, RongCallCommon.CallDisconnectedReason reason) {
shouldShowFloat = false;
String text = null;
switch (reason) {
case CANCEL:
text = getString(R.string.rc_voip_mo_cancel);
break;
case REJECT:
text = getString(R.string.rc_voip_mo_reject);
break;
case NO_RESPONSE:
case BUSY_LINE:
text = getString(R.string.rc_voip_mo_no_response);
break;
case REMOTE_BUSY_LINE:
text = getString(R.string.rc_voip_mt_busy);
break;
case REMOTE_CANCEL:
text = getString(R.string.rc_voip_mt_cancel);
break;
case REMOTE_REJECT:
text = getString(R.string.rc_voip_mt_reject);
break;
case REMOTE_NO_RESPONSE:
text = getString(R.string.rc_voip_mt_no_response);
break;
case REMOTE_HANGUP:
case HANGUP:
case NETWORK_ERROR:
case INIT_VIDEO_ERROR:
text = getString(R.string.rc_voip_call_terminalted);
break;
}
if (text != null) {
showShortToast(text);
}
stopRing();
NotificationUtil.clearNotification(this, BaseCallActivity.CALL_NOTIFICATION_ID);
RongCallProxy.getInstance().setCallListener(null);
}
@Override
public void onRemoteUserInvited(String userId, RongCallCommon.CallMediaType mediaType) {
}
@Override
public void onRemoteUserJoined(String userId, RongCallCommon.CallMediaType mediaType, SurfaceView remoteVideo) {
}
@Override
public void onRemoteUserLeft(String userId, RongCallCommon.CallDisconnectedReason reason) {
}
@Override
public void onMediaTypeChanged(String userId, RongCallCommon.CallMediaType mediaType, SurfaceView video) {
}
@Override
public void onError(RongCallCommon.CallErrorCode errorCode) {
}
@Override
public void onCallConnected(RongCallSession callProfile, SurfaceView localVideo) {
shouldShowFloat = true;
}
@Override
protected void onPause() {
super.onPause();
if (shouldShowFloat) {
Bundle bundle = new Bundle();
String action = onSaveFloatBoxState(bundle);
if (action != null) {
bundle.putString("action", action);
CallFloatBoxView.showFloatBox(getApplicationContext(), bundle, time);
int mediaType = bundle.getInt("mediaType");
showOnGoingNotification(getString(R.string.rc_call_on_going),
mediaType == RongCallCommon.CallMediaType.AUDIO.getValue() ? getString(R.string.rc_audio_call_on_going) : getString(R.string.rc_video_call_on_going));
}
}
}
@Override
protected void onResume() {
super.onResume();
RLog.d(TAG, "BaseCallActivity onResume");
RongCallProxy.getInstance().setCallListener(this);
if (shouldRestoreFloat){
time = CallFloatBoxView.hideFloatBox();
}
shouldRestoreFloat = true;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
shouldRestoreFloat = false;
}
@Override
protected void onDestroy() {
try {
if (mHomeKeyReceiver != null) {
unregisterReceiver(mHomeKeyReceiver);
}
} catch (Exception e) {
e.printStackTrace();
}
isFinishing = false;
handler.removeCallbacks(updateTimeRunnable);
super.onDestroy();
}
@Override
public void onRemoteCameraDisabled(String userId, boolean muted) {
}
public void onRestoreFloatBox(Bundle bundle) {
}
public String onSaveFloatBoxState(Bundle bundle) {
return null;
}
public void showOnGoingNotification(String title, String content) {
Intent intent = new Intent(getIntent().getAction());
Bundle bundle = new Bundle();
onSaveFloatBoxState(bundle);
intent.putExtra("floatbox", bundle);
intent.putExtra("callAction", RongCallAction.ACTION_RESUME_CALL.getName());
PendingIntent pendingIntent = PendingIntent.getActivity(this, 1000, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationUtil.showNotification(this, title, content, pendingIntent, CALL_NOTIFICATION_ID, Notification.DEFAULT_LIGHTS);
}
@Override
public void onBackPressed() {
super.onBackPressed();
}
@TargetApi(23)
boolean requestCallPermissions(RongCallCommon.CallMediaType type, int requestCode) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
return true;
String[] permissions;
if (type.equals(RongCallCommon.CallMediaType.VIDEO)) {
permissions = new String[]{Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO};
} else if (type.equals(RongCallCommon.CallMediaType.AUDIO)) {
permissions = new String[]{Manifest.permission.RECORD_AUDIO};
} else {
return true;
}
return PermissionCheckUtil.requestPermissions(this, permissions, requestCode);
}
private class UpdateTimeRunnable implements Runnable {
private TextView timeView;
public UpdateTimeRunnable(TextView timeView) {
this.timeView = timeView;
}
@Override
public void run() {
time++;
if (time >= 3600) {
timeView.setText(String.format("%d:%02d:%02d", time / 3600, (time % 3600) / 60, (time % 60)));
} else {
timeView.setText(String.format("%02d:%02d", (time % 3600) / 60, (time % 60)));
}
handler.postDelayed(this, 1000);
}
}
void onMinimizeClick(View view) {
if (Build.BRAND.toLowerCase().contains("xiaomi")) {
if (PermissionCheckUtil.canDrawOverlays(this)) {
finish();
} else {
Toast.makeText(this, R.string.rc_voip_float_window_not_allowed, Toast.LENGTH_LONG).show();
}
} else {
finish();
}
}
protected void createPowerManager() {
if (powerManager == null) {
powerManager = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, TAG);
}
}
protected void createPickupDetector() {
if (pickupDetector == null) {
pickupDetector = new PickupDetector(this);
}
}
@Override
public void onPickupDetected(boolean isPickingUp) {
if (wakeLock == null) {
RLog.d(TAG, "No PROXIMITY_SCREEN_OFF_WAKE_LOCK");
return;
}
if (isPickingUp && !wakeLock.isHeld()) {
setShouldShowFloat(false);
shouldRestoreFloat = false;
wakeLock.acquire();
}
if (!isPickingUp && wakeLock.isHeld()) {
try {
wakeLock.setReferenceCounted(false);
wakeLock.release();
setShouldShowFloat(true);
shouldRestoreFloat = true;
} catch (Exception e) {
}
}
}
}