Android studio 无法连接视频通话-Agora.io

Android studio 无法连接视频通话-Agora.io,android-studio,agora.io,Android Studio,Agora.io,我第一次尝试制作视频通话应用程序。我正在android studio中使用Agora.io进行视频通话。我面临的问题是我看不到我打电话的人的视频。我完全可以从前面的摄像机中得到我自己的 我在这个问题上纠缠了好几天 下面是Dashboard.java的代码 public class Dashboard extends AppCompatActivity { private static final String TAG = "1"; private static final int PERMIS

我第一次尝试制作视频通话应用程序。我正在android studio中使用Agora.io进行视频通话。我面临的问题是我看不到我打电话的人的视频。我完全可以从前面的摄像机中得到我自己的

我在这个问题上纠缠了好几天

下面是Dashboard.java的代码

public class Dashboard extends AppCompatActivity {
private static final String TAG = "1";

private static final int PERMISSION_REQ_ID = 22;

// Permission WRITE_EXTERNAL_STORAGE is not mandatory
// for Agora RTC SDK, just in case if you wanna save
// logs to external sdcard.
private static final String[] REQUESTED_PERMISSIONS = {
        Manifest.permission.READ_PHONE_STATE,
        Manifest.permission.RECORD_AUDIO,
        Manifest.permission.CAMERA,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
};

private RtcEngine mRtcEngine;
private boolean mCallEnd;
private boolean mMuted;

private FrameLayout mLocalContainer;
private RelativeLayout mRemoteContainer;
private SurfaceView mLocalView;
private SurfaceView mRemoteView;

private ImageView mCallBtn;
private ImageView mMuteBtn;
private ImageView mSwitchCameraBtn;

/**
 * Event handler registered into RTC engine for RTC callbacks.
 * Note that UI operations needs to be in UI thread because RTC
 * engine deals with the events in a separate thread.
 */
private final IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() {
    @Override
    public void onJoinChannelSuccess(String channel, final int uid, int elapsed) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
            }
        });
    }

    @Override
    public void onFirstRemoteVideoDecoded(final int uid, int width, int height, int elapsed) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                setupRemoteVideo(uid);
            }
        });
    }

    @Override
    public void onUserOffline(final int uid, int reason) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                onRemoteUserLeft();
            }
        });
    }
};

private void setupRemoteVideo(int uid) {
    // Only one remote video view is available for this
    // tutorial. Here we check if there exists a surface
    // view tagged as this uid.
    int count = mRemoteContainer.getChildCount();
    View view = null;
    for (int i = 0; i < count; i++) {
        View v = mRemoteContainer.getChildAt(i);
        if (v.getTag() instanceof Integer && ((int) v.getTag()) == uid) {
            view = v;
        }
    }

    if (view != null) {
        return;
    }

    mRemoteView = RtcEngine.CreateRendererView(getBaseContext());
    mRemoteContainer.addView(mRemoteView);
    mRtcEngine.setupRemoteVideo(new VideoCanvas(mRemoteView, VideoCanvas.RENDER_MODE_HIDDEN, uid));
    mRemoteView.setTag(uid);
}

private void onRemoteUserLeft() {
    removeRemoteVideo();
}

private void removeRemoteVideo() {
    if (mRemoteView != null) {
        mRemoteContainer.removeView(mRemoteView);
    }
    mRemoteView = null;
}

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

    // Ask for permissions at runtime.
    // This is just an example set of permissions. Other permissions
    // may be needed, and please refer to our online documents.
    if (checkSelfPermission(REQUESTED_PERMISSIONS[0], PERMISSION_REQ_ID) &&
            checkSelfPermission(REQUESTED_PERMISSIONS[1], PERMISSION_REQ_ID) &&
            checkSelfPermission(REQUESTED_PERMISSIONS[2], PERMISSION_REQ_ID) &&
            checkSelfPermission(REQUESTED_PERMISSIONS[3], PERMISSION_REQ_ID)) {
        initEngineAndJoinChannel();
    }
}

private void initUI() {
    mLocalContainer = findViewById(R.id.local_video_view_container);
    mRemoteContainer = findViewById(R.id.remote_video_view_container);

    mCallBtn = findViewById(R.id.btn_call);
    mMuteBtn = findViewById(R.id.btn_mute);
    mSwitchCameraBtn = findViewById(R.id.btn_switch_camera);

}


private boolean checkSelfPermission(String permission, int requestCode) {
    if (ContextCompat.checkSelfPermission(this, permission) !=
            PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, REQUESTED_PERMISSIONS, requestCode);
        return false;
    }

    return true;
}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       @NonNull String[] permissions, @NonNull int[] grantResults) {

    if (requestCode == PERMISSION_REQ_ID) {
        if (grantResults[0] != PackageManager.PERMISSION_GRANTED ||
                grantResults[1] != PackageManager.PERMISSION_GRANTED ||
                grantResults[2] != PackageManager.PERMISSION_GRANTED ||
                grantResults[3] != PackageManager.PERMISSION_GRANTED) {
            showLongToast("Need permissions " + Manifest.permission.RECORD_AUDIO +
                    "/" + Manifest.permission.CAMERA + "/" + Manifest.permission.WRITE_EXTERNAL_STORAGE
                    + "/" + Manifest.permission.READ_PHONE_STATE);
            finish();
            return;
        }

        // Here we continue only if all permissions are granted.
        // The permissions can also be granted in the system settings manually.
        initEngineAndJoinChannel();
    }
}

private void showLongToast(final String msg) {
    this.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
        }
    });
}

private void initEngineAndJoinChannel() {
    // This is our usual steps for joining
    // a channel and starting a call.
    initializeEngine();
    setupVideoConfig();
    setupLocalVideo();
    joinChannel();
}

