Merge branch 'dev_random_pk'

# Conflicts:
#	common/src/main/res/values/strings.xml
#	config.gradle
#	live/src/main/java/com/yunbao/live/activity/LiveRyAnchorActivity.java
#	live/src/main/java/com/yunbao/live/presenter/LiveRyLinkMicPkPresenter.java
#	live/src/main/java/com/yunbao/live/socket/SocketRyClient.java
This commit is contained in:
2022-12-09 09:30:17 +08:00
54 changed files with 2956 additions and 123 deletions

View File

@@ -83,6 +83,9 @@ public class CommonAppContext extends MultiDexApplication {
}
public static Activity getTopActivity() {
return activityWeakReference.get();
}
@Override
protected void attachBaseContext(Context base) {
@@ -100,7 +103,7 @@ public class CommonAppContext extends MultiDexApplication {
@Override
public void onActivityStarted(Activity activity) {
mCount++;
activityWeakReference=new WeakReference<>(activity);
activityWeakReference = new WeakReference<>(activity);
if (!mFront) {
mFront = true;
L.e("AppContext------->处于前台");

View File

@@ -132,6 +132,7 @@ public class Constants {
public static final int LIVE_FUNC_MIC = 2013;//語音
public static final int LIVE_FUNC_WKS = 2014;//語音
public static final int LIVE_FUNC_ZSLK = 2015;//語音
public static final int LIVE_FUNC_RANDOM_PK = 2016;//随机PK
//socket
public static final String SOCKET_CONN = "conn";
@@ -145,6 +146,7 @@ public class Constants {
public static final String SOCKET_ALL_SERVER_NOTIFY = "AllServerNotify";//全服通知
public static final String SOCKET_SEND_BARRAGE = "SendBarrage";//发弹幕
public static final String SOCKET_LIVE_DRPK = "LiveDRPK";//多人PK
public static final String SOCKET_LIVE_DRPK_RANDOM = "LiveRandomPK";//多人PK
public static final String SOCKET_LEAVE_ROOM = "disconnect";//用户离开房间
public static final String SOCKET_LIVE_END = "StartEndLive";//主播关闭直播
public static final String SOCKET_SYSTEM = "SystemNot";//系统消息

View File

@@ -73,7 +73,7 @@ public class WebViewActivity extends AbsActivity {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
params.topMargin = DpUtil.dp2px(1);
// mWebView.setLayoutParams(params);
// mWebView.setLayoutParams(params);
//mWebView.setOverScrollMode(View.OVER_SCROLL_NEVER);
mWebView.setWebViewClient(new WebViewClient() {
@Override
@@ -96,9 +96,11 @@ public class WebViewActivity extends AbsActivity {
if (url.contains("for")) {
mWebView.loadUrl("javascript:goAnchorTab()");
}
//屏幕高度-ft_title的paddingTop
int height = DeviceUtils.getScreenHeight(mContext)-DpUtil.dp2px(24);
view.loadUrl("javascript:window.androidObject.setHeight("+height+",0,false)");
//真实屏幕高度-(ft_title的高度+导航栏高度)
int height = DeviceUtils.getScreenRealHeight(mContext) - DpUtil.dp2px(72) - getCurrentNavigationBarHeight(mContext);
if (!navigationGestureEnabled(mContext)) {
view.loadUrl("javascript:window.androidObject.setHeight(" + height + ",0,false)");
}
}
});

View File

@@ -0,0 +1,23 @@
package com.yunbao.common.bean;
public class HttpCallbackModel extends BaseModel{
private int code;
private String msg;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}

View File

@@ -0,0 +1,89 @@
package com.yunbao.common.bean;
import com.google.gson.annotations.SerializedName;
/**
* 随机PK UserBean
*/
public class RandomPkUserBean extends UserBean {
@SerializedName("is_pk")
private int pk;
@SerializedName("isattention")
private String attention;
@SerializedName("user_nicename")
private String userNiceName;
public RandomPkUserBean() {
}
public boolean isPk() {
return pk==1;
}
public boolean isAttention() {
return attention.equals("1");
}
public String getAttention() {
return attention;
}
public void setAttention(String attention) {
this.attention = attention;
}
public int getPk() {
return pk;
}
public void setPk(int pk) {
this.pk = pk;
}
@Override
public String getUserNiceName() {
return userNiceName;
}
@Override
public void setUserNiceName(String userNiceName) {
this.userNiceName = userNiceName;
}
@Override
public String toString() {
return "RandomPkUserBean{" +
"pk=" + pk +
", attention='" + attention + '\'' +
", userNiceName='" + userNiceName + '\'' +
", id='" + id + '\'' +
", userNiceName='" + userNiceName + '\'' +
", avatar='" + avatar + '\'' +
", avatarThumb='" + avatarThumb + '\'' +
", sex=" + sex +
", signature='" + signature + '\'' +
", coin='" + coin + '\'' +
", gold='" + gold + '\'' +
", votes='" + votes + '\'' +
", consumption='" + consumption + '\'' +
", votestotal='" + votestotal + '\'' +
", province='" + province + '\'' +
", city='" + city + '\'' +
", location='" + location + '\'' +
", birthday='" + birthday + '\'' +
", level=" + level +
", levelAnchor=" + levelAnchor +
", lives=" + lives +
", follows=" + follows +
", fans=" + fans +
", vip=" + vip +
", liang=" + liang +
", car=" + car +
", medal_level=" + medal_level +
", medal_name='" + medal_name + '\'' +
", Dress=" + Dress +
", noble_id='" + noble_id + '\'' +
", yuanbao='" + yuanbao + '\'' +
'}';
}
}

View File

@@ -0,0 +1,128 @@
package com.yunbao.common.bean;
import com.google.gson.annotations.SerializedName;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
public class RankPkInfoBean extends BaseModel {
private int id;
@SerializedName("start_time")
private String startTime;
@SerializedName("end_time")
private String endTime;
@SerializedName("pk_start_hour1")
private String pkStartHour1;
@SerializedName("pk_end_hour1")
private String pkEndHour1;
@SerializedName("pk_start_hour2")
private String pkStartHour2;
@SerializedName("pk_end_hour2")
private String pkEndHour2;
public RankPkInfoBean() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getStartTime() {
return startTime;
}
public void setStartTime(String startTime) {
this.startTime = startTime;
}
public String getEndTime() {
return endTime;
}
public void setEndTime(String endTime) {
this.endTime = endTime;
}
public String getPkStartHour1() {
return pkStartHour1;
}
public void setPkStartHour1(String pkStartHour1) {
this.pkStartHour1 = pkStartHour1;
}
public String getPkEndHour1() {
return pkEndHour1;
}
public void setPkEndHour1(String pkEndHour1) {
this.pkEndHour1 = pkEndHour1;
}
public String getPkStartHour2() {
return pkStartHour2;
}
public void setPkStartHour2(String pkStartHour2) {
this.pkStartHour2 = pkStartHour2;
}
public String getPkEndHour2() {
return pkEndHour2;
}
public void setPkEndHour2(String pkEndHour2) {
this.pkEndHour2 = pkEndHour2;
}
/**
* 判断是否在排位赛时间范围内
*/
public boolean isRankPKTime() {
try {
Date now =new Date();
Date startDate = simpleDateToDate(startTime, "yyyy-MM-dd HH:mm:ss");
Date endDate = simpleDateToDate(endTime, "yyyy-MM-dd HH:mm:ss");
if (startDate == null || endDate == null) {
return false;
}
Calendar calendarStart = Calendar.getInstance(Locale.CHINA);
Calendar calendarEnd = Calendar.getInstance(Locale.CHINA);
Calendar calendarNow = Calendar.getInstance(Locale.CHINA);
calendarNow.setTime(now);
calendarStart.setTime(startDate);
calendarEnd.setTime(endDate);
if (calendarStart.before(calendarNow) && calendarEnd.after(calendarNow)) {
calendarNow.setTime(simpleDateToDate(dateToSimpleDate(now,"HH:mm:ss"),"HH:mm:ss"));
calendarStart.setTime(simpleDateToDate(pkStartHour1, "HH:mm:ss"));
calendarEnd.setTime(simpleDateToDate(pkEndHour1, "HH:mm:ss"));
if (calendarStart.before(calendarNow) && calendarEnd.after(calendarNow)) {
return true;
} else {
calendarNow.setTime(simpleDateToDate(dateToSimpleDate(now,"HH:mm:ss"),"HH:mm:ss"));
calendarStart.setTime(simpleDateToDate(pkStartHour2, "HH:mm:ss"));
calendarEnd.setTime(simpleDateToDate(pkEndHour2, "HH:mm:ss"));
return calendarStart.before(calendarNow) && calendarEnd.after(calendarNow);
}
}
} catch (ParseException e) {
e.printStackTrace();
}
return false;
}
private Date simpleDateToDate(String time, String pattern) throws ParseException {
return new SimpleDateFormat(pattern, Locale.CHINA).parse(time);
}
private String dateToSimpleDate(Date date,String pattern){
return new SimpleDateFormat(pattern,Locale.CHINA).format(date);
}
}

View File

@@ -61,6 +61,26 @@ public class UserBean implements Parcelable {
private int praise;
//是否隐藏
private boolean isHide = false;
//是否为随机PK仅在主播PK时使用
private boolean randomPk;
//随机天梯排位赛PK img仅在主播PK时使用
private String mRankPkImgUrl;
public boolean isRandomPk() {
return randomPk;
}
public void setRandomPk(boolean randomPk) {
this.randomPk = randomPk;
}
public String getRankPkImgUrl() {
return mRankPkImgUrl;
}
public void setRankPkImgUrl(String mRankPkImgUrl) {
this.mRankPkImgUrl = mRankPkImgUrl;
}
public boolean isHide() {
return isHide;

View File

@@ -9,6 +9,7 @@ import com.yunbao.common.bean.CustomSidebarInfoModel;
import com.yunbao.common.bean.EnterRoomNewModel;
import com.yunbao.common.bean.FaceBookUpModel;
import com.yunbao.common.bean.HourRank;
import com.yunbao.common.bean.HttpCallbackModel;
import com.yunbao.common.bean.IMLoginModel;
import com.yunbao.common.bean.LinkMicUserBeanV2;
import com.yunbao.common.bean.LiveInfoModel;
@@ -18,6 +19,8 @@ import com.yunbao.common.bean.NewPeopleInfo;
import com.yunbao.common.bean.NobleRankHideUserListModel;
import com.yunbao.common.bean.NobleTrumpetModel;
import com.yunbao.common.bean.PkRankBean;
import com.yunbao.common.bean.RandomPkUserBean;
import com.yunbao.common.bean.RankPkInfoBean;
import com.yunbao.common.bean.SearchModel;
import com.yunbao.common.bean.SetAttentsModel;
import com.yunbao.common.bean.SlideInBannerModel;
@@ -177,7 +180,7 @@ public interface PDLiveApi {
* 获取多人连麦列表
*/
@GET("/api/public/?service=live.getDrLm")
Observable<ResponseModel<List<LinkMicUserBeanV2>>> getDrLm(@Query("uid")String uid);
Observable<ResponseModel<List<LinkMicUserBeanV2>>> getDrLm(@Query("uid") String uid);
/**
* 获取日榜、周榜数据
@@ -286,8 +289,9 @@ public interface PDLiveApi {
Observable<ResponseModel<BaseModel>> delDrLm();
/**
* 多人连麦-踢出用户
* @param uid 对方uid
* 多人连麦-踢出用户
*
* @param uid 对方uid
* @param roomId 当前房间号
*/
@GET("/api/public/?service=Live.killDrLm")
@@ -338,4 +342,56 @@ public interface PDLiveApi {
@Query("GroupId") String GroupId,
@Query("stream") String stream
);
/**
* 获取随机PK开关
*
* @return 1=开0=关
*/
@GET("/api/public/?service=Livepk.getRandomPKType")
Observable<ResponseModel<List<Integer>>> getRandomPkSwitch();
/**
* 设置随机PK开关
* @param pk 1=开0=关
*/
@GET("/api/public/?service=Livepk.setRandomPKType")
Observable<ResponseModel<List<BaseModel>>> changeRandomPkSwitch(@Query("random_pk") int pk);
/**
* 获取随机PK次数
*/
@GET("/api/public/?service=Livepk.getRandomPKType")
Observable<ResponseModel<Integer>> getRandomPkNumber();
/**
* 发起随机PK
*/
@GET("/api/public/?service=Livepk.setRandomPK")
Observable<ResponseModel<String>> randomPK();
/**
* 随机PK后调用接口给后台记录
*/
@GET("/api/public/?service=Livepk.startRandomPK")
Observable<ResponseModel<BaseModel>> startRandomPK(@Query("pkuid")String pkuid);
/**
* 自由PK开始后调用接口扣掉次数
*/
@GET("/api/public/?service=Livepk.setActivePkNum")
Observable<ResponseModel<BaseModel>> setRandomPkNum();
/**
* 随机PK搜索用户
* @param cs 简体关键字/uid
* @param ct 繁体关键字/uid
*/
@GET("/api/public/?service=Livepk.searchUser")
Observable<ResponseModel<List<RandomPkUserBean>>> randomPkSearchUser(@Query("jian_key")String cs,@Query("fan_key")String ct);
/**
* 拒绝随机PK
*/
@GET("/api/public/?service=Livepk.setBanRandomPK")
Observable<ResponseModel<BaseModel>> setBanRandomPK();
/**
* 拒绝随机PK
*/
@GET("/api/public/?service=Ranking.getRankingInfo")
Observable<ResponseModel<RankPkInfoBean>> getRankingInfo();
}

View File

@@ -4,6 +4,7 @@ import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import com.yunbao.common.CommonAppConfig;
import com.yunbao.common.Constants;
import com.yunbao.common.R;
import com.yunbao.common.bean.ActiveModel;
@@ -11,6 +12,7 @@ import com.yunbao.common.bean.BaseModel;
import com.yunbao.common.bean.CheckLiveModel;
import com.yunbao.common.bean.CustomSidebarInfoModel;
import com.yunbao.common.bean.EnterRoomNewModel;
import com.yunbao.common.bean.HttpCallbackModel;
import com.yunbao.common.bean.LinkMicUserBean;
import com.yunbao.common.bean.LinkMicUserBeanV2;
import com.yunbao.common.bean.LiveInfoModel;
@@ -18,6 +20,8 @@ import com.yunbao.common.bean.LiveRoomActivityBanner;
import com.yunbao.common.bean.NobleRankHideUserListModel;
import com.yunbao.common.bean.NobleTrumpetModel;
import com.yunbao.common.bean.PkRankBean;
import com.yunbao.common.bean.RandomPkUserBean;
import com.yunbao.common.bean.RankPkInfoBean;
import com.yunbao.common.bean.SetAttentsModel;
import com.yunbao.common.bean.StarChallengeStatusModel;
import com.yunbao.common.bean.VipModel;
@@ -484,6 +488,9 @@ public class LiveNetManager {
private Disposable randomPkApi;
/**
* PK排位赛接口
*/
public void getRandomPk(String mLiveUid, String pkUid, HttpCallback<PkRankBean> callback) {
randomPkApi = API.get().pdLiveApi(mContext)
.getPkRanksList(mLiveUid, pkUid)
@@ -501,6 +508,246 @@ public class LiveNetManager {
});
}
/**
* 获取随机PK开关
* 1=开0=关
*/
public void getRandomPkSwitch(HttpCallback<Integer> callback) {
API.get().pdLiveApi(mContext)
.getRandomPkSwitch()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(listResponseModel -> {
if (callback != null) {
callback.onSuccess(listResponseModel.getData().getInfo().get(0));
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
if (callback != null) {
callback.onError(throwable.getMessage());
}
}
}).isDisposed();
}
/**
* 设置随机PK开关
*
* @param pk 1=开0=关
* @param callback @{@link HttpCallbackModel#getCode()} 0=成功
*/
public void changeRandomPkSwitch(int pk, HttpCallback<HttpCallbackModel> callback) {
API.get().pdLiveApi(mContext)
.changeRandomPkSwitch(pk)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Consumer<ResponseModel<List<BaseModel>>>() {
@Override
public void accept(ResponseModel<List<BaseModel>> responseModel) throws Exception {
if (callback != null) {
HttpCallbackModel model = new HttpCallbackModel();
model.setCode(responseModel.getData().getCode());
model.setMsg(responseModel.getData().getMsg());
callback.onSuccess(model);
}
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
if (callback != null) {
callback.onError(throwable.getMessage());
}
}
}).isDisposed();
}
/**
* 获取随机PK次数
*/
public void getRandomPkNumber(HttpCallback<Integer> callback) {
API.get().pdLiveApi(mContext)
.getRandomPkNumber()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Consumer<ResponseModel<Integer>>() {
@Override
public void accept(ResponseModel<Integer> responseModel) throws Exception {
if (callback != null) {
callback.onSuccess(responseModel.getData().getInfo());
}
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
if (callback != null) {
callback.onError(throwable.getMessage());
}
}
}).isDisposed();
}
/**
* 发起随机PK
*/
public void randomPK(HttpCallback<String> callback) {
API.get().pdLiveApi(mContext)
.randomPK()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Consumer<ResponseModel<String>>() {
@Override
public void accept(ResponseModel<String> responseModel) throws Exception {
if (callback != null) {
if(CommonAppConfig.getInstance().getUid().equals("98196")) {
callback.onSuccess("98274");
}else{
callback.onSuccess("98196");
}
// callback.onSuccess(responseModel.getData().getInfo());
}
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
if (callback != null) {
callback.onError(throwable.getMessage());
}
}
}).isDisposed();
}
/**
* 自由PK开始后调用接口扣掉次数
*/
public void setRandomPkNum(HttpCallback<HttpCallbackModel> callback) {
API.get().pdLiveApi(mContext)
.setRandomPkNum()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Consumer<ResponseModel<BaseModel>>() {
@Override
public void accept(ResponseModel<BaseModel> responseModel) throws Exception {
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
if (callback != null) {
callback.onError(throwable.getMessage());
}
}
}).isDisposed();
}
/**
* 随机PK后调用接口给后台记录
*/
public void startRandomPK(String pkuid, HttpCallback<Boolean> callback) {
API.get().pdLiveApi(mContext)
.startRandomPK(pkuid)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Consumer<ResponseModel<BaseModel>>() {
@Override
public void accept(ResponseModel<BaseModel> responseModel) throws Exception {
if (responseModel.getData().getCode() == 0) {
if (callback != null) {
callback.onSuccess(true);
}
} else {
callback.onSuccess(false);
}
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
if (callback != null) {
callback.onError(throwable.getMessage());
}
}
}).isDisposed();
}
/**
* 随机PK后调用接口给后台记录
*
* @param cs 简体关键字/uid
* @param ct 繁体关键字/uid
*/
public void randomPkSearchUser(String cs, String ct, HttpCallback<List<RandomPkUserBean>> callback) {
API.get().pdLiveApi(mContext)
.randomPkSearchUser(cs, ct)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Consumer<ResponseModel<List<RandomPkUserBean>>>() {
@Override
public void accept(ResponseModel<List<RandomPkUserBean>> responseModel) throws Exception {
if (responseModel.getData().getCode() == 0) {
if (callback != null) {
callback.onSuccess(responseModel.getData().getInfo());
}
}
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
if (callback != null) {
callback.onError(throwable.getMessage());
}
}
}).isDisposed();
}
/**
* 拒绝随机PK
*/
public void setBanRandomPK(HttpCallback<HttpCallbackModel> callback) {
API.get().pdLiveApi(mContext)
.setBanRandomPK()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Consumer<ResponseModel<BaseModel>>() {
@Override
public void accept(ResponseModel<BaseModel> responseModel) throws Exception {
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
if (callback != null) {
callback.onError(throwable.getMessage());
}
}
}).isDisposed();
}
/**
* 获取随机排位赛信息
*/
public void getRankPkInfoBean(HttpCallback<RankPkInfoBean> callback) {
API.get().pdLiveApi(mContext)
.getRankingInfo()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Consumer<ResponseModel<RankPkInfoBean>>() {
@Override
public void accept(ResponseModel<RankPkInfoBean> rankPkInfoBeanResponseModel) throws Exception {
if (callback != null) {
callback.onSuccess(rankPkInfoBeanResponseModel.getData().getInfo());
}
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
if (callback != null) {
callback.onError(throwable.getMessage());
}
}
}).isDisposed();
}
/**
* 直播间取消网络请求
*/

View File

@@ -0,0 +1,91 @@
package com.yunbao.common.manager;
import com.yunbao.common.utils.ToastUtil;
import cn.rongcloud.rtc.api.RCRTCRoom;
import cn.rongcloud.rtc.api.callback.IRCRTCResultCallback;
import cn.rongcloud.rtc.base.RTCErrorCode;
/**
* RTC管理类负责管理申请、同意、拒绝PK
*/
public class IMRTCManager {
private static IMRTCManager manager;
private RCRTCRoom rtcRoom;
private IMRTCManager() {
}
public static IMRTCManager getInstance() {
if (manager == null) {
manager = new IMRTCManager();
}
return manager;
}
public void setRtcRoom(RCRTCRoom rtcRoom) {
this.rtcRoom = rtcRoom;
}
/**
* 响应PK请求
* @param liveUid 对方房间号
* @param agree 是否同意
* @param extra 扩展参数
* @param callback 回调
*/
public void responseJoinOtherRoom(String liveUid, boolean agree, String extra, IRCRTCResultCallback callback) {
if (rtcRoom != null) {
/*
inviterRoomId - 邀请者所在房间 id
inviterUserId - 邀请者用户 id
agree - 被邀请者是否同意连麦邀请
inviteeAutoMix - 是否将被邀请者音视频资源发送到邀请人房间中合流
1inviteeAutoMix 为true时
1.1:如果邀请方在发送连麦请求之前发布了资源,当被邀请方加入邀请者房间成功后,服务器会把邀请方流资源合并到被邀请方视图(默认仅悬浮布局合流)上。
1.2:如果邀请方在发送连麦请求之前没有发布资源,将会在邀请方发布资源成功后,服务器才会把邀请方的资源合并到被邀请方视图(默认仅悬浮布局合流)上。
2: 无论为true或false双方都可以使用RCRTCLiveInfo.setMixConfig(RCRTCMixConfig, IRCRTCResultCallback) 方法主动设置合流布局。一旦主动设置过合流布局,后续音视频直播过程中设置的自动合流参数将失效。
extra - 扩展字段,默认为空
*/
rtcRoom.getLocalUser().responseJoinOtherRoom(liveUid, liveUid, agree, agree, extra, callback);
} else {
callback.onFailed(RTCErrorCode.RongRTCCodeIMError);
}
}
/**
* 申请PK
* @param liveUid 对方房间号
* @param inviterAutoMix 是否将邀请者音视频资源发送到被邀请人房间中合流
* @param extra 扩展参数
* @param callback 回调
*/
public void requestJoinOtherRoom(String liveUid,boolean inviterAutoMix,String extra,IRCRTCResultCallback callback){
if(rtcRoom!=null){
/*
inviteeRoomId - 被邀请者所在房间 id
inviteeUserId - 被邀请用户 id
inviterAutoMix - 是否将邀请者音视频资源发送到被邀请人房间中合流
1: inviterAutoMix为true时
1.1:如果被邀请方在加入邀请方房间之前发布了资源,当被邀请方加入邀请者房间成功后,服务器会把被邀请方流资源合并到邀请方视图 ·(默认仅悬浮布局合流)上。
1.2:如果被邀请方在加入邀请方房间之前没有发布过资源,将会在被邀请方发布资源成功后,服务器会把被邀请方流资源合并到邀请方视图(默认仅悬浮布局合流)上。
2:无论为true或false双方都可以使用RCRTCLiveInfo.setMixConfig(RCRTCMixConfig, IRCRTCResultCallback) 方法主动设置合流布局。一旦主动设置过合流布局,后续音视频直播过程中设置的自动合流参数将失效。
extra - 扩展字段,默认为空
*/
rtcRoom.getLocalUser().requestJoinOtherRoom(liveUid, liveUid, inviterAutoMix, extra, new IRCRTCResultCallback() {
@Override
public void onSuccess() {
callback.onSuccess();
}
@Override
public void onFailed(RTCErrorCode errorCode) {
callback.onFailed(errorCode);
}
});
}else{
callback.onFailed(RTCErrorCode.RongRTCCodeIMError);
}
}
}

View File

@@ -0,0 +1,403 @@
package com.yunbao.common.manager;
import android.os.Handler;
import android.os.Looper;
import com.yunbao.common.CommonAppContext;
import com.yunbao.common.bean.RankPkInfoBean;
import com.yunbao.common.http.base.HttpCallback;
import com.yunbao.common.http.live.LiveNetManager;
import com.yunbao.common.utils.ToastUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
/**
* 随机PK管理类
*/
public class RandomPkManager {
public final static int PK_STATUS_DEFAULT = -1;//默认状态,一般为为开始匹配
public final static int PK_STATUS_REQUEST = 0;//已发出匹配请求
public final static int PK_STATUS_START = 1;//匹配到用户
public final static int PK_STATUS_CLOSE = 2;//PK结束
public final static int PK_STATUS_REFUSE = 3;//对方拒绝
public final static int PK_STATUS_EXIT_ING = 4;//退出匹配中
private static RandomPkManager manager;
private int min = -1;//匹配计时器 分钟
private int sec = -1;//匹配计时器 秒钟
private int status = PK_STATUS_DEFAULT;
private Timer timer;
private TimerTask task;
private final List<OnRandomPkTimer> randomPkTimer = new ArrayList<>();//监听器集合
private String pkUid;//对方房间ID
private RankPkInfoBean rankPkInfoBean;//排位赛信息
Handler handler = new Handler(Looper.getMainLooper());
private RandomPkManager() {
getRankInfo();
initTask();
}
public static RandomPkManager getInstance() {
if (manager == null) {
manager = new RandomPkManager();
}
return manager;
}
/**
* 添加监听器
*/
public void addOnRandomPkTimer(OnRandomPkTimer randomPkTimer) {
if (randomPkTimer != null) {
this.randomPkTimer.add(randomPkTimer);
}
}
/**
* 移除监听器
*/
public void unregisterOnRandomPkTimer(OnRandomPkTimer randomPkTimer) {
if (randomPkTimer != null) {
this.randomPkTimer.remove(randomPkTimer);
}
}
/**
* 初始化参数
*/
private void initVal() {
min = -1;
sec = -1;
}
/**
* 初始化任务
*/
private void initTask() {
if (task != null) {
return;
}
task = new TimerTask() {
@Override
public void run() {
status = PK_STATUS_REQUEST;
sec++;
if (sec % 60 == 0) {
min++;
sec = 0;
}
handler.post(() -> {
for (OnRandomPkTimer onRandomPkTimer : randomPkTimer) {
onRandomPkTimer.onTimer(String.format(Locale.CHINA, "%02d:%02d", min, sec));
}
if (sec == 2) {
nextPk();
}
});
}
};
}
/**
* 格式化匹配时间
*/
public String getTimer() {
return String.format(Locale.CHINA, "%02d:%02d", min, sec);
}
/**
* 对方拒绝,开始下一轮匹配
*/
private void nextPk() {
if (status != PK_STATUS_REQUEST && status != PK_STATUS_REFUSE) {
return;
}
LiveNetManager.get(CommonAppContext.getTopActivity())
.randomPK(new HttpCallback<String>() {
@Override
public void onSuccess(String data) {
pkUid = data;
for (OnRandomPkTimer pkTimer : randomPkTimer) {
pkTimer.onStartPK(data);
}
}
@Override
public void onError(String error) {
}
});
}
/**
* 是否为排位赛模式
*/
public boolean isRankModel() {
return rankPkInfoBean != null && rankPkInfoBean.isRankPKTime();
}
/**
* 开始匹配
*/
public boolean start() {
if (status == PK_STATUS_START) {
ToastUtil.show("PK中");
return false;
}
if (status == PK_STATUS_EXIT_ING) {
return false;
}
if (task != null) {
task.cancel();
}
task = null;
initTask();
initVal();
timer = new Timer();
timer.schedule(task, 0, 1000);
return true;
}
private void getRankInfo(){
LiveNetManager.get(CommonAppContext.getTopActivity())
.getRankPkInfoBean(new HttpCallback<RankPkInfoBean>() {
@Override
public void onSuccess(RankPkInfoBean data) {
rankPkInfoBean = data;
}
@Override
public void onError(String error) {
}
});
}
/**
* 通知所有监听者,开始退出匹配
*/
private void callEndPkStart() {
for (OnRandomPkTimer pkTimer : randomPkTimer) {
pkTimer.onPkEndStart();
}
}
/**
* 通知所有监听者,退出匹配倒计时
*/
private void callEndPkTimer(String time) {
for (OnRandomPkTimer pkTimer : randomPkTimer) {
pkTimer.onPkEndTimer(time);
}
}
/**
* 通知所有监听者,退出匹配成功
*/
private void callEndPkSuccess() {
for (OnRandomPkTimer pkTimer : randomPkTimer) {
pkTimer.onPkEndSuccess();
}
status = PK_STATUS_DEFAULT;
rankPkInfoBean = null;
}
private int exitTimer;
/**
* 退出匹配
*/
public void exitPk() {
if (status == PK_STATUS_EXIT_ING) {
return;
}
callEndPkStart();
status = PK_STATUS_EXIT_ING;
exitTimer = 11;
new Timer().schedule(new TimerTask() {
Handler handler = new Handler(Looper.getMainLooper());
@Override
public void run() {
handler.post(() -> {
exitTimer--;
callEndPkTimer(exitTimer + "");
if (exitTimer == 0) {
end();
callEndPkSuccess();
cancel();
}
});
}
}, 0, 1000);
}
/**
* 退出连麦
*/
public void end() {
if (task != null) {
task.cancel();
}
task = null;
status = PK_STATUS_DEFAULT;
pkUid = null;
callEnd();
}
/**
* 是否正在匹配中
*/
public boolean isRequestPk() {
return status == PK_STATUS_REQUEST;
}
/**
* 通知所有监听者,结束匹配
*/
private void callEnd() {
if (task != null) {
task.cancel();
task = null;
}
handler.post(() -> {
for (OnRandomPkTimer pkTimer : randomPkTimer) {
pkTimer.onPkEnd();
}
});
}
/**
* 通知所有监听者,开始匹配
*/
private void callStart() {
if (task != null) {
task.cancel();
task = null;
}
handler.post(() -> {
for (OnRandomPkTimer pkTimer : randomPkTimer) {
pkTimer.onPking();
}
});
LiveNetManager.get(CommonAppContext.getTopActivity())
.startRandomPK(pkUid, new HttpCallback<Boolean>() {
@Override
public void onSuccess(Boolean data) {
}
@Override
public void onError(String error) {
}
});
}
/**
* 通知所有监听者对方拒绝PK
*/
private void callRefuse() {
handler.post(() -> {
for (OnRandomPkTimer pkTimer : randomPkTimer) {
pkTimer.onRefuse();
}
});
}
/**
* 设置PK状态
*/
public void setPkStatus(int status) {
if (this.status == PK_STATUS_DEFAULT || this.status == PK_STATUS_EXIT_ING) {//默认状态下不响应随机PK接口
return;
}
this.status = status;
switch (status) {
case PK_STATUS_START:
callStart();
break;
case PK_STATUS_CLOSE:
callEnd();
break;
case PK_STATUS_REFUSE:
//callRefuse();
nextPk();
break;
}
}
/**
* 是否正在退出匹配中
*/
public boolean isExiting() {
return status == PK_STATUS_EXIT_ING;
}
/**
* 获取退出匹配倒计时
*/
public String getExitTimer() {
return exitTimer + "";
}
public static abstract class OnRandomPkTimer {
/**
* 匹配倒计时
*/
public void onTimer(String time) {
}
/**
* 匹配到对方
* @param pkUid 对方uid
*/
public void onStartPK(String pkUid) {
}
/**
* 匹配中
*/
public void onPking() {
}
/**
* 连麦结束
*/
public void onPkEnd() {
}
/**
* 对方拒绝PK
*/
public void onRefuse() {
}
/**
* 退出匹配倒计时
*/
public void onPkEndTimer(String time) {
}
/**
* 开始退出匹配
*/
public void onPkEndStart() {
}
/**
* 退出匹配成功
*/
public void onPkEndSuccess() {
}
}
}

View File

@@ -5,8 +5,10 @@ import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Point;
import android.text.format.Formatter;
import android.util.DisplayMetrics;
import android.view.WindowManager;
/**
* 设备通用类
@@ -36,6 +38,19 @@ public class DeviceUtils {
return displayMetrics.heightPixels;
}
/**
* 获取屏幕真实高度
*
* @param activity activity
* @return 屏幕高度
*/
public static int getScreenRealHeight(Activity activity) {
WindowManager service = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
Point point = new Point();
service.getDefaultDisplay().getRealSize(point);
return point.y;
}
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*
@@ -63,7 +78,7 @@ public class DeviceUtils {
public static String getVersionName(Context context) {
try {
PackageManager manager = context.getPackageManager();
PackageInfo info = manager.getPackageInfo(context.getPackageName(),0);
PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0);
return info.versionName;
} catch (Exception e) {
e.printStackTrace();
@@ -81,6 +96,7 @@ public class DeviceUtils {
am.getMemoryInfo(mi);
return mi.lowMemory;
}
public static String getMemory(Context context) {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();

View File

@@ -3,8 +3,10 @@ package com.yunbao.common.utils;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.text.InputFilter;
import android.text.InputType;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.SparseArray;
@@ -322,7 +324,9 @@ public class DialogUitl {
private int mLength;
private SimpleCallback mClickCallback;
private SimpleCallback3 mClickCallback3;
private SimpleCallbackView mSimpleCallbackView;
private int mView = 0;
private CharSequence mSpanned;
public Builder(Context context) {
mContext = context;
@@ -335,6 +339,18 @@ public class DialogUitl {
public Builder setContent(String content) {
mContent = content;
this.mSpanned = null;//设置文本则不是使用HTML代码
return this;
}
public Builder setHtmlCode(CharSequence mSpanned) {
this.mSpanned = mSpanned;
this.mContent = null;//设置HTML代码则不使用文本
return this;
}
public Builder setSimpleCallbackView(SimpleCallbackView mSimpleCallbackView) {
this.mSimpleCallbackView = mSimpleCallbackView;
return this;
}
@@ -413,6 +429,9 @@ public class DialogUitl {
if (!TextUtils.isEmpty(mContent)) {
content.setText(mContent);
}
if (mSpanned != null) {
content.setText(mSpanned);
}
if (mInputType == INPUT_TYPE_NUMBER) {
content.setInputType(InputType.TYPE_CLASS_NUMBER);
} else if (mInputType == INPUT_TYPE_NUMBER_PASSWORD) {
@@ -443,23 +462,33 @@ public class DialogUitl {
mClickCallback.onConfirmClick(dialog, "");
}
} else {
dialog.dismiss();
if (mClickCallback3 != null) {
mClickCallback3.onConfirmClick(dialog);
}
if (mSimpleCallbackView != null) {
mSimpleCallbackView.onConfirmClick(dialog,titleView, content, btnConfirm, btnCancel);
}else{
dialog.dismiss();
}
}
} else {
dialog.dismiss();
if (mClickCallback3 != null) {
mClickCallback3.onCancel();
dialog.dismiss();
} else {
if (mClickCallback instanceof SimpleCallback2) {
((SimpleCallback2) mClickCallback).onCancelClick();
}
if (mSimpleCallbackView != null) {
mSimpleCallbackView.onCancel(dialog,titleView, content, btnConfirm, btnCancel);
}else{
dialog.dismiss();
}
}
}
@@ -467,6 +496,14 @@ public class DialogUitl {
};
btnConfirm.setOnClickListener(listener);
btnCancel.setOnClickListener(listener);
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialogInterface) {
if (mSimpleCallbackView != null) {
mSimpleCallbackView.onShow(dialog,titleView, content, btnConfirm, btnCancel);
}
}
});
return dialog;
}
@@ -494,6 +531,14 @@ public class DialogUitl {
void onCancel();
}
public interface SimpleCallbackView {
void onShow(Dialog dialog, View title, View context, View confirmBtn, View cancelBtn);
void onConfirmClick(Dialog dialog, View title, View context, View confirmBtn, View cancelBtn);
void onCancel(Dialog dialog, View title, View context, View confirmBtn, View cancelBtn);
}
/**
* 城市选择

View File

@@ -256,6 +256,27 @@
android:textColor="#FF9A9A9A"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/live_tool_random_pk"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="23dp"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@mipmap/icon_live_random_pk" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="@string/live_random"
android:textColor="#FF9A9A9A"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/live_tool_mic"

View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="280dp"
android:layout_height="wrap_content"
android:background="@drawable/bg_dialog"
android:gravity="center_horizontal"
android:orientation="vertical"
>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:layout_marginTop="15dp"
android:gravity="center_horizontal"
android:text="@string/random_pk_dialog_title"
android:textColor="@color/textColor"
android:textSize="16sp"
/>
<TextView
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:gravity="center_horizontal"
android:textColor="#161616"
android:textSize="14sp"
/>
<LinearLayout
android:layout_width="match_parent"
android:gravity="center"
android:layout_marginBottom="22dp"
android:layout_height="40dp">
<TextView
android:id="@+id/btn_cancel"
android:layout_width="87dp"
android:layout_height="33dp"
android:gravity="center"
android:text="@string/random_pk_dialog_refuse"
android:textColor="#FFC621"
android:layout_marginRight="7dp"
android:textSize="14sp"
android:background="@drawable/bg_dialog_unfollow_cancel"
/>
<TextView
android:id="@+id/btn_confirm"
android:layout_width="87dp"
android:layout_height="33dp"
android:gravity="center"
android:layout_marginLeft="7dp"
android:text="@string/random_pk_dialog_apply"
android:textColor="#FFFFFF"
android:textSize="14sp"
android:background="@mipmap/tipbox_btn_orange"
/>
</LinearLayout>
</LinearLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -723,6 +723,7 @@
<string name="live_wishlist">心願單</string>
<string name="live_zg">娛樂整蠱</string>
<string name="live_dr">多人PK</string>
<string name="live_random" translatable="false">随机PK</string>
<string name="live_mic">語音連麥</string>
<string name="live_wks">周星榜</string>
<string name="live_zslk">暫時離開</string>
@@ -971,4 +972,9 @@
<string name="invite_anchor">邀請\n主播</string>
<string name="end_pk">結束\nPK</string>
<string name="pk_time">時間 %s</string>
<string name="random_pk_dialog_apply" translatable="false">接受</string>
<string name="random_pk_dialog_refuse" translatable="false">拒绝</string>
<string name="random_pk_dialog_refuse_again" translatable="false">坚持拒绝</string>
<string name="random_pk_dialog_title" translatable="false">随机PK提示</string>
</resources>