diff --git a/OneToOne/src/main/AndroidManifest.xml b/OneToOne/src/main/AndroidManifest.xml index 5c79f1afb..902225d5d 100644 --- a/OneToOne/src/main/AndroidManifest.xml +++ b/OneToOne/src/main/AndroidManifest.xml @@ -149,9 +149,11 @@ android:windowSoftInputMode="stateHidden|adjustResize" /> + android:windowSoftInputMode="stateHidden|adjustResize"/> + - () { @Override public void onItemClick(String bean, int position) { - ToastUtil.show(bean + "|" + position); + Bundle bundle = new Bundle(); + bundle.putString("model", CallClientManager.VIDEO_CALL); + bundle.putString("targetId", targetId); + bundle.putString("callId", targetId); + RouteManager.forwardActivity(RouteManager.ACTIVITY_CALL_VIDEO, bundle); } - }).setStrings(Arrays.asList("发起语音通话\n200钻/分钟", "发起视频通话\n100钻/分钟")) + }).setStrings(Collections.singletonList("发起视频通话\n100钻/分钟")) .showDialog(); } @@ -234,7 +241,17 @@ public class ChatMessageFragment extends AbsConversationFragment { @Override public void onSuccess(String token) { super.onSuccess(token); - ToastUtil.show("弹音频聊天"); + new BottomListDialog(mContext).setSelect(new OnItemClickListener() { + @Override + public void onItemClick(String bean, int position) { + Bundle bundle = new Bundle(); + bundle.putString("model", CallClientManager.AUDIO_CALL); + bundle.putString("targetId", targetId); + bundle.putString("callId", targetId); + RouteManager.forwardActivity(RouteManager.ACTIVITY_CALL_AUDIO, bundle); + } + }).setStrings(Collections.singletonList("发起语音通话\n200钻/分钟")) + .showDialog(); } @Override diff --git a/OneToOne/src/main/java/com/shayu/onetoone/activity/message/CallAudioActivity.java b/OneToOne/src/main/java/com/shayu/onetoone/activity/message/CallAudioActivity.java new file mode 100644 index 000000000..827567268 --- /dev/null +++ b/OneToOne/src/main/java/com/shayu/onetoone/activity/message/CallAudioActivity.java @@ -0,0 +1,314 @@ +package com.shayu.onetoone.activity.message; + +import android.os.Bundle; +import android.view.MotionEvent; +import android.view.SurfaceView; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.alibaba.android.arouter.facade.annotation.Route; +import com.lzf.easyfloat.EasyFloat; +import com.lzf.easyfloat.enums.ShowPattern; +import com.lzf.easyfloat.interfaces.OnFloatCallbacks; +import com.makeramen.roundedimageview.RoundedImageView; +import com.shayu.onetoone.R; +import com.shayu.onetoone.activity.AbsOTOActivity; +import com.shayu.onetoone.bean.FollowBean; +import com.shayu.onetoone.bean.UserBean; +import com.shayu.onetoone.dialog.GiftDialog; +import com.shayu.onetoone.listener.OnCallStatusListener; +import com.shayu.onetoone.manager.CallClientManager; +import com.shayu.onetoone.manager.OTONetManager; +import com.shayu.onetoone.manager.RouteManager; +import com.shayu.onetoone.utils.ConversationUtils; +import com.yunbao.common.glide.ImgLoader; +import com.yunbao.common.http.base.HttpCallback; +import com.yunbao.common.utils.DpUtil; +import com.yunbao.common.utils.ToastUtil; +import com.yunbao.common.utils.WordUtil; + + +@Route(path = RouteManager.ACTIVITY_CALL_AUDIO) +public class CallAudioActivity extends AbsOTOActivity implements View.OnClickListener { + private ImageView vague; + private ImageView close; + private ImageView avatar; + private ImageView follow; + private TextView userName; + private TextView userInfo; + private ImageView gift; + private ImageView money; + private ImageView callStop; + private ImageView callMsg; + private TextView callTime; + + private String targetId; + private String callId; + private String model; + + + private OnCallStatusListener onCallStatusListener; + + @Override + protected int getLayoutId() { + return R.layout.activity_call_audio; + } + + @Override + protected void main(Bundle savedInstanceState) { + + Bundle bundle = getIntent().getBundleExtra("bundle"); + if (bundle == null) { + finish(); + return; + } + targetId = bundle.getString("targetId"); + callId = bundle.getString("callId"); + model = bundle.getString("model"); + initView(); + onCallStatusListener = new CallStatusListener(); + CallClientManager.getManager().addOnVoIPCallListener(onCallStatusListener); + initTargetData(); + if (model.equals(CallClientManager.VIDEO_FLOAT)) { + EasyFloat.dismiss("call"); + callMsg.setTag(true); + callMsg.setImageResource(R.mipmap.ic_call_audio_msg); + gift.setVisibility(View.VISIBLE); + money.setVisibility(View.VISIBLE); + } + if (model.equals(CallClientManager.AUDIO_CALL)) { + CallClientManager.getManager().callAudio(targetId); + callMsg.setTag(true); + callMsg.setImageResource(R.mipmap.ic_call_audio_msg); + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + CallClientManager.getManager().removeOnVoIPCallListener(onCallStatusListener); + } + + private void initView() { + // 获取全局变量 + vague = findViewById(R.id.vague); + close = findViewById(R.id.close); + avatar = findViewById(R.id.avatar); + follow = findViewById(R.id.follow); + userName = findViewById(R.id.user_name); + userInfo = findViewById(R.id.user_info); + gift = findViewById(R.id.gift); + money = findViewById(R.id.money); + callStop = findViewById(R.id.call_stop); + callMsg = findViewById(R.id.call_msg); + callTime = findViewById(R.id.call_time); + + callMsg.setImageResource(io.rong.callkit.R.drawable.rc_voip_audio_answer_selector_new); + + // 注册点击事件 + vague.setOnClickListener(this); + close.setOnClickListener(this); + avatar.setOnClickListener(this); + follow.setOnClickListener(this); + userName.setOnClickListener(this); + userInfo.setOnClickListener(this); + gift.setOnClickListener(this); + money.setOnClickListener(this); + callStop.setOnClickListener(this); + callMsg.setOnClickListener(this); + callTime.setOnClickListener(this); + + gift.setVisibility(View.INVISIBLE); + money.setVisibility(View.INVISIBLE); + + } + + private void initTargetData() { + OTONetManager.getInstance(mContext) + .getTargetUserInfo(Integer.parseInt(targetId), new HttpCallback() { + @Override + public void onSuccess(UserBean data) { + userName.setText(data.getUser().getUserNicename()); + userInfo.setText(data.getUser().getSignature()); + ImgLoader.display(mContext, data.getUser().getAvatar(), avatar); + ImgLoader.displayBlur(mContext, data.getUser().getAvatar(), vague, 50); + if (data.getUser().isFollow()) { + follow.setVisibility(View.GONE); + } else { + follow.setVisibility(View.VISIBLE); + } + } + + @Override + public void onError(String error) { + } + }); + } + + private void accept() { + CallClientManager.getManager().acceptCall(targetId); + } + + private void stop() { + CallClientManager.getManager().endCall(); + } + + private void showGift() { + new GiftDialog(mContext) + .setTargetId(targetId) + .showDialog(); + } + private void follow(){ + OTONetManager.getInstance(mContext) + .follow(targetId, new HttpCallback() { + @Override + public void onSuccess(FollowBean data) { + ToastUtil.show(WordUtil.getNewString(R.string.system_tip_success)); + follow.setVisibility(View.GONE); + } + + @Override + public void onError(String error) { + + } + }); + } + + private void showWindow(boolean toChatView) { + ImageView icon = new ImageView(mContext); + icon.setTag(getIntent().getBundleExtra("bundle")); + icon.setImageResource(io.rong.callkit.R.drawable.rc_voip_audio_answer_selector_new); + icon.setLayoutParams(new ViewGroup.LayoutParams(DpUtil.dp2px(40), DpUtil.dp2px(40))); + finish(); + EasyFloat.with(this) + .setLayout(icon) + .setShowPattern(ShowPattern.FOREGROUND) + .setTag("call") + .setDragEnable(true) + .setBorder() + .registerCallbacks(new OnFloatCallbacks() { + OnCallStatusListener windowListener; + + @Override + public void createdResult(boolean b, @Nullable String s, @Nullable View view) { + + } + + @Override + public void show(@NonNull View view) { + view.setOnClickListener(v -> { + Bundle bundle = (Bundle) v.getTag(); + bundle.putString("model", CallClientManager.AUDIO_FLOAT); + RouteManager.forwardActivity(RouteManager.ACTIVITY_CALL_AUDIO, bundle); + }); + windowListener = new WindowCallStatusListener(); + CallClientManager.getManager().addOnVoIPCallListener(windowListener); + } + + @Override + public void hide(@NonNull View view) { + + } + + @Override + public void dismiss() { + CallClientManager.getManager().removeOnVoIPCallListener(windowListener); + } + + @Override + public void touchEvent(@NonNull View view, @NonNull MotionEvent motionEvent) { + + } + + @Override + public void drag(@NonNull View view, @NonNull MotionEvent motionEvent) { + + } + + @Override + public void dragEnd(@NonNull View view) { + + } + }).show(); + if (toChatView) { + ConversationUtils.startConversation(mContext, targetId); + } + } + + private class CallStatusListener extends OnCallStatusListener { + @Override + public void onCallWait(SurfaceView surfaceView) { + + } + + @Override + public void onCallStart(String userId, SurfaceView surfaceView) { + gift.setVisibility(View.VISIBLE); + money.setVisibility(View.VISIBLE); + } + + @Override + public void onCallEnd() { + finish(); + } + + @Override + public void onStartFirstFrame() { + + } + + @Override + public void onTime(String time) { + super.onTime(time); + callTime.setText("通话时长:" + time); + } + } + + private static class WindowCallStatusListener extends OnCallStatusListener { + @Override + public void onCallWait(SurfaceView surfaceView) { + + } + + @Override + public void onCallStart(String userId, SurfaceView surfaceView) { + + } + + @Override + public void onCallEnd() { + EasyFloat.dismiss("call"); + } + + @Override + public void onStartFirstFrame() { + } + } + + @Override + public void onClick(View v) { + int id = v.getId(); + if (id == R.id.call_msg) { + if (v.getTag() == null) { + accept(); + v.setTag(true); + callMsg.setImageResource(R.mipmap.ic_call_audio_msg); + } else { + showWindow(true); + } + } else if (id == R.id.call_stop) { + stop(); + } else if (id == R.id.gift) { + showGift(); + } else if (id == R.id.close) { + showWindow(false); + }else if(id ==R.id.follow){ + follow(); + } + } +} diff --git a/OneToOne/src/main/java/com/shayu/onetoone/activity/message/CallVideoActivity.java b/OneToOne/src/main/java/com/shayu/onetoone/activity/message/CallVideoActivity.java index e52020830..4b4ae62bb 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/activity/message/CallVideoActivity.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/activity/message/CallVideoActivity.java @@ -29,13 +29,20 @@ import com.lzf.easyfloat.interfaces.OnFloatCallbacks; import com.makeramen.roundedimageview.RoundedImageView; import com.shayu.onetoone.R; import com.shayu.onetoone.activity.AbsOTOActivity; +import com.shayu.onetoone.bean.FollowBean; +import com.shayu.onetoone.bean.UserBean; import com.shayu.onetoone.dialog.GiftDialog; import com.shayu.onetoone.listener.OnCallStatusListener; import com.shayu.onetoone.manager.CallClientManager; +import com.shayu.onetoone.manager.OTONetManager; import com.shayu.onetoone.manager.RouteManager; import com.shayu.onetoone.utils.ConversationUtils; +import com.yunbao.common.glide.ImgLoader; +import com.yunbao.common.http.base.HttpCallback; import com.yunbao.common.utils.DpUtil; +import com.yunbao.common.utils.StringUtil; import com.yunbao.common.utils.ToastUtil; +import com.yunbao.common.utils.WordUtil; import java.util.HashMap; @@ -53,6 +60,7 @@ public class CallVideoActivity extends AbsOTOActivity { private ViewGroup myView; private ViewGroup targetView; private ViewGroup callLayout; + private View callWaitLayout; private ViewGroup rootView; private View buttonView; private ImageView callStop; @@ -66,6 +74,7 @@ public class CallVideoActivity extends AbsOTOActivity { private ImageView close; private ImageView follow; private TextView followText; + private TextView callTime; private OnCallStatusListener onCallStatusListener; @@ -97,10 +106,10 @@ public class CallVideoActivity extends AbsOTOActivity { callId = bundle.getString("callId"); model = bundle.getString("model"); - onCallStatusListener = new CallStatusListener(); CallClientManager.getManager().addOnVoIPCallListener(onCallStatusListener); - if (!EasyFloat.isShow("call")) { + + if (!model.equals(CallClientManager.VIDEO_FLOAT)) { RongCallClient.getInstance() .startIncomingPreview( new StartIncomingPreviewCallback() { @@ -108,6 +117,7 @@ public class CallVideoActivity extends AbsOTOActivity { public void onDone(boolean isFront, SurfaceView localVideo) { myView.removeAllViews(); myView.addView(localVideo); + callLayout.setVisibility(View.VISIBLE); } @Override @@ -115,12 +125,17 @@ public class CallVideoActivity extends AbsOTOActivity { } }); } + initButton(buttonView); + if (!StringUtil.isEmpty(callId)) { + CallClientManager.getManager().callVideo(callId); + initWaitView(); + } } @Override protected void onResume() { super.onResume(); - if (EasyFloat.isShow("call") && CallClientManager.getManager().getRemoteVideo(targetId) != null) { + if (model.equals(CallClientManager.VIDEO_FLOAT)) { callLayout.setVisibility(View.GONE); EasyFloat.getFloatView("call").setOnClickListener(null); ((ViewGroup) EasyFloat.getFloatView("call").getParent()).removeAllViews(); @@ -129,11 +144,14 @@ public class CallVideoActivity extends AbsOTOActivity { new Handler(Looper.getMainLooper()) .postDelayed(() -> { - SurfaceView surfaceView = CallClientManager.getManager().getRemoteVideo(targetId); + SurfaceView surfaceView = CallClientManager.getManager().getRemoteVideo(); surfaceView.setLayoutParams(new ViewGroup.LayoutParams(-1, -1)); + initView(); + initButton(buttonView); myView.addView(surfaceView); myView.addView(buttonView); targetView.addView(CallClientManager.getManager().getLocalVideo()); + initTargetData(); }, 300); } @@ -145,9 +163,22 @@ public class CallVideoActivity extends AbsOTOActivity { targetView = findViewById(R.id.target_view); callLayout = findViewById(R.id.rc_voip_two_btn); buttonView = LayoutInflater.from(mContext).inflate(R.layout.view_call_video_item, rootView, false); - initButton(buttonView); - // 为所有View设置点击事件监听器 - setClickListeners(); + callWaitLayout = LayoutInflater.from(mContext).inflate(R.layout.view_call_video_wait, rootView, false); + + } + + private void initWaitView() { + callLayout.setVisibility(View.GONE); + callStop = callWaitLayout.findViewById(R.id.call_stop); + cameraCloseSwitch = callWaitLayout.findViewById(R.id.camera_close_switch); + cameraSwitch = callWaitLayout.findViewById(R.id.camera_switch); + micSwitch = callWaitLayout.findViewById(R.id.mic_switch); + close = callWaitLayout.findViewById(R.id.close); + callStop.setOnClickListener(onClickListener); + cameraCloseSwitch.setOnClickListener(onClickListener); + cameraSwitch.setOnClickListener(onClickListener); + micSwitch.setOnClickListener(onClickListener); + close.setOnClickListener(onClickListener); } private void initButton(View itemView) { @@ -162,6 +193,7 @@ public class CallVideoActivity extends AbsOTOActivity { close = itemView.findViewById(R.id.close); follow = itemView.findViewById(R.id.follow); followText = itemView.findViewById(R.id.follow_text); + callTime = itemView.findViewById(R.id.call_time); // 为所有View设置点击事件监听器 setClickListeners(); } @@ -204,19 +236,19 @@ public class CallVideoActivity extends AbsOTOActivity { } private void switchAudio() { - RongCallClient.getInstance().setEnableLocalAudio(!RongCallClient.getInstance().isLocalAudioEnabled()); - ToastUtil.show("麦克风状态:" + RongCallClient.getInstance().isLocalAudioEnabled()); - micSwitch.setImageResource(RongCallClient.getInstance().isLocalAudioEnabled() ? R.mipmap.ic_call_audio_select : R.mipmap.ic_call_audio); + boolean enabled = RongCallClient.getInstance().isLocalAudioEnabled(); + RongCallClient.getInstance().setEnableLocalAudio(!enabled); + micSwitch.setImageResource(!enabled ? R.mipmap.ic_call_audio_select : R.mipmap.ic_call_audio); } private void showWindow(boolean toChatView) { - CallClientManager.getManager().getRemoteVideo(targetId).setTag(getIntent().getBundleExtra("bundle")); + CallClientManager.getManager().getRemoteVideo().setTag(getIntent().getBundleExtra("bundle")); myView.removeAllViews(); targetView.removeAllViews(); finish(); - CallClientManager.getManager().getRemoteVideo(targetId).setLayoutParams(new ViewGroup.LayoutParams(DpUtil.dp2px(114), DpUtil.dp2px(164))); + CallClientManager.getManager().getRemoteVideo().setLayoutParams(new ViewGroup.LayoutParams(DpUtil.dp2px(114), DpUtil.dp2px(164))); EasyFloat.with(this) - .setLayout(CallClientManager.getManager().getRemoteVideo(targetId)) + .setLayout(CallClientManager.getManager().getRemoteVideo()) .setShowPattern(ShowPattern.FOREGROUND) .setTag("call") .setDragEnable(true) @@ -232,7 +264,9 @@ public class CallVideoActivity extends AbsOTOActivity { @Override public void show(@NonNull View view) { view.setOnClickListener(v -> { - RouteManager.forwardActivity(RouteManager.ACTIVITY_CALL_VIDEO, (Bundle) v.getTag()); + Bundle bundle = (Bundle) v.getTag(); + bundle.putString("model", CallClientManager.VIDEO_FLOAT); + RouteManager.forwardActivity(RouteManager.ACTIVITY_CALL_VIDEO, bundle); }); windowListener = new WindowCallStatusListener(); CallClientManager.getManager().addOnVoIPCallListener(windowListener); @@ -266,10 +300,41 @@ public class CallVideoActivity extends AbsOTOActivity { if (toChatView) { ConversationUtils.startConversation(mContext, targetId); } - - } + private void initTargetData() { + OTONetManager.getInstance(mContext) + .getTargetUserInfo(Integer.parseInt(targetId), new HttpCallback() { + @Override + public void onSuccess(UserBean data) { + ImgLoader.display(mContext, data.getUser().getAvatar(), avatar); + if (data.getUser().isFollow()) { + follow.setVisibility(View.GONE); + } else { + follow.setVisibility(View.VISIBLE); + } + } + + @Override + public void onError(String error) { + } + }); + } + private void follow(){ + OTONetManager.getInstance(mContext) + .follow(targetId, new HttpCallback() { + @Override + public void onSuccess(FollowBean data) { + ToastUtil.show(WordUtil.getNewString(R.string.system_tip_success)); + follow.setVisibility(View.GONE); + } + + @Override + public void onError(String error) { + + } + }); + } private final View.OnClickListener onClickListener = new View.OnClickListener() { @Override public void onClick(View v) { @@ -293,6 +358,8 @@ public class CallVideoActivity extends AbsOTOActivity { showWindow(false); } else if (id == R.id.message) { showWindow(true); + }else if(id == R.id.follow){ + follow(); } } }; @@ -302,10 +369,16 @@ public class CallVideoActivity extends AbsOTOActivity { public void onCallWait(SurfaceView surfaceView) { myView.removeAllViews(); myView.addView(surfaceView); + if (model.equals(CallClientManager.VIDEO_CALL)) { + myView.addView(callWaitLayout); + } } @Override public void onCallStart(String userId, SurfaceView surfaceView) { + initView(); + initButton(buttonView); + initTargetData(); surfaceView.setZOrderOnTop(false); surfaceView.setZOrderMediaOverlay(false); surfaceView.invalidate(); @@ -314,18 +387,11 @@ public class CallVideoActivity extends AbsOTOActivity { surfaceView.setZOrderMediaOverlay(false); surfaceView.invalidate(); }); - if (model.equals(CallClientManager.VIDEO_CALL)) { - targetView.removeAllViews(); - targetView.addView(surfaceView); - myView.removeAllViews(); - myView.addView(CallClientManager.getManager().getLocalVideo()); - } else { - myView.removeAllViews(); - myView.addView(surfaceView); - targetView.removeAllViews(); - targetView.addView(CallClientManager.getManager().getLocalVideo()); - myView.addView(buttonView); - } + myView.removeAllViews(); + myView.addView(surfaceView); + targetView.removeAllViews(); + targetView.addView(CallClientManager.getManager().getLocalVideo()); + myView.addView(buttonView); } @Override @@ -335,13 +401,19 @@ public class CallVideoActivity extends AbsOTOActivity { @Override public void onStartFirstFrame() { - /* CallClientManager.getManager().getRemoteVideo(targetId).setZOrderOnTop(false); - CallClientManager.getManager().getRemoteVideo(targetId).setZOrderMediaOverlay(false); - CallClientManager.getManager().getRemoteVideo(targetId).invalidate();*/ + + } + + @Override + public void onTime(String time) { + super.onTime(time); + if(callTime!=null){ + callTime.setText("通话时长:"+time); + } } } - private class WindowCallStatusListener extends OnCallStatusListener { + private static class WindowCallStatusListener extends OnCallStatusListener { @Override public void onCallWait(SurfaceView surfaceView) { diff --git a/OneToOne/src/main/java/com/shayu/onetoone/listener/OnCallStatusListener.java b/OneToOne/src/main/java/com/shayu/onetoone/listener/OnCallStatusListener.java index 837d60301..3d5bccd10 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/listener/OnCallStatusListener.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/listener/OnCallStatusListener.java @@ -10,4 +10,7 @@ public abstract class OnCallStatusListener { public abstract void onCallEnd(); public abstract void onStartFirstFrame(); + public void onTime(String time){ + + } } diff --git a/OneToOne/src/main/java/com/shayu/onetoone/manager/CallClientManager.java b/OneToOne/src/main/java/com/shayu/onetoone/manager/CallClientManager.java index 73182e797..07a945d20 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/manager/CallClientManager.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/manager/CallClientManager.java @@ -2,22 +2,23 @@ package com.shayu.onetoone.manager; import android.Manifest; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; import android.text.TextUtils; import android.view.SurfaceView; import com.blankj.utilcode.util.PermissionUtils; import com.shayu.onetoone.listener.OnCallStatusListener; -import com.yunbao.common.CommonAppContext; -import com.yunbao.common.manager.IMLoginManager; import com.yunbao.common.utils.ToastUtil; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Timer; +import java.util.TimerTask; import io.rong.callkit.util.CallKitUtils; -import io.rong.calllib.CallUserProfile; import io.rong.calllib.IRongCallListener; import io.rong.calllib.IRongReceivedCallListener; import io.rong.calllib.RongCallClient; @@ -31,11 +32,16 @@ import io.rong.imlib.RongIMClient; import io.rong.imlib.model.Conversation; public class CallClientManager { - public static final String VIDEO_RECEIVED_CALL = "receivedCall"; - public static final String VIDEO_CALL = "call"; + public static final String VIDEO_RECEIVED_CALL = "receivedCall";//接听 + public static final String VIDEO_CALL = "call";//拨打 + public static final String VIDEO_FLOAT = "floatWindow";//浮窗 + public static final String AUDIO_RECEIVED_CALL = "receivedCall";//接听 + public static final String AUDIO_CALL = "call";//拨打 + public static final String AUDIO_FLOAT = "floatWindow";//浮窗 private static CallClientManager manager; - // private SurfaceView localVideo, remoteVideo; + private SurfaceView localVideo, remoteVideo; private List listeners; + private CallTimeTask timeTask = null; public static CallClientManager getManager() { if (manager == null) { @@ -50,26 +56,11 @@ public class CallClientManager { } public SurfaceView getLocalVideo() { - RongCallSession session = RongCallClient.getInstance().getCallSession(); - String userId= IMLoginManager.get(CommonAppContext.getTopActivity()).getUserInfo().getId()+""; - for (CallUserProfile profile : session.getParticipantProfileList()) { - if(profile.getUserId().equals(userId)){ - return profile.getVideoView(); - } - - } - return null; + return localVideo; } - public SurfaceView getRemoteVideo(String id) { - RongCallSession session = RongCallClient.getInstance().getCallSession(); - for (CallUserProfile profile : session.getParticipantProfileList()) { - if(profile.getUserId().equals(id)){ - return profile.getVideoView(); - } - - } - return null; + public SurfaceView getRemoteVideo() { + return remoteVideo; } private void init() { @@ -84,6 +75,21 @@ public class CallClientManager { listeners.remove(statusListener); } + private void startTimer() { + if (timeTask != null) { + timeTask.cancel(); + } + timeTask = new CallTimeTask(); + new Timer().schedule(timeTask, 0, 1000); + } + + private void endTimer() { + if (timeTask != null) { + timeTask.cancel(); + } + timeTask = null; + } + public void callVideo(String targetId) { RongCallClient.getInstance().setVoIPCallListener(new CallStatusListener(new OnCallStatusListener() { @Override @@ -91,6 +97,7 @@ public class CallClientManager { for (OnCallStatusListener listener : listeners) { listener.onCallWait(localVideo); } + ToastUtil.show("等待对方接受邀请..."); } @Override @@ -98,6 +105,8 @@ public class CallClientManager { for (OnCallStatusListener listener : listeners) { listener.onCallStart(userId, remoteVideo); } + ToastUtil.show("连接成功"); + startTimer(); } @Override @@ -105,6 +114,7 @@ public class CallClientManager { for (OnCallStatusListener listener : listeners) { listener.onCallEnd(); } + endTimer(); } @Override @@ -119,6 +129,45 @@ public class CallClientManager { RongCallClient.getInstance().startCall(Conversation.ConversationType.PRIVATE, targetId, userIds, null, RongCallCommon.CallMediaType.VIDEO, null); } + public void callAudio(String targetId) { + RongCallClient.getInstance().setVoIPCallListener(new CallStatusListener(new OnCallStatusListener() { + @Override + public void onCallWait(SurfaceView localVideo) { + for (OnCallStatusListener listener : listeners) { + listener.onCallWait(localVideo); + } + ToastUtil.show("等待对方接受邀请..."); + } + + @Override + public void onCallStart(String userId, SurfaceView remoteVideo) { + for (OnCallStatusListener listener : listeners) { + listener.onCallStart(userId, remoteVideo); + } + ToastUtil.show("连接成功"); + startTimer(); + } + + @Override + public void onCallEnd() { + for (OnCallStatusListener listener : listeners) { + listener.onCallEnd(); + } + endTimer(); + } + + @Override + public void onStartFirstFrame() { + for (OnCallStatusListener listener : listeners) { + listener.onStartFirstFrame(); + } + } + })); + List userIds = new ArrayList<>(); + userIds.add(targetId); + RongCallClient.getInstance().startCall(Conversation.ConversationType.PRIVATE, targetId, userIds, null, RongCallCommon.CallMediaType.AUDIO, null); + } + public void acceptCall(String callId) { RongCallClient.getInstance().setVoIPCallListener(new CallStatusListener(new OnCallStatusListener() { @Override @@ -133,6 +182,7 @@ public class CallClientManager { for (OnCallStatusListener listener : listeners) { listener.onCallStart(userId, remoteVideo); } + startTimer(); } @Override @@ -140,6 +190,7 @@ public class CallClientManager { for (OnCallStatusListener listener : listeners) { listener.onCallEnd(); } + endTimer(); } @Override @@ -162,6 +213,50 @@ public class CallClientManager { return RongCallClient.getInstance() != null && RongCallClient.getInstance().getCallSession() != null; } + public boolean isCallVideo(RongCallSession callSession) { + return callSession.getMediaType().equals(RongCallCommon.CallMediaType.VIDEO); + } + + public long getTime(long activeTime) { + return activeTime == 0 ? 0 : (System.currentTimeMillis() - activeTime) / 1000; + } + + private class CallTimeTask extends TimerTask { + Handler handler = new Handler(Looper.getMainLooper()); + + @Override + public void run() { + RongCallSession callSession = RongCallClient.getInstance().getCallSession(); + if (callSession == null) { + cancel(); + timeTask = null; + return; + } + long time = getTime(callSession.getActiveTime()); + String extra; + if (time > 0) { + if (time >= 3600) { + extra = + String.format( + Locale.ROOT, + "%d:%02d:%02d", + time / 3600, + (time % 3600) / 60, + (time % 60)); + } else { + extra = String.format(Locale.ROOT, "%02d:%02d", (time % 3600) / 60, (time % 60)); + } + handler.post(() -> { + for (OnCallStatusListener listener : listeners) { + listener.onTime(extra); + } + }); + + } + + } + } + private static class CallMeListener implements IRongReceivedCallListener { @Override @@ -171,7 +266,11 @@ public class CallClientManager { bundle.putString("targetId", callSession.getTargetId()); bundle.putString("callId", callSession.getCallId()); bundle.putString("sessionId", callSession.getSessionId()); - RouteManager.forwardActivity(RouteManager.ACTIVITY_CALL_VIDEO, bundle); + if (callSession.getMediaType() == RongCallCommon.CallMediaType.VIDEO) { + RouteManager.forwardActivity(RouteManager.ACTIVITY_CALL_VIDEO, bundle); + } else { + RouteManager.forwardActivity(RouteManager.ACTIVITY_CALL_AUDIO, bundle); + } } @Override @@ -191,7 +290,6 @@ public class CallClientManager { } } - private class CallStatusListener implements IRongCallListener { OnCallStatusListener statusListener; private long time = 0; @@ -220,8 +318,11 @@ public class CallClientManager { */ @Override public void onCallOutgoing(RongCallSession callSession, SurfaceView localVideo) { - localVideo.setZOrderOnTop(true); - localVideo.setZOrderMediaOverlay(true); + if (isCallVideo(callSession)) { + localVideo.setZOrderOnTop(true); + localVideo.setZOrderMediaOverlay(true); + CallClientManager.this.localVideo = localVideo; + } statusListener.onCallWait(localVideo); System.out.println("CallStatusListener.onCallOutgoing"); } @@ -235,8 +336,11 @@ public class CallClientManager { */ @Override public void onCallConnected(RongCallSession callSession, SurfaceView localVideo) { - localVideo.setZOrderOnTop(true); - localVideo.setZOrderMediaOverlay(true); + if (isCallVideo(callSession)) { + localVideo.setZOrderOnTop(true); + localVideo.setZOrderMediaOverlay(true); + CallClientManager.this.localVideo = localVideo; + } statusListener.onCallWait(localVideo); } @@ -274,6 +378,7 @@ public class CallClientManager { extra = String.format(Locale.ROOT, "%02d:%02d", (time % 3600) / 60, (time % 60)); } } + if (!TextUtils.isEmpty(senderId)) { CallSTerminateMessage message = new CallSTerminateMessage(); message.setReason(reason); @@ -305,6 +410,8 @@ public class CallClientManager { } } statusListener.onCallEnd(); + CallClientManager.this.remoteVideo = null; + CallClientManager.this.localVideo = null; } @Override @@ -328,17 +435,26 @@ public class CallClientManager { * 如果对端调用{@link RongCallClient#startCall(int, boolean, Conversation.ConversationType, String, List, List, RongCallCommon.CallMediaType, String, StartCameraCallback)} 或 * {@link RongCallClient#acceptCall(String, int, boolean, StartCameraCallback)}开始的音视频通话,则可以使用如下设置改变对端视频流的镜像显示:
*
-         *                                                               public void onRemoteUserJoined(String userId, RongCallCommon.CallMediaType mediaType, int userType, SurfaceView remoteVideo) {
-         *                                                                    if (null != remoteVideo) {
-         *                                                                        ((RongRTCVideoView) remoteVideo).setMirror( boolean);//观看对方视频流是否镜像处理
-         *                                                                    }
-         *                                                               }
-         *                                                               
+ * public void onRemoteUserJoined(String userId, RongCallCommon.CallMediaType mediaType, int userType, SurfaceView remoteVideo) { + * if (null != remoteVideo) { + * ((RongRTCVideoView) remoteVideo).setMirror( boolean);//观看对方视频流是否镜像处理 + * } + * } + * */ @Override public void onRemoteUserJoined(String userId, RongCallCommon.CallMediaType mediaType, int userType, SurfaceView remoteVideo) { + if (mediaType == RongCallCommon.CallMediaType.AUDIO) { + statusListener.onCallStart(userId, null); + return; + } + if (CallClientManager.this.remoteVideo != null) { + statusListener.onCallStart(userId, CallClientManager.this.remoteVideo); + return; + } remoteVideo.setZOrderOnTop(false); remoteVideo.setZOrderMediaOverlay(false); + CallClientManager.this.remoteVideo = remoteVideo; statusListener.onCallStart(userId, remoteVideo); System.out.println("CallStatusListener.onRemoteUserJoined"); } diff --git a/OneToOne/src/main/java/com/shayu/onetoone/manager/RouteManager.java b/OneToOne/src/main/java/com/shayu/onetoone/manager/RouteManager.java index 16e669c3a..965efb403 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/manager/RouteManager.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/manager/RouteManager.java @@ -18,6 +18,7 @@ public class RouteManager { public static final String ACTIVITY_HOME_SEARCH = "/activity/HomeSearchActivity"; public static final String ACTIVITY_HOME_SCREEN = "/activity/HomeScreenActivity"; public static final String ACTIVITY_CALL_VIDEO = "/activity/CallVideoActivity"; + public static final String ACTIVITY_CALL_AUDIO = "/activity/CallVAudioActivity"; public static final String PATH_EDITPROFILE = "/main/EditProfileActivity"; //设置基本资料 diff --git a/OneToOne/src/main/java/com/shayu/onetoone/provider/OTOCallEndMessageItemProvider.java b/OneToOne/src/main/java/com/shayu/onetoone/provider/OTOCallEndMessageItemProvider.java index 733a97bdb..d95de5fbe 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/provider/OTOCallEndMessageItemProvider.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/provider/OTOCallEndMessageItemProvider.java @@ -1,185 +1,33 @@ package com.shayu.onetoone.provider; -import static io.rong.calllib.RongCallCommon.CallDisconnectedReason.HANGUP; import static io.rong.calllib.RongCallCommon.CallDisconnectedReason.OTHER_DEVICE_HAD_ACCEPTED; import android.content.Context; -import android.content.Intent; -import android.graphics.drawable.Drawable; +import android.os.Bundle; import android.text.Spannable; import android.text.SpannableString; -import android.text.TextUtils; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; import android.widget.Toast; import com.shayu.onetoone.R; +import com.shayu.onetoone.manager.CallClientManager; +import com.shayu.onetoone.manager.RouteManager; import com.yunbao.common.utils.ToastUtil; -import io.rong.callkit.RongCallAction; +import java.util.List; + +import io.rong.callkit.CallEndMessageItemProvider; import io.rong.callkit.util.CallKitUtils; import io.rong.calllib.RongCallClient; import io.rong.calllib.RongCallCommon; import io.rong.calllib.RongCallSession; import io.rong.calllib.message.CallSTerminateMessage; -import io.rong.imkit.conversation.messgelist.provider.BaseMessageItemProvider; import io.rong.imkit.model.UiMessage; import io.rong.imkit.widget.adapter.IViewProviderListener; import io.rong.imkit.widget.adapter.ViewHolder; -import io.rong.imlib.model.Message; import io.rong.imlib.model.MessageContent; -import java.util.List; -import java.util.Locale; -public class OTOCallEndMessageItemProvider extends BaseMessageItemProvider { - @Override - protected io.rong.imkit.widget.adapter.ViewHolder onCreateMessageContentViewHolder( - ViewGroup parent, int viewType) { - View textView = - LayoutInflater.from(parent.getContext()) - .inflate(R.layout.rc_text_message_item, parent, false); - return new ViewHolder(parent.getContext(), textView); - } - - @Override - protected void bindMessageContentViewHolder( - ViewHolder holder, - ViewHolder parentHolder, - CallSTerminateMessage callSTerminateMessage, - UiMessage uiMessage, - int position, - List list, - IViewProviderListener listener) { - Message message = uiMessage.getMessage(); - final TextView view = holder.getView(io.rong.imkit.R.id.rc_text); - if (message.getMessageDirection() == Message.MessageDirection.SEND) { - view.setBackgroundResource(R.drawable.rc_ic_bubble_right); - } else { - view.setBackgroundResource(R.drawable.rc_ic_bubble_left); - } - - RongCallCommon.CallMediaType mediaType = callSTerminateMessage.getMediaType(); - String direction = callSTerminateMessage.getDirection(); - Drawable drawable = null; - - String msgContent = ""; - switch (callSTerminateMessage.getReason()) { - case CANCEL: - msgContent = view.getResources().getString(R.string.rc_voip_mo_cancel); - break; - case REJECT: - msgContent = view.getResources().getString(R.string.rc_voip_mo_reject); - break; - case NO_RESPONSE: - case BUSY_LINE: - msgContent = view.getResources().getString(R.string.rc_voip_mo_no_response); - break; - case REMOTE_BUSY_LINE: - msgContent = view.getResources().getString(R.string.rc_voip_mt_busy); - break; - case REMOTE_CANCEL: - msgContent = view.getResources().getString(R.string.rc_voip_mt_cancel); - break; - case REMOTE_REJECT: - msgContent = view.getResources().getString(R.string.rc_voip_mt_reject); - break; - case REMOTE_NO_RESPONSE: - msgContent = view.getResources().getString(R.string.rc_voip_mt_no_response); - break; - case NETWORK_ERROR: - case REMOTE_NETWORK_ERROR: - case INIT_VIDEO_ERROR: - msgContent = view.getResources().getString(R.string.rc_voip_call_interrupt); - break; - case OTHER_DEVICE_HAD_ACCEPTED: - msgContent = view.getResources().getString(R.string.rc_voip_call_other); - break; - case SERVICE_NOT_OPENED: - case REMOTE_ENGINE_UNSUPPORTED: - msgContent = view.getResources().getString(R.string.rc_voip_engine_notfound); - break; - case REJECTED_BY_BLACKLIST: - msgContent = - view.getResources().getString(R.string.rc_voip_mo_rejected_by_blocklist); - break; - default: - String mo_reject = view.getResources().getString(R.string.rc_voip_mo_reject); - String mt_reject = view.getResources().getString(R.string.rc_voip_mt_reject); - String extra = callSTerminateMessage.getExtra(); - String timeRegex = "([0-9]?[0-9]:)?([0-5][0-9]:)?([0-5][0-9])$"; - if (!TextUtils.isEmpty(extra)) { - boolean val = extra.matches(timeRegex); - if (val) { - msgContent = - view.getResources().getString(R.string.rc_voip_call_time_length); - msgContent += extra; - } else { - msgContent = - view.getResources().getString(R.string.rc_voip_call_time_length); - } - } else { - msgContent = - callSTerminateMessage.getReason() == HANGUP ? mo_reject : mt_reject; - } - break; - } - - view.setText(msgContent); - view.setCompoundDrawablePadding(15); - - if (mediaType.equals(RongCallCommon.CallMediaType.VIDEO)) { - if (direction != null && direction.equals("MO")) { - drawable = view.getResources().getDrawable(R.drawable.rc_voip_video_right); - drawable.setBounds( - 0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); - view.setCompoundDrawablesRelative(null, null, drawable, null); - view.setTextColor(view.getResources().getColor(R.color.rc_voip_color_right)); - } else { - drawable = view.getResources().getDrawable(R.drawable.rc_voip_video_left); - drawable.setBounds( - 0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); - view.setCompoundDrawablesRelative(drawable, null, null, null); - view.setTextColor(view.getResources().getColor(R.color.rc_voip_color_left)); - } - } else { - if (direction != null && direction.equals("MO")) { - if (callSTerminateMessage.getReason().equals(HANGUP) - || callSTerminateMessage - .getReason() - .equals(RongCallCommon.CallDisconnectedReason.REMOTE_HANGUP)) { - drawable = - view.getResources() - .getDrawable(R.drawable.rc_voip_audio_right_connected); - } else { - drawable = - view.getResources().getDrawable(R.drawable.rc_voip_audio_right_cancel); - } - drawable.setBounds( - 0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); - view.setCompoundDrawablesRelative(null, null, drawable, null); - view.setTextColor(view.getResources().getColor(R.color.rc_voip_color_right)); - } else { - if (callSTerminateMessage.getReason().equals(HANGUP) - || callSTerminateMessage - .getReason() - .equals(RongCallCommon.CallDisconnectedReason.REMOTE_HANGUP)) { - drawable = - view.getResources() - .getDrawable(R.drawable.rc_voip_audio_left_connected); - } else { - drawable = - view.getResources().getDrawable(R.drawable.rc_voip_audio_left_cancel); - } - drawable.setBounds( - 0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); - view.setCompoundDrawablesRelative(drawable, null, null, null); - view.setTextColor(view.getResources().getColor(R.color.rc_voip_color_left)); - } - } - } +public class OTOCallEndMessageItemProvider extends CallEndMessageItemProvider { @Override protected boolean onItemClick( @@ -192,7 +40,6 @@ public class OTOCallEndMessageItemProvider extends BaseMessageItemProvider 0) { @@ -221,19 +68,17 @@ public class OTOCallEndMessageItemProvider extends BaseMessageItemProvider + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OneToOne/src/main/res/layout/dialog_bottom_list.xml b/OneToOne/src/main/res/layout/dialog_bottom_list.xml index 05b48de55..b09685671 100644 --- a/OneToOne/src/main/res/layout/dialog_bottom_list.xml +++ b/OneToOne/src/main/res/layout/dialog_bottom_list.xml @@ -34,6 +34,6 @@ app:layout_constraintHorizontal_bias="1.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/recyclerView" - tools:text="取消" /> + android:text="取消" /> \ No newline at end of file diff --git a/OneToOne/src/main/res/layout/view_call_video_item.xml b/OneToOne/src/main/res/layout/view_call_video_item.xml index d36c6a597..7648321cc 100644 --- a/OneToOne/src/main/res/layout/view_call_video_item.xml +++ b/OneToOne/src/main/res/layout/view_call_video_item.xml @@ -48,6 +48,17 @@ app:layout_constraintStart_toStartOf="parent" app:srcCompat="@mipmap/ic_call_video_select" /> + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OneToOne/src/main/res/mipmap-xxhdpi/ic_call_audio_msg.png b/OneToOne/src/main/res/mipmap-xxhdpi/ic_call_audio_msg.png new file mode 100644 index 000000000..b4e6f3318 Binary files /dev/null and b/OneToOne/src/main/res/mipmap-xxhdpi/ic_call_audio_msg.png differ diff --git a/OneToOne/src/main/res/mipmap-xxhdpi/ic_call_money.png b/OneToOne/src/main/res/mipmap-xxhdpi/ic_call_money.png index fa1fe63a3..5e40a21c3 100644 Binary files a/OneToOne/src/main/res/mipmap-xxhdpi/ic_call_money.png and b/OneToOne/src/main/res/mipmap-xxhdpi/ic_call_money.png differ diff --git a/common/src/main/java/com/yunbao/common/glide/ImgLoader.java b/common/src/main/java/com/yunbao/common/glide/ImgLoader.java index c6f6c01c8..b7f48aa3e 100644 --- a/common/src/main/java/com/yunbao/common/glide/ImgLoader.java +++ b/common/src/main/java/com/yunbao/common/glide/ImgLoader.java @@ -321,6 +321,23 @@ public class ImgLoader { } builder.into(imageView); } + public static void displayBlur(Context context, String url, ImageView imageView,int radius) { + displayBlur(context, url, imageView,-1,-1,radius); + } + public static void displayBlur(Context context, String url, ImageView imageView, int width, int height,int radius) { + if (!contextIsExist(context)) { + return; + } + + RequestBuilder builder = Glide.with(context) + .load(url) + .thumbnail(thumbnail) + .apply(RequestOptions.bitmapTransform(new BlurTransformation(radius))); + if (width != -1 && height != -1) { + builder = builder.override(width, height); + } + builder.into(imageView); + } /** * 显示模糊的毛玻璃图片