本机Android(Java)中的Agora.io
我知道以前有人问过这个问题,但代码后面提到的查询并没有解决这个问题本机Android(Java)中的Agora.io,java,android,agora.io,Java,Android,Agora.io,我知道以前有人问过这个问题,但代码后面提到的查询并没有解决这个问题 package io.agora.tutorials1v1vcall; import android.Manifest; import android.content.pm.PackageManager; import android.os.Bundle; import android.support.annotation.NonNull; import android.support
package io.agora.tutorials1v1vcall;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.SurfaceView;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import io.agora.uikit.logger.LoggerRecyclerView;
import io.agora.rtc.IRtcEngineEventHandler;
import io.agora.rtc.RtcEngine;
import io.agora.rtc.video.VideoCanvas;
import io.agora.rtc.video.VideoEncoderConfiguration;
public class VideoChatViewActivity extends AppCompatActivity {
private static final String TAG = VideoChatViewActivity.class.getSimpleName();
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.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;
// Customized logger view
private LoggerRecyclerView mLogView;
/**
* 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() {
mLogView.logI("Join channel success, uid: " + (uid & 0xFFFFFFFFL));
}
});
}
@Override
public void onFirstRemoteVideoDecoded(final int uid, int width, int height, int elapsed) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mLogView.logI("First remote video decoded, uid: " + (uid & 0xFFFFFFFFL));
setupRemoteVideo(uid);
}
});
}
@Override
public void onUserOffline(final int uid, int reason) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mLogView.logI("User offline, uid: " + (uid & 0xFFFFFFFFL));
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_video_chat_view);
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)) {
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);
mLogView = findViewById(R.id.log_recycler_view);
// Sample logs are optional.
showSampleLogs();
}
private void showSampleLogs() {
mLogView.logI("Welcome to Agora 1v1 video call");
mLogView.logW("You will see custom logs here");
mLogView.logE("You can also use this to show errors");
}
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) {
showLongToast("Need permissions " + Manifest.permission.RECORD_AUDIO +
"/" + Manifest.permission.CAMERA + "/" + Manifest.permission.WRITE_EXTERNAL_STORAGE);
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.agora_app_id), 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 = getString(R.string.agora_access_token);
if (TextUtils.isEmpty(token) || TextUtils.equals(token, "#YOUR ACCESS TOKEN#")) {
token = null; // default, no token
}
mRtcEngine.joinChannel(token, "demoChannel1", "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);
}
}
包io.agora.tutorials1vCall;
导入android.Manifest;
导入android.content.pm.PackageManager;
导入android.os.Bundle;
导入android.support.annotation.NonNull;
导入android.support.v4.app.ActivityCompat;
导入android.support.v4.content.ContextCompat;
导入android.support.v7.app.AppActivity;
导入android.text.TextUtils;
导入android.util.Log;
导入android.view.SurfaceView;
导入android.view.view;
导入android.widget.FrameLayout;
导入android.widget.ImageView;
导入android.widget.RelativeLayout;
导入android.widget.Toast;
导入io.agora.uikit.logger.LoggerRecyclerView;
导入io.agora.rtc.IRTCEngineeEventHandler;
导入io.agora.rtc.rtcnengine;
导入io.agora.rtc.video.VideoCanvas;
导入io.agora.rtc.video.video编码器配置;
公共类VideoChatViewActivity扩展了AppCompatActivity{
私有静态最终字符串标记=VideoChatViewActivity.class.getSimpleName();
私有静态最终int权限需求ID=22;
//写入外部存储的权限不是强制性的
//对于Agora RTC SDK,以防您想要保存
//记录到外部SD卡。
私有静态最终字符串[]请求的\u权限={
Manifest.permission.RECORD_音频,
舱单,许可,摄像机,
Manifest.permission.WRITE\u外部存储
};
专用RTC引擎mRtcEngine;
私有布尔mCallEnd;
私有布尔运算;
专用框架布局局部容器;
私有相对物mRemoteContainer;
私人SurfaceView mLocalView;
私人SurfaceView mRemoteView;
私有ImageView mCallBtn;
私有图像视图mMuteBtn;
私有ImageView mSwitchCameraBtn;
//自定义记录器视图
私人LoggerRecyclerView mLogView;
/**
*为RTC回调注册到RTC引擎的事件处理程序。
*注意,UI操作需要在UI线程中,因为RTC
*引擎在单独的线程中处理事件。
*/
私有最终IRtcEngineEventHandler mRtcEventHandler=新IRtcEngineEventHandler(){
@凌驾
public void onJoinChannelSuccess(字符串通道、最终整数uid、整数已过){
runOnUiThread(新的Runnable(){
@凌驾
公开募捐{
logI(“加入频道成功,uid:+(uid&0xffffffffffl));
}
});
}
@凌驾
已解码公共无效onFirstRemoteVideoDecoded(最终整数uid、整数宽度、整数高度、整数经过时间){
runOnUiThread(新的Runnable(){
@凌驾
公开募捐{
logI(“解码的第一个远程视频,uid:+(uid&0xffffffffffl));
设置远程视频(uid);
}
});
}
@凌驾
公共无效onUserOffline(最终输入uid,输入原因){
runOnUiThread(新的Runnable(){
@凌驾
公开募捐{
logI(“用户脱机,uid:+(uid&0xffffffffffl));
onRemoteUserLeft();
}
});
}
};
私有void setupRemoteVideo(int-uid){
//只有一个远程视频视图可用于此操作
//教程。这里我们检查是否存在曲面
//标记为此uid的视图。
int count=mRemoteContainer.getChildCount();
视图=空;
for(int i=0;i