如何通过创建按钮(Sinch)禁用一个最终用户的视频通话?

时间:2019-12-08 18:54:18

标签: android firebase sinch android-sinch-api

我用Sinch创建了一个视频和语音通话应用程序。我准备了所有布局,并且工作正常,还需要实现一项新功能,如果有的话-正在进行一个视频通话。如果另一位最终用户启用了视频,则一个用户可以禁用他们的视频,并且可以看到其他视频。在这种情况下,我没有任何想法可言,因为我尝试了很多,但没有从任何地方得到任何答复。

呼叫屏幕布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:keepScreenOn="true">

    <RelativeLayout
        android:id="@+id/remoteVideo"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"/>

    <ImageView
        android:id="@+id/userImage1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@drawable/ic_placeholder"
        android:tint="#99000000"
        tools:ignore="ContentDescription" />

    <View
        android:id="@+id/tintBlue"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/vertical_gradient" />

    <TextView
        android:id="@+id/txt_calling"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/layout_btns"
        android:layout_centerHorizontal="true"
        android:fontFamily="@font/roboto_medium"
        android:gravity="center"
        android:text="Infinite Messenger"
        android:textColor="@android:color/white"
        android:textSize="12sp"
        tools:ignore="HardcodedText" />

    <ImageView
        android:id="@+id/userImage2"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_above="@+id/txt_calling"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="34dp"
        android:scaleType="centerCrop"
        android:visibility="gone"
        tools:ignore="ContentDescription" />

    <TextView
        android:id="@+id/remoteUser"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/txt_calling"
        android:layout_centerHorizontal="true"
        android:ellipsize="marquee"
        android:fontFamily="@font/roboto_medium"
        android:gravity="center"
        android:singleLine="true"
        android:textColor="@android:color/white"
        android:textSize="22sp" />

    <TextView
        android:id="@+id/callState"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/txt_calling"
        android:layout_centerHorizontal="true"
        android:fontFamily="@font/roboto_light"
        android:padding="@dimen/_8sdp"
        android:textColor="@android:color/white"
        android:textSize="14sp"
        android:visibility="gone" />

    <TextView
        android:id="@+id/callDuration"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/txt_calling"
        android:layout_centerHorizontal="true"
        android:fontFamily="@font/roboto_light"
        android:textColor="@android:color/white"
        android:textSize="16sp" />

    <ImageView
        android:id="@+id/hangupButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="@dimen/_16sdp"
        android:background="@drawable/round_red_hangup"
        android:padding="16dp"
        android:src="@drawable/ic_call_end_black_24dp"
        tools:ignore="ContentDescription" />

    <RelativeLayout
        android:id="@+id/localVideo"
        android:layout_width="100dp"
        android:layout_height="130dp"
        android:layout_above="@+id/layout_btns"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_marginEnd="4dp"
        android:layout_marginRight="4dp"
        android:layout_marginBottom="@dimen/_50sdp"
        tools:ignore="RtlHardcoded" />

    <LinearLayout
        android:id="@+id/layout_btns"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/hangupButton"
        android:layout_marginBottom="@dimen/_16sdp"
        android:orientation="horizontal"
        android:padding="@dimen/_10sdp"
        tools:ignore="DisableBaselineAlignment">

        <LinearLayout
            android:id="@+id/switchVideo_LLY"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:visibility="visible">

            <ImageView
                android:id="@+id/switchVideo"
                android:layout_width="@dimen/_50sdp"
                android:layout_height="@dimen/_50sdp"
                android:padding="4dp"
                android:src="@drawable/ic_camera_turn"
                tools:ignore="ContentDescription" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center">

            <ImageView
                android:id="@+id/switchVolume"
                android:layout_width="@dimen/_50sdp"
                android:layout_height="@dimen/_50sdp"
                android:padding="4dp"
                android:src="@drawable/ic_speaker"
                tools:ignore="ContentDescription" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center">

            <ImageView
                android:id="@+id/switchMic"
                android:layout_width="@dimen/_50sdp"
                android:layout_height="@dimen/_50sdp"
                android:padding="4dp"
                android:src="@drawable/ic_mic_on"
                tools:ignore="ContentDescription" />
        </LinearLayout>
    </LinearLayout>
    <com.google.android.gms.ads.AdView xmlns:ads="http://schemas.android.com/apk/res-auto"
        android:id="@+id/adView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        ads:adSize="BANNER"
        ads:adUnitId="@string/bannerad_id" />