private void initializeEngine() {
    try {
        mRtcEngine = RtcEngine.create(getBaseContext(), getString(R.string.app_id_agora), mRtcEventHandler);
    } catch (Exception e) {
        Log.e(TAG, Log.getStackTraceString(e));
        throw new RuntimeException("NEED TO check rtc sdk init fatal error\n" + Log.getStackTraceString(e));
    }
}

private void setupVideoConfig() {
    // In simple use cases, we only need to enable video capturing
    // and rendering once at the initialization step.
    // Note: audio recording and playing is enabled by default.
    mRtcEngine.enableVideo();

    // Please go to this page for detailed explanation
    // https://docs.agora.io/en/Video/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_rtc_engine.html#af5f4de754e2c1f493096641c5c5c1d8f
    mRtcEngine.setVideoEncoderConfiguration(new VideoEncoderConfiguration(
            VideoEncoderConfiguration.VD_640x360,
            VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_15,
            VideoEncoderConfiguration.STANDARD_BITRATE,
            VideoEncoderConfiguration.ORIENTATION_MODE.ORIENTATION_MODE_FIXED_PORTRAIT));
}

private void setupLocalVideo() {
    // This is used to set a local preview.
    // The steps setting local and remote view are very similar.
    // But note that if the local user do not have a uid or do
    // not care what the uid is, he can set his uid as ZERO.
    // Our server will assign one and return the uid via the event
    // handler callback function (onJoinChannelSuccess) after
    // joining the channel successfully.
    mLocalView = RtcEngine.CreateRendererView(getBaseContext());
    mLocalView.setZOrderMediaOverlay(true);
    mLocalContainer.addView(mLocalView);
    mRtcEngine.setupLocalVideo(new VideoCanvas(mLocalView, VideoCanvas.RENDER_MODE_HIDDEN, 0));
}

private void joinChannel() {
    // 1. Users can only see each other after they join the
    // same channel successfully using the same app id.
    // 2. One token is only valid for the channel name that
    // you use to generate this token.
    String token = "12312323123123wedsa";
    mRtcEngine.joinChannel(token, "brolChannelbrobro", "Extra Optional Data", 0);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (!mCallEnd) {
        leaveChannel();
    }
    RtcEngine.destroy();
}

private void leaveChannel() {
    mRtcEngine.leaveChannel();
}

public void onLocalAudioMuteClicked(View view) {
    mMuted = !mMuted;
    mRtcEngine.muteLocalAudioStream(mMuted);
    int res = mMuted ? R.drawable.btn_mute : R.drawable.btn_unmute;
    mMuteBtn.setImageResource(res);
}

public void onSwitchCameraClicked(View view) {
    mRtcEngine.switchCamera();
}

public void onCallClicked(View view) {
    if (mCallEnd) {
        startCall();
        mCallEnd = false;
        mCallBtn.setImageResource(R.drawable.btn_endcall);
    } else {
        endCall();
        mCallEnd = true;
        mCallBtn.setImageResource(R.drawable.btn_startcall);
    }

    showButtons(!mCallEnd);
}

private void startCall() {
    setupLocalVideo();
    joinChannel();
}

private void endCall() {
    removeLocalVideo();
    removeRemoteVideo();
    leaveChannel();
}

private void removeLocalVideo() {
    if (mLocalView != null) {
        mLocalContainer.removeView(mLocalView);
    }
    mLocalView = null;
}

private void showButtons(boolean show) {
    int visibility = show ? View.VISIBLE : View.GONE;
    mMuteBtn.setVisibility(visibility);
    mSwitchCameraBtn.setVisibility(visibility);
}
公共类仪表板扩展了AppCompatActivity{
私有静态最终字符串TAG=“1”;
私有静态最终int权限需求ID=22;
//写入外部存储的权限不是强制性的
//对于Agora RTC SDK,以防您想要保存
//记录到外部SD卡。
私有静态最终字符串[]请求的\u权限={
Manifest.permission.READ\u PHONE\u状态,
Manifest.permission.RECORD_音频,
舱单,许可,摄像机,
Manifest.permission.WRITE\u外部存储
};
专用RTC引擎mRtcEngine;
私有布尔mCallEnd;
私有布尔运算;
专用框架布局局部容器;
私有相对物mRemoteContainer;
私人SurfaceView mLocalView;
私人SurfaceView mRemoteView;
私有ImageView mCallBtn;
私有图像视图mMuteBtn;
私有ImageView mSwitchCameraBtn;
/**
*为RTC回调注册到RTC引擎的事件处理程序。
*注意,UI操作需要在UI线程中,因为RTC
*引擎在单独的线程中处理事件。
*/
私有最终IRtcEngineEventHandler mRtcEventHandler=新IRtcEngineEventHandler(){
@凌驾
public void onJoinChannelSuccess(字符串通道、最终整数uid、整数已过){
runOnUiThread(新的Runnable(){
@凌驾
公开募捐{
}
});
}
@凌驾
已解码公共无效onFirstRemoteVideoDecoded(最终整数uid、整数宽度、整数高度、整数经过时间){
runOnUiThread(新的Runnable(){
@凌驾
公开募捐{
设置远程视频(uid);
}
});
}
@凌驾
公共无效onUserOffline(最终输入uid,输入原因){
runOnUiThread(新的Runnable(){
@凌驾
公开募捐{
onRemoteUserLeft();
}
});
}
};
私有void setupRemoteVideo(int-uid){
//只有一个远程视频视图可用于此操作
//教程。这里我们检查是否存在曲面
//标记为此uid的视图。
int count=mRemoteContainer.getChildCount();
视图=空;
for(int i=0;i