</RelativeLayout>

呼叫屏幕类别:

import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.AudioManager;
import android.os.PowerManager;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.infinite.messenger.models.Status;
import com.infinite.messenger.utils.OnDragTouchListener;
import com.sinch.android.rtc.AudioController;
import com.sinch.android.rtc.PushPair;
import com.sinch.android.rtc.calling.Call;
import com.sinch.android.rtc.calling.CallEndCause;
import com.sinch.android.rtc.calling.CallState;
import com.sinch.android.rtc.video.VideoCallListener;
import com.sinch.android.rtc.video.VideoController;
import com.infinite.messenger.R;
import com.infinite.messenger.models.Contact;
import com.infinite.messenger.models.Group;
import com.infinite.messenger.models.LogCall;
import com.infinite.messenger.models.User;
import com.infinite.messenger.services.SinchService;
import com.infinite.messenger.utils.AudioPlayer;
import com.squareup.picasso.Picasso;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;

public class CallScreenActivity extends BaseActivity implements SensorEventListener {
    static final String TAG = CallScreenActivity.class.getSimpleName();
    static final String ADDED_LISTENER = "addedListener";
    private static String EXTRA_DATA_USER = "extradatauser";
    private static String EXTRA_DATA_IN_OR_OUT = "extradatainorout";

    private AudioPlayer mAudioPlayer;
    private Timer mTimer;
    private UpdateCallDurationTask mDurationTask;

    private String mCallId, inOrOut;
    private boolean mAddedListener, mLocalVideoViewAdded, mRemoteVideoViewAdded, isVideo, isMute, isSpeaker, alphaInvisible, logSaved;
    private int mCallDurationSecond = 0;
    private RelativeLayout myCallScreenRootRLY;

    private TextView mCallDuration, mCallState, mCallerName, myTxtCalling;
    private ImageView userImage1, userImage2, switchVideo, switchMic, switchVolume;
    private View tintBlue, bottomButtons;
    private RelativeLayout localVideo, remoteVideo;
    private LinearLayout mySwitchCameraLLY;

    private SensorManager mSensorManager;
    private Sensor mProximity;
    PowerManager.WakeLock wlOff = null, wlOn = null;

    @Override
    protected void onDestroy() {
        super.onDestroy();
        try {
            if (wlOff != null && wlOff.isHeld()) {
                wlOff.release();
            } else if (wlOn != null && wlOn.isHeld()) {
                wlOn.release();
            }
        } catch (RuntimeException ex) {
        }
    }

    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        float distance = sensorEvent.values[0];
        if (!isVideo && !isSpeaker) {
            PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
            if (distance < 4) {
                if (wlOn != null && wlOn.isHeld()) {
                    wlOn.release();
                }
                if (pm != null) {
                    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                        if (wlOff == null)
                            wlOff = pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, "tag");
                        if (!wlOff.isHeld()) wlOff.acquire();
                    }
                }
            } else {
                if (wlOff != null && wlOff.isHeld()) {
                    wlOff.release();
                }
                if (pm != null) {
                    if (wlOn == null)
                        wlOn = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "tag");
                    if (!wlOn.isHeld()) wlOn.acquire();
                }
            }
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {
    }

    private class UpdateCallDurationTask extends TimerTask {

        @Override
        public void run() {
            CallScreenActivity.this.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    updateCallDuration();
                }
            });
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        savedInstanceState.putBoolean(ADDED_LISTENER, mAddedListener);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        mAddedListener = savedInstanceState.getBoolean(ADDED_LISTENER);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_call_screen);

        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mProximity = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);

        Intent intent = getIntent();
        user = intent.getParcelableExtra(EXTRA_DATA_USER);
        mCallId = intent.getStringExtra(SinchService.CALL_ID);
        inOrOut = intent.getStringExtra(EXTRA_DATA_IN_OR_OUT);

        mAudioPlayer = new AudioPlayer(this);
        mCallDuration = findViewById(R.id.callDuration);
        mCallerName = findViewById(R.id.remoteUser);
        mCallState = findViewById(R.id.callState);
        userImage1 = findViewById(R.id.userImage1);
        userImage2 = findViewById(R.id.userImage2);
        myTxtCalling = findViewById(R.id.txt_calling);
        tintBlue = findViewById(R.id.tintBlue);
        localVideo = findViewById(R.id.localVideo);
        remoteVideo = findViewById(R.id.remoteVideo);
        switchVideo = findViewById(R.id.switchVideo);
        switchMic = findViewById(R.id.switchMic);
        switchVolume = findViewById(R.id.switchVolume);
        bottomButtons = findViewById(R.id.layout_btns);
        mySwitchCameraLLY = findViewById(R.id.switchVideo_LLY);
        findViewById(R.id.hangupButton).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                endCall();
            }
        });

       remoteVideo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startAlphaAnimation();
            }
        });
        switchMic.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                isMute = !isMute;
                setMuteUnmute();
            }
        });
        switchVolume.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                isSpeaker = !isSpeaker;
                enableSpeaker(isSpeaker);
            }
        });
        switchVideo.setClickable(false);
    }

    @Override
    public void onPause() {
        super.onPause();
        mDurationTask.cancel();
        mTimer.cancel();
        mSensorManager.unregisterListener(this);
        removeVideoViews();
    }

    @Override
    public void onResume() {
        super.onResume();
        mTimer = new Timer();
        mDurationTask = new UpdateCallDurationTask();
        mTimer.schedule(mDurationTask, 0, 500);
        mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL);
        updateUI();
    }

    @Override
    public void onBackPressed() {
        // User should exit activity by ending call, not by going back.
    }

    private void endCall() {
        mAudioPlayer.stopProgressTone();
        Call call = getSinchServiceInterface().getCall(mCallId);

        if (call != null) {
            if (user == null) {
                user = new User(call.getRemoteUserId(), call.getRemoteUserId(), getString(R.string.app_name), "");
            }
            call.hangup();
        }
        saveLog();
        finish();
    }

    private void saveLog() {
        if (!logSaved) {
            rChatDb.beginTransaction();
            rChatDb.copyToRealm(new LogCall(user, System.currentTimeMillis(), mCallDurationSecond,
                    isVideo, inOrOut, userMe.getId(), user.getId()));
            rChatDb.commitTransaction();
            logSaved = true;
        }
    }

    private String formatTimespan(int totalSeconds) {
        long minutes = totalSeconds / 60;
        long seconds = totalSeconds % 60;
        return String.format(Locale.US, "%02d:%02d", minutes, seconds);
    }

    private void updateCallDuration() {
        Call call = getSinchServiceInterface().getCall(mCallId);
        if (call != null) {
            mCallDurationSecond = call.getDetails().getDuration();
            mCallDuration.setText(formatTimespan(call.getDetails().getDuration()));
        }
    }

    @Override
    void onSinchConnected() {
        Call call = getSinchServiceInterface().getCall(mCallId);
        if (call != null) {
            if (!mAddedListener) {
                call.addCallListener(new SinchCallListener());
                mAddedListener = true;
            }
            mCallerName.setText(user != null ? user.getNameToDisplay() : call.getRemoteUserId());
            mCallState.setText(call.getState().toString());
            if (user != null) {
//                Glide.with(this).load(user.getImage()).apply(new RequestOptions().placeholder(R.drawable.ic_logo_)).into(userImage1);
//                Glide.with(this).load(user.getImage()).apply(RequestOptions.circleCropTransform().placeholder(R.drawable.ic_logo_)).into(userImage2);
                if (user.getImage() != null && !user.getImage().isEmpty()) {
                    Picasso.get()
                            .load(user.getImage())
                            .tag(this)
                            .error(R.drawable.ic_avatar)
                            .placeholder(R.drawable.ic_avatar)
                            .into(userImage1);

                    Picasso.get()
                            .load(user.getImage())
                            .tag(this)
                            .error(R.drawable.ic_avatar)
                            .placeholder(R.drawable.ic_avatar)
                            .into(userImage2);
                } else {
                    userImage1.setBackgroundResource(R.drawable.ic_avatar);
                    userImage2.setBackgroundResource(R.drawable.ic_avatar);
                }
//                tintBlue.setVisibility(View.INVISIBLE);
//                remoteVideo.setVisibility(View.INVISIBLE);
            }
        } else {
            Log.e(TAG, "Started with invalid callId, aborting.");
            finish();
        }

        updateUI();
    }

    private void updateUI() {
        if (getSinchServiceInterface() == null) {
            return; // early
        }

        Call call = getSinchServiceInterface().getCall(mCallId);
        if (call != null) {
            mCallerName.setText(user != null ? user.getNameToDisplay() : call.getRemoteUserId());
            mCallState.setText(call.getState().toString());
            isVideo = call.getDetails().isVideoOffered();
            if (isVideo) {
                addLocalView();
                if (call.getState() == CallState.ESTABLISHED) {
                    addRemoteView();
                }
                mySwitchCameraLLY.setVisibility(View.VISIBLE);
            } else {
                mySwitchCameraLLY.setVisibility(View.GONE);
            }

            myTxtCalling.setText(getResources().getString(R.string.app_name) + (isVideo ? " Video Calling" : " Voice Calling"));
            tintBlue.setVisibility(isVideo ? View.GONE : View.VISIBLE);
            localVideo.setVisibility(!isVideo ? View.GONE : View.VISIBLE);
        }
    }

    private void removeVideoViews() {
        if (getSinchServiceInterface() == null) {
            return; // early
        }

        VideoController vc = getSinchServiceInterface().getVideoController();
        if (vc != null) {
            remoteVideo.removeView(vc.getRemoteView());

            localVideo.removeView(vc.getLocalView());
            mLocalVideoViewAdded = false;
            mRemoteVideoViewAdded = false;
        }
    }

    private void addLocalView() {
        if (mLocalVideoViewAdded || getSinchServiceInterface() == null) {
            return; //early
        }
        final VideoController vc = getSinchServiceInterface().getVideoController();
        if (vc != null) {
            localVideo.addView(vc.getLocalView());
            switchVideo.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    vc.toggleCaptureDevicePosition();
                }
            });
            mLocalVideoViewAdded = true;
            localVideo.setOnTouchListener(new OnDragTouchListener(localVideo, remoteVideo));
        }
    }

    private void addRemoteView() {
        if (mRemoteVideoViewAdded || getSinchServiceInterface() == null) {
            return; //early
        }
        final VideoController vc = getSinchServiceInterface().getVideoController();
        if (vc != null) {
            RelativeLayout view = (RelativeLayout) findViewById(R.id.remoteVideo);
            view.addView(vc.getRemoteView());
            mRemoteVideoViewAdded = true;
        }
    }

    private void startAlphaAnimation() {
        AlphaAnimation animation1 = new AlphaAnimation(alphaInvisible ? 0.0f : 1.0f, alphaInvisible ? 1.0f : 0.0f);
        animation1.setDuration(500);
        animation1.setStartOffset(25);
        animation1.setFillAfter(true);

        myTxtCalling.startAnimation(animation1);
        userImage2.startAnimation(animation1);
        mCallerName.startAnimation(animation1);
        mCallState.startAnimation(animation1);
        mCallDuration.startAnimation(animation1);
        bottomButtons.startAnimation(animation1);

        alphaInvisible = !alphaInvisible;
    }

    private void enableSpeaker(boolean enable) {
        AudioController audioController = getSinchServiceInterface().getAudioController();
        if (enable)
            audioController.enableSpeaker();
        else
            audioController.disableSpeaker();
        switchVolume.setImageDrawable(ContextCompat.getDrawable(this, isSpeaker ? R.drawable.ic_speaker : R.drawable.ic_speaker_off));
    }

    private void setMuteUnmute() {
        AudioController audioController = getSinchServiceInterface().getAudioController();
        if (isMute) {
            audioController.mute();
            switchMic.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_mic_off));
        } else {
            audioController.unmute();
            switchMic.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_mic_on));

        }

    }

    @Override
    void onSinchDisconnected() {

    }

    private class SinchCallListener implements VideoCallListener {


        @Override
        public void onCallEnded(Call call) {
            CallEndCause cause = call.getDetails().getEndCause();
            Log.d(TAG, "Call ended. Reason: " + cause.toString());
            mAudioPlayer.stopProgressTone();
            setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE);
            String endMsg = call.getDetails().toString();
            Log.d(TAG, "Call ended. Reason: " + endMsg);
            if (user == null) {
                user = new User(call.getRemoteUserId(), call.getRemoteUserId(), getString(R.string.app_name), "");
            }
            endCall();
        }

        @Override
        public void onCallEstablished(Call call) {
            Log.d(TAG, "Call established");
            mAudioPlayer.stopProgressTone();
            mCallState.setText(call.getState().toString());
            setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
            isSpeaker = call.getDetails().isVideoOffered();
            enableSpeaker(isSpeaker);
            switchVideo.setClickable(call.getDetails().isVideoOffered());
            if (call.getDetails().isVideoOffered()) {
                mySwitchCameraLLY.setVisibility(View.VISIBLE);
            } else {
                mySwitchCameraLLY.setVisibility(View.GONE);
            }
            switchVideo.setAlpha(call.getDetails().isVideoOffered() ? 1f : 0.4f);
            userImage1.setVisibility(isVideo ? View.GONE : View.VISIBLE);
            Log.d(TAG, "Call offered video: " + call.getDetails().isVideoOffered());
        }

        @Override
        public void onCallProgressing(Call call) {
            Log.d(TAG, "Call progressing");
            mAudioPlayer.playProgressTone();
        }

        @Override
        public void onShouldSendPushNotification(Call call, List<PushPair> pushPairs) {
            // Send a push through your push provider here, e.g. GCM
        }

        @Override
        public void onVideoTrackAdded(Call call) {
            Log.d(TAG, "Video track added");
            addRemoteView();
        }

        @Override
        public void onVideoTrackPaused(Call call) {

        }

        @Override
        public void onVideoTrackResumed(Call call) {

        }

    }

    public static Intent newIntent(Context context, User user, String callId, String inOrOut) {
        Intent intent = new Intent(context, CallScreenActivity.class);
        intent.putExtra(EXTRA_DATA_USER, user);
        intent.putExtra(EXTRA_DATA_IN_OR_OUT, inOrOut);
        intent.putExtra(SinchService.CALL_ID, callId);
        return intent;
    }

    @Override
    void myUsersResult(ArrayList<User> myUsers) {

    }

    @Override
    void myContactsResult(ArrayList<Contact> myContacts) {

    }

    @Override
    void userAdded(User valueUser) {

    }

    @Override
    void groupAdded(Group valueGroup) {

    }

    @Override
    void userUpdated(User valueUser) {

    }

    @Override
    void groupUpdated(Group valueGroup) {

    }

    @Override
    void statusAdded(Status status) {

    }

    @Override
    void statusUpdated(Status status) {

    }
}

就这些。

0 个答案:

没有答案