修改BUG

This commit is contained in:
2025-09-02 23:03:08 +08:00
parent fe4ff5655a
commit 101eb87e5f
94 changed files with 2147 additions and 2203 deletions

View File

@@ -75,7 +75,7 @@ public class OfficialNoticeActivity extends BaseMvpActivity<NewsPresenter, Activ
@Override
public void onClick(View view) {
if (item.getRoom_id()>0){
ARouter.getInstance().build(ARouteConstants.ROOM_DETAILS).withString("room_id", item.getRoom_id() + "").navigation();
ARouter.getInstance().build(ARouteConstants.ROOM_DETAILS).withString("roomId", item.getRoom_id() + "").navigation();
}else if (item.getRoom_id() == 0 && item.getUrl() != null && !item.getUrl().isEmpty()){
ARouter.getInstance().build(ARouteConstants.H5).withString("url", item.getUrl()).navigation();
}

View File

@@ -109,13 +109,13 @@ public class CommonAppContext extends MultiDexApplication {
AgoraManager.getInstance(this).init(currentEnvironment.getSwSdkAppId());
MessageListenerSingleton.getInstance();
CrashReport.initCrashReport(this, "ac3ed4d89f", true);/*bugly初始化*/
// ServiceUtils.startService(MyMqttService.class);/*Mqtt初始化*/
// 初始化MQTT服务
// 获取单例实例
MyMqttService mqttService = MyMqttService.getInstance(this);
// 启动服务
mqttService.startService();
// // 启动 MQTT 服务
Intent mqttServiceIntent = new Intent(this, MyMqttService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(mqttServiceIntent);
} else {
startService(mqttServiceIntent);
}
// 每次启动应用时重置状态
SpUtil.getInstance().setBooleanValue("youth_model_shown", false);

View File

@@ -88,7 +88,9 @@ public class RoomMessageEvent {
private int online_number;//在线人数
private BlindBoxBean.XlhData xlh_Data;
private BlindBoxBean.XlhData xlh_data;
private String from_pit_number;
private String to_pit_number;
}
@Data

View File

@@ -0,0 +1,16 @@
package com.xscm.moduleutil.bean;
import lombok.Data;
/**
*@author qx
*@data 2025/9/2
*@description: 巡乐会开始后推送的信息
*/
@Data
public class XLHBean {
private String text;
private String room_id;
private int from_type ;
}

View File

@@ -21,10 +21,17 @@ public class BlindBoxBean {
private String title;
private String rule_url;
private String rule;
private String box_price ;
private int box_price ;///每一次抽奖的价格
private String xlh_end_time;///巡乐会结束时间
private int is_xlh; ///是否开启巡乐会 0 关闭 1 开启
private Object xlh_data;
private List<GiftBean> gift_list;
private GiveGift give_homeowner_gift;//房主礼物
private GiveGift locking_gift;//锁定礼物
private xlhUser xlh_user;//巡乐会中奖用户
public boolean isXlhDataArray() {
return xlh_data instanceof JsonArray || xlh_data instanceof List;
}
@@ -124,4 +131,18 @@ public class BlindBoxBean {
private int current_num;//当前已抽奖次数
private int status;
}
@Data
public static class GiveGift {
private int gift_id;
private String gift_name;
private String base_image;
private String gift_num;
}
@Data
public static class xlhUser {
private String user_id;
private String nickname;
private String avatar;
}
}

View File

@@ -100,6 +100,9 @@ public class EMMessageInfo implements MultiItemEntity {
public static final int QXRoomMessageTypeMangH = 1056;
///巡乐会
public static final int QXRoomMessageTypeXlh = 1057;
///
public static final int QXRoomMessageTypehm = 1039;
private RoomMessageEvent emMessage;
private int custom = 0;
@@ -154,6 +157,7 @@ public class EMMessageInfo implements MultiItemEntity {
case QXRoomMessageTypeRoomOMh:
case QXRoomMessageTypeRoomFriendPartDidChanged:
case QXRoomMessageTypeSeatDidChanged:
case QXRoomMessageTypehm:
return 1;
case QXRoomMessageTypeGift:
return 3;

View File

@@ -40,7 +40,7 @@ public class RoomAuction implements Serializable {
}
@Data
public class AuctionListBean implements Serializable {
public static class AuctionListBean implements Serializable {
private String user_id;
private String user_code;
private String nickname;

View File

@@ -63,7 +63,7 @@ public class PolicyDialog extends Dialog {
ds.setUnderlineText(true);
}
};
spanUtils.append("欢迎使用羽声\n").append("在使用我们的产品和服务之前,请您先阅读并了解").append("《用户协议》").setClickSpan(clickSpan).append("").append("《隐私协议》").setClickSpan(ysClickSpan).append("。我们将严格按照上述协议为" +
spanUtils.append("欢迎使用秘地\n").append("在使用我们的产品和服务之前,请您先阅读并了解").append("《用户协议》").setClickSpan(clickSpan).append("").append("《隐私协议》").setClickSpan(ysClickSpan).append("。我们将严格按照上述协议为" +
"您提供服务,保护您的信息安全,点" +
"击“同意”即表示您已阅读并同意全部" +
"条款,可以继续使用我们的产品和服" +

View File

@@ -4,8 +4,10 @@ import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.JavascriptInterface;
@@ -39,12 +41,27 @@ import com.tencent.qcloud.tuikit.tuichat.classicui.page.TUIGroupChatActivity;
public class WebViewDialog extends BaseDialog<WebViewDialogBinding> {
String mUrl;
int type;//10天空之境 11岁月之城 12时空之巅
public WebViewDialog(@NonNull Context context,String url) {
public WebViewDialog(@NonNull Context context, Bundle args) {
super(context, R.style.BaseDialogStyleH);
this.mUrl=url;
this.mUrl = args.getString("url");
this.type = args.getInt("type");
initData1();
}
@Override
public void onStart() {
super.onStart();
if (getWindow() != null) {
// 获取屏幕尺寸
android.util.DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
// 设置高度为屏幕高度的80%
android.view.WindowManager.LayoutParams params = getWindow().getAttributes();
params.height = (int) (displayMetrics.heightPixels * 0.7);
params.width = android.view.ViewGroup.LayoutParams.MATCH_PARENT;
getWindow().setAttributes(params);
}
}
@Override
public int getLayoutId() {
return R.layout.web_view_dialog;
@@ -52,19 +69,34 @@ public class WebViewDialog extends BaseDialog<WebViewDialogBinding> {
@Override
public void initView() {
setCancelable(false);
setCanceledOnTouchOutside(false);
setCancelable(true);
setCanceledOnTouchOutside(true);
Window window = getWindow();
assert window != null;
window.setGravity(Gravity.BOTTOM);
window.setLayout((int) (ScreenUtils.getScreenWidth() * 320.f / 375), WindowManager.LayoutParams.MATCH_PARENT);
mBinding.ivClose.setOnClickListener(v -> dismiss());
//
}
if (type==10){
mBinding.gzCl.setBackgroundResource(R.mipmap.tkzj);
mBinding.imGz.setImageResource(R.mipmap.tkzj_gz);
}else if (type==11){
mBinding.gzCl.setBackgroundResource(R.mipmap.syzc);
mBinding.imGz.setImageResource(R.mipmap.syzc_gz);
}else if (type==12){
mBinding.gzCl.setBackgroundResource(R.mipmap.skzj);
mBinding.imGz.setImageResource(R.mipmap.skzj_gz);
}
}
@Override
public void initData() {
}
public void initData1() {
WebSettings webSettings = mBinding.webView.getSettings();
webSettings.setUseWideViewPort(true);
webSettings.setLoadWithOverviewMode(true);

View File

@@ -47,7 +47,7 @@ public class GiftLotteryAdapter extends BaseQuickAdapter<GiftBean, BaseViewHolde
helper.setText(R.id.tv_gift_time, item.getCreatetime());
ImageUtils.loadHeadCC(item.getBase_image(),helper.getView(R.id.iv_gift_image));
// 使用 SpannableString 给 "x4" 设置不同颜色
TextView giftNameTextView = helper.getView(R.id.tv_gift_name);
TextView giftNameTextView = helper.getView(R.id.gift_name);
TextView nickNameTextView = helper.getView(R.id.tv_user_name);
if (giftNameTextView != null) {
String baseName = item.getGift_name();

View File

@@ -34,5 +34,7 @@ public class GiftLotteryContacts {
void giftSend(String send_id);
void wallet();
void xlh(String room_id);
}
}

View File

@@ -332,8 +332,13 @@ public class GiftLotteryDialog extends BaseMvpDialogFragment<GiftLotteryPresente
} else if (id == R.id.sw_tex) {//特效
isOpenSpecial = mBinding.mirroeSky.swTex.isChecked();
} else if (id == R.id.tv_gz) {//规则
WebViewDialog webViewDialog = new WebViewDialog(getActivity(), getRule_url);
webViewDialog.show();
Bundle bundle = new Bundle();
bundle.putString("url", getRule_url);
bundle.putInt("type", type);
WebViewDialog dialog = new WebViewDialog(getActivity(), bundle);
dialog.show();
// WebViewDialog webViewDialog = new WebViewDialog(getActivity(), getRule_url);
// webViewDialog.show();
} else if (id == R.id.tv_jc) {
if (giftLists != null && !giftLists.isEmpty()) {
PrizePoolDialog prizePoolDialog = new PrizePoolDialog(getActivity());
@@ -351,6 +356,8 @@ public class GiftLotteryDialog extends BaseMvpDialogFragment<GiftLotteryPresente
giftLotteryDialogFragment = GiftLotteryDialogFragment.newInstance(giftBagId);
giftLotteryDialogFragment.show(getChildFragmentManager(), "GiftLotteryDialogFragment");
}else if (id == R.id.tv_start){
}
}
@@ -579,6 +586,8 @@ public class GiftLotteryDialog extends BaseMvpDialogFragment<GiftLotteryPresente
@Override
public void getGiftListSuccess(BlindBoxBean blindBoxBean) {
if (blindBoxBean != null && blindBoxBean.getGift_list() != null) {
upTitle(blindBoxBean.getBox_price());
giftLists = blindBoxBean.getGift_list();
getRule_url = blindBoxBean.getRule_url();
// 确保数据数量不超过视图数量
@@ -616,7 +625,25 @@ public class GiftLotteryDialog extends BaseMvpDialogFragment<GiftLotteryPresente
}
}
}
private void upTitle(int boxPrice){
if (type==10){
mBinding.mirroeSky.oneTitle.setText(boxPrice+"币一次");
mBinding.mirroeSky.tenTitle.setText((boxPrice*10)+"币十次");
mBinding.mirroeSky.hundredTitle.setText((boxPrice*100)+"币十次");
}else if (type==11){
mBinding.cityTime.oneTitle.setText(boxPrice+"币一次");
mBinding.cityTime.tenTitle.setText((boxPrice*10)+"币十次");
mBinding.cityTime.hundredTitle.setText((boxPrice*100)+"币十次");
}else if (type==12){
mBinding.pinnacleTime.oneTitle.setText(boxPrice+"币一次");
mBinding.pinnacleTime.tenTitle.setText((boxPrice*10)+"币十次");
mBinding.pinnacleTime.hundredTitle.setText((boxPrice*100)+"币十次");
}
}
private void UpView(BlindBoxBean.XlhData xlhData) {
if (xlhData != null) {
@@ -739,7 +766,7 @@ public class GiftLotteryDialog extends BaseMvpDialogFragment<GiftLotteryPresente
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMusicPlay(RoomMessageEvent message) {
if (message.getMsgType() == 1056){
UpView(message.getText().getXlh_Data());
UpView(message.getText().getXlh_data());
}
}

View File

@@ -13,6 +13,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener;
@@ -39,6 +40,7 @@ public class GiftLotteryDialogFragment extends BaseMvpDialogFragment<GiftLottery
private String giftBagId;
private int type=1;
private GiftLotteryAdapter adapter;
private GiftRecordAdapte giftRecordAdapte;
private List<GiftBean> data=new ArrayList<>();
@Override
@@ -147,16 +149,11 @@ public class GiftLotteryDialogFragment extends BaseMvpDialogFragment<GiftLottery
columns = 3;
}
adapter=new GiftLotteryAdapter();
giftRecordAdapte=new GiftRecordAdapte();
// PagerGridLayoutManager layoutManager = new PagerGridLayoutManager(rows, columns, PagerGridLayoutManager.VERTICAL);
GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 3);
mBinding.recyclerView.setLayoutManager(layoutManager);
mBinding.recyclerView.setOnFlingListener(null);
// 设置滚动辅助工具
PagerGridSnapHelper pageSnapHelper = new PagerGridSnapHelper();
pageSnapHelper.attachToRecyclerView(mBinding.recyclerView);
mBinding.recyclerView.setAdapter(adapter);
dianj(1);
}
private void onClick(View view) {
@@ -169,10 +166,20 @@ public class GiftLotteryDialogFragment extends BaseMvpDialogFragment<GiftLottery
}
public void dianj(int type1){
if (type1==1) {
GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 3);
mBinding.recyclerView.setLayoutManager(layoutManager);
mBinding.recyclerView.setOnFlingListener(null);
// 设置滚动辅助工具
PagerGridSnapHelper pageSnapHelper = new PagerGridSnapHelper();
pageSnapHelper.attachToRecyclerView(mBinding.recyclerView);
mBinding.recyclerView.setAdapter(adapter);
type=1;
setTextViewStyle(mBinding.textView2, false);
setTextViewStyle(mBinding.textView1, true);
}else if (type1==2){
mBinding.recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
mBinding.recyclerView.setAdapter(giftRecordAdapte);
type=2;
setTextViewStyle(mBinding.textView2, true);
setTextViewStyle(mBinding.textView1, false);
@@ -227,15 +234,16 @@ public class GiftLotteryDialogFragment extends BaseMvpDialogFragment<GiftLottery
@Override
public void getAllRecordSuccess(List<GiftBean> data) {
if (data != null){
if (page==1){
adapter.setNewData(data);
giftRecordAdapte.setNewData(data);
}else {
adapter.addData(data);
giftRecordAdapte.addData(data);
}
}else {
if (page == 1) {
adapter.setNewData(null);
giftRecordAdapte.setNewData(null);
}
}
}

View File

@@ -125,4 +125,9 @@ public class GiftLotteryPresenter extends BasePresenter<GiftLotteryContacts.View
});
}
@Override
public void xlh(String room_id) {
// api.xlh(room_id, new BaseObserver<String>() {)
}
}

View File

@@ -5,6 +5,7 @@ import android.os.Bundle;
import android.view.WindowManager;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import com.xscm.moduleutil.R;
import com.xscm.moduleutil.adapter.GiftAdapter;
@@ -48,7 +49,7 @@ public class PrizePoolDialog extends BaseDialog<DialogPrizePoolBinding> {
android.util.DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
// 设置高度为屏幕高度的80%
android.view.WindowManager.LayoutParams params = getWindow().getAttributes();
params.height = (int) (displayMetrics.heightPixels * 0.8);
params.height = (int) (displayMetrics.heightPixels * 0.7);
params.width = android.view.ViewGroup.LayoutParams.MATCH_PARENT;
getWindow().setAttributes(params);
}
@@ -94,13 +95,13 @@ public class PrizePoolDialog extends BaseDialog<DialogPrizePoolBinding> {
float density = mContext.getResources().getDisplayMetrics().density;
if (density <= 2.0) { // 低密度屏幕如mdpi, hdpi
rows = 5;
rows = 4;
columns = 3;
} else if (density <= 3.0) { // 中密度屏幕如xhdpi
rows = 5;
rows = 4;
columns = 3;
} else { // 高密度屏幕如xxhdpi, xxxhdpi
rows = 5;
rows = 4;
columns = 3;
}
@@ -108,12 +109,13 @@ public class PrizePoolDialog extends BaseDialog<DialogPrizePoolBinding> {
this.gift_list = newData;
if (mBinding != null && mContext != null) {
PrizePoolAdapter prizePoolAdapter = new PrizePoolAdapter();
PagerGridLayoutManager layoutManager = new PagerGridLayoutManager(rows, columns, PagerGridLayoutManager.VERTICAL);
GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 3);
// PagerGridLayoutManager layoutManager = new PagerGridLayoutManager(rows, columns, PagerGridLayoutManager.VERTICAL);
mBinding.gvGift.setLayoutManager(layoutManager);
mBinding.gvGift.setOnFlingListener(null);
// mBinding.gvGift.setOnFlingListener(null);
// 设置滚动辅助工具
PagerGridSnapHelper pageSnapHelper = new PagerGridSnapHelper();
pageSnapHelper.attachToRecyclerView(mBinding.gvGift);
// PagerGridSnapHelper pageSnapHelper = new PagerGridSnapHelper();
// pageSnapHelper.attachToRecyclerView(mBinding.gvGift);
mBinding.gvGift.setAdapter(prizePoolAdapter);
prizePoolAdapter.setNewData(gift_list);
}

View File

@@ -0,0 +1,78 @@
package com.xscm.moduleutil.dialog.giftLottery;
import android.view.View;
import com.xscm.moduleutil.R;
import com.xscm.moduleutil.base.BaseMvpDialogFragment;
import com.xscm.moduleutil.bean.GiftBean;
import com.xscm.moduleutil.bean.WalletBean;
import com.xscm.moduleutil.bean.blindboxwheel.BlindBoxBean;
import com.xscm.moduleutil.bean.blindboxwheel.BlindReslutBean;
import com.xscm.moduleutil.databinding.FragmentTourClubDialogBinding;
import java.util.List;
public class TourClubDialogFragment extends BaseMvpDialogFragment<GiftLotteryPresenter, FragmentTourClubDialogBinding> implements GiftLotteryContacts.View {
@Override
protected GiftLotteryPresenter bindPresenter() {
return new GiftLotteryPresenter(this, getActivity());
}
@Override
protected void initData() {
}
@Override
protected void initView() {
mBinding.tvJc.setOnClickListener(this::onClick);
}
private void onClick(View view) {
int id = view.getId();
if (id==R.id.tv_jc){
// if (giftLists != null && !giftLists.isEmpty()) {
// PrizePoolDialog prizePoolDialog = new PrizePoolDialog(getActivity());
// prizePoolDialog.updateData(giftLists, type);
// prizePoolDialog.show();
// } else {
// com.hjq.toast.ToastUtils.show("奖池数据加载中,请稍后再试");
// }
}
}
@Override
protected int getLayoutId() {
return R.layout.fragment_tour_club_dialog;
}
@Override
public void getGiftListSuccess(BlindBoxBean blindBoxBean) {
}
@Override
public void drawGiftListSuccess(BlindReslutBean blindReslutBean) {
}
@Override
public void getMyRecordSuccess(List<GiftBean> data) {
}
@Override
public void getAllRecordSuccess(List<GiftBean> data) {
}
@Override
public void finishRefreshLoadMore() {
}
@Override
public void wallet(WalletBean walletBean) {
}
}

View File

@@ -0,0 +1,43 @@
package com.xscm.moduleutil.dialog.giftLottery;
import android.content.Context;
import android.view.Window;
import android.view.WindowManager;
import androidx.annotation.NonNull;
import com.blankj.utilcode.util.ScreenUtils;
import com.xscm.moduleutil.R;
import com.xscm.moduleutil.databinding.DialogHeavenGiftBinding;
import com.xscm.moduleutil.databinding.DialogXlhObtainBinding;
import com.xscm.moduleutil.widget.dialog.BaseDialog;
/**
*@author qx
*@data 2025/9/2
*@description: 巡乐会恭喜或得礼弹窗
*/
public class XlhObtainDialog extends BaseDialog<DialogXlhObtainBinding> {
public XlhObtainDialog(@NonNull Context context) {
super(context,R.style.BaseDialogStyleH);
}
@Override
public int getLayoutId() {
return R.layout.dialog_xlh_obtain;
}
@Override
public void initView() {
setCancelable(false);
setCanceledOnTouchOutside(false);
Window window = getWindow();
window.setLayout((int) (ScreenUtils.getScreenWidth() * 375.f / 375), WindowManager.LayoutParams.WRAP_CONTENT);
mBinding.xlhClose.setOnClickListener(v -> dismiss());
mBinding.ivAgain.setOnClickListener(v -> dismiss());///在玩一次
}
@Override
public void initData() {
}
}

View File

@@ -15,7 +15,9 @@ public class RoomGiftGiveEvent {
public RoonGiftModel roonGiftModel;
public int send_type;
public String heart_id;
public RoomGiftGiveEvent(String userId, String room_id, String pit, String num, int send_type, RoonGiftModel giftModel, RoonGiftModel roonGiftModel,String heart_id){
public String auction_id;
public RoomGiftGiveEvent(String userId, String room_id, String pit, String num, int send_type,
RoonGiftModel giftModel, RoonGiftModel roonGiftModel,String heart_id,String auction_id){
this.userId = userId;
this.room_id = room_id;
this.pit = pit;
@@ -24,6 +26,7 @@ public class RoomGiftGiveEvent {
this.giftModel = giftModel;
this.roonGiftModel = roonGiftModel;
this.heart_id = heart_id;
this.auction_id = auction_id;
}

View File

@@ -1432,7 +1432,7 @@ public class RetrofitClient {
if (response.code() == 200) {
BaseModel<String> baseModel = response.body();
if (baseModel.getCode() != 1) {
com.hjq.toast.ToastUtils.show(baseModel.getMsg());
// com.hjq.toast.ToastUtils.show(baseModel.getMsg());
}
}
}

View File

@@ -78,6 +78,9 @@ public abstract class BasePresenter<V extends IView> implements IPresenter {
* @param disposable
*/
public void addDisposable(Disposable disposable) {
if (mDisposables == null){
mDisposables = new CompositeDisposable();
}
mDisposables.add(disposable);
}

View File

@@ -411,7 +411,9 @@ public class AgoraManager {
@SuppressLint("SuspiciousIndentation")
public void setLocalAudioEnabled(boolean enabled, String userId) {
if (rtcEngine != null) {
rtcEngine.enableLocalAudio(enabled); // 启用/禁用音频采集
if (userId.equals(SpUtil.getUserId()+"")) {
rtcEngine.enableLocalAudio(enabled); // 启用/禁用音频采集
}
this.isLocalAudioEnabled = enabled;
if (!enabled) {
for (SoundLevelUpdateListener listener : soundLevelUpdateListeners) {

View File

@@ -3,12 +3,15 @@ package com.xscm.moduleutil.service;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
@@ -17,6 +20,8 @@ import com.alibaba.fastjson.JSONObject;
import com.blankj.utilcode.util.LogUtils;
import com.orhanobut.logger.Logger;
import com.xscm.moduleutil.R;
import com.xscm.moduleutil.bean.XLHBean;
import com.xscm.moduleutil.event.MqttBean;
import com.xscm.moduleutil.event.RoomGiftRunable;
import org.eclipse.paho.android.service.MqttAndroidClient;
@@ -28,25 +33,23 @@ import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.greenrobot.eventbus.EventBus;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class MyMqttService implements MyEmqttConnectListener, MyEmqttMesgListener, MyEmqttSubscribeListener {
public class MyMqttService extends Service implements MyEmqttConnectListener, MyEmqttMesgListener, MyEmqttSubscribeListener {
private final static String TAG = "lxj";
private static int qos = 2;
private static String HOST = "tcp://1.13.181.248";//测试
// private static String HOST = "tcp://1.13.181.248";//测试
private static String HOST = "tcp://62.234.12.147";//正式
private static MqttAndroidClient mqttAndroidClient;
private MqttConnectOptions mMqttConnectOptions;
private static boolean b = true;
// 使用单例模式
private static MyMqttService instance;
// 使用线程安全的集合存储监听器
private static final CopyOnWriteArrayList<MyEmqttMesgListener> messageListeners = new CopyOnWriteArrayList<>();
private static final CopyOnWriteArrayList<MyEmqttConnectListener> connectListeners = new CopyOnWriteArrayList<>();
@@ -67,26 +70,12 @@ public class MyMqttService implements MyEmqttConnectListener, MyEmqttMesgListene
// 服务状态
private static boolean isServiceRunning = false;
private Context mContext;
private static final int NOTIFICATION_ID = 1;
private static final String CHANNEL_ID = "mqtt_channel";
// 私有构造函数
private MyMqttService(Context context) {
this.mContext = context.getApplicationContext();
initService();
}
public static MyMqttService getInstance(Context context) {
if (instance == null) {
synchronized (MyMqttService.class) {
if (instance == null) {
instance = new MyMqttService(context);
}
}
}
return instance;
}
private void initService() {
@Override
public void onCreate() {
super.onCreate();
isServiceRunning = true;
// 创建专用的HandlerThread处理MQTT操作
@@ -96,6 +85,10 @@ public class MyMqttService implements MyEmqttConnectListener, MyEmqttMesgListene
// 创建线程池处理消息
messageExecutorService = Executors.newCachedThreadPool();
// 启动前台服务
startForegroundService();
try {
init();
} catch (MqttException e) {
@@ -103,23 +96,39 @@ public class MyMqttService implements MyEmqttConnectListener, MyEmqttMesgListene
}
}
/**
* 启动MQTT连接
*/
public void startService() {
b = true;
if (!isServiceRunning) {
initService();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
/**
* 停止MQTT服务
*/
public void stopService() {
b = false;
isServiceRunning = false;
cleanup();
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void startForegroundService() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// 创建通知渠道
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID,
"MQTT Service",
NotificationManager.IMPORTANCE_LOW
);
NotificationManager manager = getSystemService(NotificationManager.class);
if (manager != null) {
manager.createNotificationChannel(channel);
}
// 创建通知
Notification notification = new Notification.Builder(this, CHANNEL_ID)
.setContentTitle("消息服务")
.setContentText("正在接收实时消息")
.setSmallIcon(R.mipmap.default_avatar)
.setOngoing(true)
.build();
startForeground(NOTIFICATION_ID, notification);
}
}
/**
@@ -127,13 +136,13 @@ public class MyMqttService implements MyEmqttConnectListener, MyEmqttMesgListene
*/
private void init() throws MqttException {
String CLIENTID = "android-" + MqttClient.generateClientId();
mqttAndroidClient = new MqttAndroidClient(mContext, HOST, CLIENTID);
mqttAndroidClient.setCallback(mqttCallback); //设置监听订阅消息的回调
mqttAndroidClient = new MqttAndroidClient(this, HOST, CLIENTID);
mqttAndroidClient.setCallback(mqttCallback);
mMqttConnectOptions = new MqttConnectOptions();
mMqttConnectOptions.setCleanSession(true); //设置是否清除缓存
mMqttConnectOptions.setConnectionTimeout(10); //设置超时时间,单位:秒
mMqttConnectOptions.setKeepAliveInterval(10); //设置心跳包发送间隔,单位:秒
mMqttConnectOptions.setUserName("public"); //设置用户名
mMqttConnectOptions.setCleanSession(true);
mMqttConnectOptions.setConnectionTimeout(10);
mMqttConnectOptions.setKeepAliveInterval(10);
mMqttConnectOptions.setUserName("public");
mMqttConnectOptions.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1);
if (mqttAndroidClient != null && !mqttAndroidClient.isConnected()) {
@@ -167,43 +176,19 @@ public class MyMqttService implements MyEmqttConnectListener, MyEmqttMesgListene
Log.e(TAG, "MQTT连接异常", e);
}
}
}, 5000); // 5秒后重试
}, 5000);
} else {
Log.w(TAG, "达到最大重试次数,停止重试");
retryCount = 0;
}
}
public static void closeConnection() {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(() -> {
try {
if (mqttAndroidClient != null && mqttAndroidClient.isConnected()) {
IMqttToken disconnect = mqttAndroidClient.disconnect();
disconnect.setActionCallback(new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
Logger.e(TAG, "断开链接", "断开链接成功");
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Logger.e(TAG, "断开链接", "断开链接失败" + exception.getMessage());
}
});
}
} catch (Exception e) {
Log.e(TAG, "关闭连接异常", e);
}
});
}
/**
* 判断网络是否连接
*/
private boolean isConnectIsNomarl() {
try {
ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
NetworkInfo info = connectivityManager.getActiveNetworkInfo();
if (info != null && info.isAvailable()) {
@@ -221,110 +206,11 @@ public class MyMqttService implements MyEmqttConnectListener, MyEmqttMesgListene
return false;
}
/**
* 发布 (模拟其他客户端发布消息)
*
* @param message 消息
*/
public static void publish(String topic, String message) {
if (mqttAndroidClient == null) {
Logger.e(TAG, "mqttAndroidClient is null", "发送失败");
return;
}
// 在后台线程执行发布操作
Handler handler = new Handler(Looper.getMainLooper());
handler.post(() -> {
try {
//参数分别为:主题、消息的字节数组、服务质量、是否在服务器保留断开连接后的最后一条消息
IMqttDeliveryToken publish = mqttAndroidClient.publish(topic, message.getBytes(), qos, false);
publish.setActionCallback(new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
Logger.e(TAG, "发送消息", "发送成功");
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Logger.e(TAG, "发送消息", "发送失败: " + exception.getMessage());
}
});
} catch (Exception e) {
Logger.e(TAG, "发送消息", "发送异常: " + e.getMessage());
}
});
}
public static void subscribe(String topic) {
// 在后台线程执行订阅操作
Handler handler = new Handler(Looper.getMainLooper());
handler.post(() -> {
try {
if (mqttAndroidClient != null && mqttAndroidClient.isConnected()) {
IMqttToken subToken = mqttAndroidClient.subscribe(topic, qos);
subToken.setActionCallback(new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
for (MyEmqttSubscribeListener listener : subscribeListeners) {
if (listener != null) {
listener.onSubscribeSuccess(topic);
}
}
Logger.e(TAG, "订阅成功:" + topic);
}
@Override
public void onFailure(IMqttToken asyncActionToken,
Throwable exception) {
for (MyEmqttSubscribeListener listener : subscribeListeners) {
if (listener != null &&
!TOPIC_BOSS.equals(topic) &&
!TOPIC_XLH.equals(topic)) {
listener.onSubscribeFailure();
}
}
Logger.e(TAG, "订阅失败:" + topic + ", error: " + exception.getMessage());
}
});
}
} catch (Exception e) {
Log.e(TAG, "订阅异常:" + topic, e);
}
});
}
public static void cleanSubscribe(String topic) {
// 在后台线程执行取消订阅操作
Handler handler = new Handler(Looper.getMainLooper());
handler.post(() -> {
try {
if (mqttAndroidClient != null && mqttAndroidClient.isConnected()) {
IMqttToken subToken = mqttAndroidClient.unsubscribe(topic);
subToken.setActionCallback(new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
Logger.e(TAG, "取消成功" + topic);
}
@Override
public void onFailure(IMqttToken asyncActionToken,
Throwable exception) {
Logger.e(TAG, "取消失败" + topic + ", error: " + exception.getMessage());
}
});
}
} catch (Exception e) {
Log.e(TAG, "取消订阅异常:" + topic, e);
}
});
}
//MQTT是否连接成功的监听
private IMqttActionListener iMqttActionListener = new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken arg0) {
retryCount = 0; // 重置重试计数
retryCount = 0;
// 通知所有连接监听器
for (MyEmqttConnectListener listener : connectListeners) {
@@ -360,7 +246,6 @@ public class MyMqttService implements MyEmqttConnectListener, MyEmqttMesgListene
//订阅主题的回调
private MqttCallback mqttCallback = new MqttCallback() {
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
// 将消息处理放到后台线程执行
@@ -369,25 +254,9 @@ public class MyMqttService implements MyEmqttConnectListener, MyEmqttMesgListene
String messageStr = message.toString();
Logger.e(TAG, "收到的消息", "主题:" + topic + " 收到的消息:" + messageStr);
if (topic.equals(TOPIC_BOSS)) {
// 处理消息
// receiveMessage(topic, messageStr);
// new Handler(Looper.getMainLooper()).post(() -> {
receiveMessage(topic, messageStr);
// });
// 通知监听器
// for (MyEmqttMesgListener listener : messageListeners) {
// if (listener != null) {
// // 切换到主线程通知
//// new Handler(Looper.getMainLooper()).post(() -> {
////// listener.messageArrived(topic, messageStr);
//// });
// }
// }
receiveMessage(topic, messageStr);
} else if (topic.equals(TOPIC_XLH)) {
// receiveXlhMessage(messageStr);
// new Handler(Looper.getMainLooper()).post(() -> {
receiveXlhMessage(messageStr);
// });
receiveXlhMessage(messageStr);
}
} catch (Exception e) {
Log.e(TAG, "处理MQTT消息异常", e);
@@ -426,26 +295,22 @@ public class MyMqttService implements MyEmqttConnectListener, MyEmqttMesgListene
private void receiveXlhMessage(String messageStr) {
try {
String newdata = messageStr;
JSONObject jsonObject = JSON.parseObject(newdata);
JSONObject jsonObject = JSON.parseObject(messageStr);
int type = jsonObject.getIntValue("type");
String message = jsonObject.getString("msg");
XLHBean xlhBean=JSON.parseObject(message, XLHBean.class);
// 将事件处理放到主线程执行
new Handler(Looper.getMainLooper()).post(() -> {
processMessageType(type, message);
// processMessageType(type, message);
EventBus.getDefault().post(xlhBean);
});
} catch (Exception e) {
Log.e(TAG, "解析MQTT消息异常", e);
}
}
private void receiveMessage(String topic, String data) {
try {
String newdata = data;
JSONObject jsonObject = JSON.parseObject(newdata);
JSONObject jsonObject = JSON.parseObject(data);
int type = jsonObject.getIntValue("type");
String message = jsonObject.getString("msg");
@@ -460,155 +325,134 @@ public class MyMqttService implements MyEmqttConnectListener, MyEmqttMesgListene
private void processMessageType(int type, String message) {
switch (type) {
case 3001://抢糖果游戏
break;
case 5001://延时一秒推送房间-人气变化
break;
case 5003://延时一秒推送房间-坐骑进场特效
break;
case 5004://延时一秒推送房间-爵位用户进场特效
break;
case 5005://推送房间-上麦申请人数变化
Logger.e("环信5005", message);
break;
case 5007://推送房间-用户是否禁言 1禁言2解禁
break;
case 5011://推送房间-是否封麦 1封麦2解封
break;
case 5013://推送房间-清空单个麦位心动值
case 5014://推送房间-清空所有麦位心动值
break;
case 5015://推送房间-设置房间管理员
break;
case 5016://推送房间-删除房间管理员
break;
case 5017://用户开关麦
break;
case 5019://推送所有人-横幅礼物通知
new RoomGiftRunable(message).run();
break;
case 5020://推送房间-聊天室礼物通知
Logger.e("环信5020", message);
break;
case 5030:
case 5021://推送所有人-小猫钓鱼钓到大礼物时通知
break;
case 5022://推送房间-房间密码变化通知 0取消密码1设置或修改密码
break;
case 5023://推送房间-房间心动值开关变化通知 1开2关
break;
case 5024://推送房间-上麦模式变化通知 1自由2排麦
break;
case 5025://推送房间-修改房间名称
break;
case 5027://推送房间-周星用户进场特效
break;
case 5028://推送房间-修改房间背景
break;
case 5029://推送房间-修改房间公告
break;
case 5032://推送房间-上麦
Logger.e("环信5032", message);
break;
case 5033://推送房间-下麦
Logger.e("环信5033", message);
break;
case 5034://踢出房间
Logger.e("环信5034", message);
break;
case 5035://推送单独用户-定向推向给上麦的用户
break;
case 5036://推送房间-用户禁麦 1禁麦2解禁
break;
case 5037://推送房间-用户进入房间
break;
case 5038://麦位倒计时
break;
case 5039://扔骰子
break;
case 5040://开通守护推送
break;
case 5041://发送表情
break;
case 5042://上传即构日志
break;
case 5043://公屏状态
break;
case 5044://开球
break;
case 5045://弃球
break;
case 5046://亮球
break;
case 5047://调音
break;
case 5050://推送
break;
case 5051://需求变化
break;
case 5054://房主模式切换
break;
case 5055://离开房间
Logger.e("环信5055", message);
break;
case 5056://房主加入
break;
case 5057://房间浇水礼物推送
break;
case 5058://切换相亲房状态
break;
case 5059://相亲房礼物动画
break;
case 5060://房间玫瑰爱神礼物推送
break;
case 5061://交友房心动值变化
Logger.e("环信5061", message);
break;
case 5062://交友房换麦
Logger.e("环信5062", message);
break;
case 5063://进入小黑屋
Logger.e("环信5063", message);
break;
case 5064://退出小黑屋
Logger.e("环信5064", message);
break;
case 5065://点击开始后进行提示弹框
Logger.e("环信5065", message);
break;
case 5066://cp对数
Logger.e("环信5066", message);
break;
case 5067://延迟时间
Logger.e("环信5067", message);
break;
case 5068://房间内广播
Logger.e("环信5068", message);
break;
case 5069://房间内换麦
Logger.e("环信5069", message);
break;
case 10001: //房间红包
break;
case 10002: //雨开始
break;
case 10003: //打开红包
break;
case 7001: //奖池进度更新
break;
case 7002://cp时间到
Logger.e("环信7002", message);
break;
case 5070:
Logger.e("环信5070", message);
break;
}
}
/**
* 发布 (模拟其他客户端发布消息)
*/
public static void publish(String topic, String message) {
if (mqttAndroidClient == null) {
Logger.e(TAG, "mqttAndroidClient is null", "发送失败");
return;
}
// 在后台线程执行发布操作
new Handler(Looper.getMainLooper()).post(() -> {
try {
IMqttDeliveryToken publish = mqttAndroidClient.publish(topic, message.getBytes(), qos, false);
publish.setActionCallback(new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
Logger.e(TAG, "发送消息", "发送成功");
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Logger.e(TAG, "发送消息", "发送失败: " + exception.getMessage());
}
});
} catch (Exception e) {
Logger.e(TAG, "发送消息", "发送异常: " + e.getMessage());
}
});
}
public static void subscribe(String topic) {
// 在后台线程执行订阅操作
new Handler(Looper.getMainLooper()).post(() -> {
try {
if (mqttAndroidClient != null && mqttAndroidClient.isConnected()) {
IMqttToken subToken = mqttAndroidClient.subscribe(topic, qos);
subToken.setActionCallback(new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
for (MyEmqttSubscribeListener listener : subscribeListeners) {
if (listener != null) {
listener.onSubscribeSuccess(topic);
}
}
Logger.e(TAG, "订阅成功:" + topic);
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
for (MyEmqttSubscribeListener listener : subscribeListeners) {
if (listener != null &&
!TOPIC_BOSS.equals(topic) &&
!TOPIC_XLH.equals(topic)) {
listener.onSubscribeFailure();
}
}
Logger.e(TAG, "订阅失败:" + topic + ", error: " + exception.getMessage());
}
});
}
} catch (Exception e) {
Log.e(TAG, "订阅异常:" + topic, e);
}
});
}
public static void cleanSubscribe(String topic) {
// 在后台线程执行取消订阅操作
new Handler(Looper.getMainLooper()).post(() -> {
try {
if (mqttAndroidClient != null && mqttAndroidClient.isConnected()) {
IMqttToken subToken = mqttAndroidClient.unsubscribe(topic);
subToken.setActionCallback(new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
Logger.e(TAG, "取消成功" + topic);
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Logger.e(TAG, "取消失败" + topic + ", error: " + exception.getMessage());
}
});
}
} catch (Exception e) {
Log.e(TAG, "取消订阅异常:" + topic, e);
}
});
}
public static void closeConnection() {
new Handler(Looper.getMainLooper()).post(() -> {
try {
if (mqttAndroidClient != null && mqttAndroidClient.isConnected()) {
IMqttToken disconnect = mqttAndroidClient.disconnect();
disconnect.setActionCallback(new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
Logger.e(TAG, "断开链接", "断开链接成功");
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Logger.e(TAG, "断开链接", "断开链接失败" + exception.getMessage());
}
});
}
} catch (Exception e) {
Log.e(TAG, "关闭连接异常", e);
}
});
}
/**
* 清理资源
*/
public void cleanup() {
@Override
public void onDestroy() {
super.onDestroy();
b = false;
isServiceRunning = false;
try {
// 清理资源
if (messageExecutorService != null) {
@@ -630,10 +474,13 @@ public class MyMqttService implements MyEmqttConnectListener, MyEmqttMesgListene
cleanSubscribe(TOPIC_BOSS);
cleanSubscribe(TOPIC_XLH);
if (mqttAndroidClient != null) {
mqttAndroidClient.disconnect(); //断开连接
mqttAndroidClient.disconnect();
mqttAndroidClient.unregisterResources();
mqttAndroidClient = null;
}
// 停止前台服务
stopForeground(true);
Logger.e(TAG, "服务关闭", "资源释放成功");
} catch (Exception e) {
Log.e(TAG, "服务关闭异常", e);

View File

@@ -4,6 +4,7 @@ import android.content.Context;
import com.blankj.utilcode.util.LogUtils;
import com.bumptech.glide.Glide;
import com.orhanobut.logger.Logger;
public class MemoryOptimizationUtils {
private static final String TAG = "MemoryOptimization";
@@ -22,18 +23,35 @@ public class MemoryOptimizationUtils {
// 内存使用超过85%认为是低内存
return memoryUsage > 0.85;
}
private static long lastGCTime = 0;
private static final long MIN_GC_INTERVAL = 5000; // 5秒最小间隔
/**
* 强制进行垃圾回收
*/
public static void forceGC() {
try {
LogUtils.d(TAG, "Forcing garbage collection");
Runtime.getRuntime().gc();
Thread.sleep(100); // 给GC一些时间
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
long currentTime = System.currentTimeMillis();
// 避免频繁调用GC
if (currentTime - lastGCTime < MIN_GC_INTERVAL) {
Logger.d(TAG, "Skipping GC, too frequent");
return;
}
lastGCTime = currentTime;
// 使用异步方式调用GC
new Thread(() -> {
try {
// 在后台线程执行GC
System.gc();
Thread.sleep(100); // 给GC一些时间
Runtime.getRuntime().runFinalization();
Logger.d(TAG, "Garbage collection completed");
} catch (Exception e) {
Logger.e(TAG, "Error during GC: " + e.getMessage());
}
}).start();
}
/**

View File

@@ -2,18 +2,18 @@ package com.xscm.moduleutil.utils.config;
public enum EnvironmentEnum {
PRODUCTION(//生产环境
"http://chat.qxmier.com/",
"6rdWuz058oq5OahdbFiGEybUcdahd12J83L34Uc7MrPIrxtFG+rXiwDvRcqNvjwbClbbmvMrmxKVkIysFByBsl0Qe9kqd2w8T/nhK5G6eXXlk2V9AjYCieIU+jRnjZBB+Cfechr6rCGJ2aeBARIsXcRPW7wm9WFK9euh5T+v6Pyte68yNaNdcYCll3+U4/uCEog7HygCnMIbAU+kqoPdmn2H+51YOHW+VsnsHd4w1+I3f8Tt0xLIXGM4GWnQueZ5GR46GTWiSYMy8dCIh9SPIMRyC91GosVcfGPMJSdcXqc=",
"https://oss-cn-hangzhou.aliyuncs.com/",
"LTAI5tJ2UYfFNF7K3F4e1siv",
"DhpCS82gaigZljYqsWsUWUAZ20dREz",
"qx-yusheng",
"https://qx-yusheng.oss-cn-hangzhou.aliyuncs.com/",
"wxc7681513be9f926b",
"http://md.xscmmidi.site/",
"yIZtKT0bz5hhD3wb30p+n5+qoasPj0XGza1qRuYXhtm9nFJdf1fA5B4tB6MjGRQNrCIAmlRMiiUP2DhjsDcih9Szx8HmZADuwCI0YTnva6kibqgbuYOtU2zeem3phkbZe27vbZ94aCWAZulloMeXuAFHd0jSaCBxNctKTYLjGQUGnDt/IDQr6mvLHSbb19X9vgQBa2gsTHjt3HYh2EY7dRJA020SPDe35hKf54v826Vgd34isc+BERQ7dwSH0NJ16OqFP181nlGRZvFFbuab3mweFyDOXQTpuN4NbixO5QQ=",
"https://oss-cn-beijing.aliyuncs.com/",
"LTAI5tKgrfcFQxH46ZwWYgFW",
"ZOjTqAJmUL563EKFKySrUwAHtx4hKt",
"midi01",
"https://midi01.oss-cn-beijing.aliyuncs.com/",
"wxef1289d8a89b41d4",
1600101474,
"4a521d6f1c6343998b1c8fd425dea02a",
"a3f0f0c78307434fa1c697c3429fbdcf",
"tcp://81.70.45.221",
"https://vespa.qxmier.com"),
"https://mdh.xscmmidi.site"),
TEST(//测试环境
"http://md.qxmier.com/",
"6rdWuz058oq5OahdbFiGEybUcdahd12J83L34Uc7MrPIrxtFG+rXiwDvRcqNvjwbClbbmvMrmxKVkIysFByBsl0Qe9kqd2w8T/nhK5G6eXXlk2V9AjYCieIU+jRnjZBB+Cfechr6rCGJ2aeBARIsXcRPW7wm9WFK9euh5T+v6Pyte68yNaNdcYCll3+U4/uCEog7HygCnMIbAU+kqoPdmn2H+51YOHW+VsnsHd4w1+I3f8Tt0xLIXGM4GWnQueZ5GR46GTWiSYMy8dCIh9SPIMRyC91GosVcfGPMJSdcXqc=",

View File

@@ -27,11 +27,11 @@ public class EnvironmentPrefs {
// 获取当前选择的环境,默认为 PRODUCTION
public EnvironmentEnum getSelectedEnvironment() {
String envName = sharedPreferences.getString(KEY_ENV, EnvironmentEnum.TEST.name());
String envName = sharedPreferences.getString(KEY_ENV, EnvironmentEnum.PRODUCTION.name());
try {
return EnvironmentEnum.valueOf(envName);
} catch (IllegalArgumentException e) {
return EnvironmentEnum.TEST; // 出错时默认返回生产环境
return EnvironmentEnum.PRODUCTION; // 出错时默认返回生产环境
}
}
}

View File

@@ -22,6 +22,7 @@ import androidx.databinding.DataBindingUtil;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.PathUtils;
import com.blankj.utilcode.util.ThreadUtils;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.ui.PlayerView;
@@ -299,10 +300,42 @@ public class AvatarFrameView extends FrameLayout implements IAnimListener {
clearQueue();
return;
}
// 异步处理URL解析等耗时操作
ThreadUtils.executeByIo(new ThreadUtils.SimpleTask<String>() {
@Override
public String doInBackground() throws Throwable {
// 在后台线程进行URL有效性检查或其他预处理
if (url == null || url.isEmpty()) {
return null;
}
return url; // 返回处理后的URL
}
@Override
public void onSuccess(String processedUrl) {
if (processedUrl != null) {
// 使用post方法确保在下一个UI循环中执行
mainHandler.post(() -> {
// 再次检查状态
if (!isDestroyed && !isPlaying) {
playQueue.add(new PlayItem(processedUrl, type2));
checkAndStartPlayback();
} else {
// 如果正在播放,添加到队列中
playQueue.add(new PlayItem(processedUrl, type2));
}
});
}
}
@Override
public void onFail(Throwable e) {
LogUtils.e("Error processing gift URL: " + e.getMessage());
}
});
// 添加到播放队列
// playQueue.offer(new PlayItem(url, type2));
playQueue.add(new PlayItem(url, type2));
// playQueue.add(new PlayItem(url, type2));
Logger.d("AvatarFrameView", "Added to queue, queue size: " + playQueue.size() + ", url: " + url);
// 如果当前没有在播放,则开始播放
@@ -310,7 +343,7 @@ public class AvatarFrameView extends FrameLayout implements IAnimListener {
// playNextFromQueue();
// }
// 改进播放检查逻辑
checkAndStartPlayback();
// checkAndStartPlayback();
}
@@ -829,43 +862,113 @@ public class AvatarFrameView extends FrameLayout implements IAnimListener {
private void releaseResources() {
LogUtils.d(TAG, "Releasing all resources");
// if (isDestroyed) return;
if (isDestroyed) return;
// 使用异步线程处理耗时操作
new Thread(() -> {
try {
// 在后台线程处理文件操作和大对象清理
performHeavyCleanup();
try {
// 清理 SVGA 资源
if (svgaSurface != null && svgaSurface.getDrawable() instanceof SVGADrawable) {
SVGADrawable drawable = (SVGADrawable) svgaSurface.getDrawable();
if (drawable != null) {
try {
drawable.stop();
svgaSurface.clearAnimation();
svgaSurface.setImageDrawable(null);
} catch (Exception e) {
LogUtils.e(TAG, "Error releasing SVGA resources: " + e.getMessage());
}
}
// 回到主线程处理 UI 相关的清理
mainHandler.post(() -> {
performUICleanup();
});
} catch (Exception e) {
Logger.e(TAG, "Error in async releaseResources: " + e.getMessage());
// 出错时仍在主线程清理 UI 资源
mainHandler.post(() -> {
performUICleanup();
});
}
}).start();
// try {
// // 清理 SVGA 资源
// if (svgaSurface != null && svgaSurface.getDrawable() instanceof SVGADrawable) {
// SVGADrawable drawable = (SVGADrawable) svgaSurface.getDrawable();
// if (drawable != null) {
// try {
// drawable.stop();
// svgaSurface.clearAnimation();
// svgaSurface.setImageDrawable(null);
// } catch (Exception e) {
// LogUtils.e(TAG, "Error releasing SVGA resources: " + e.getMessage());
// }
// }
// }
//
// // 停止并清理播放器
// if (mBinding != null && mBinding.playView != null) {
// mBinding.playView.stopPlay();
// }
//
// // 清理 ExoPlayer 资源
// if (exoPlayer != null) {
// try {
// exoPlayer.stop();
// exoPlayer.clearVideoSurface();
// } catch (Exception e) {
// LogUtils.e(TAG, "Error releasing ExoPlayer resources: " + e.getMessage());
// }
// }
// } catch (Exception e) {
// LogUtils.e(TAG, "Error in releaseResources: " + e.getMessage());
// }
}
/**
* 在后台线程执行耗时的清理操作
*/
private void performHeavyCleanup() {
try {
// 清理缓存文件(如果需要)
// 清理大对象引用等
// clearCacheFiles();
} catch (Exception e) {
Logger.e(TAG, "Error in performHeavyCleanup: " + e.getMessage());
}
}
/**
* 在主线程执行 UI 相关的清理操作
*/
private void performUICleanup() {
try {
// 停止并清理播放器
if (mBinding != null && mBinding.playView != null) {
mBinding.playView.stopPlay();
try {
mBinding.playView.stopPlay();
} catch (Exception e) {
Logger.e(TAG, "Error stopping playView: " + e.getMessage());
}
}
// 清理 ExoPlayer 资源
if (exoPlayer != null) {
try {
// 使用异步停止避免阻塞
exoPlayer.stop();
exoPlayer.clearVideoSurface();
} catch (Exception e) {
LogUtils.e(TAG, "Error releasing ExoPlayer resources: " + e.getMessage());
Logger.e(TAG, "Error releasing ExoPlayer resources: " + e.getMessage());
}
}
// 清理 SVGA 资源
if (svgaSurface != null) {
try {
svgaSurface.pauseAnimation();
svgaSurface.clearAnimation();
svgaSurface.setImageDrawable(null);
} catch (Exception e) {
Logger.e(TAG, "Error releasing SVGA resources: " + e.getMessage());
}
}
} catch (Exception e) {
LogUtils.e(TAG, "Error in releaseResources: " + e.getMessage());
Logger.e(TAG, "Error in performUICleanup: " + e.getMessage());
}
}
/**
* 公共释放方法,用于外部主动释放资源
*/
@@ -877,7 +980,7 @@ public class AvatarFrameView extends FrameLayout implements IAnimListener {
mainHandler.post(this::release);
return;
}
// isDestroyed = true;
isDestroyed = true;
try {
// 清空播放队列
@@ -886,26 +989,36 @@ public class AvatarFrameView extends FrameLayout implements IAnimListener {
// 释放所有资源
releaseResources();
// 释放 ExoPlayer
if (exoPlayer != null) {
try {
exoPlayer.stop();
exoPlayer.release();
} catch (Exception e) {
LogUtils.e(TAG, "Error releasing ExoPlayer: " + e.getMessage());
// 延迟清理 ExoPlayer(避免主线程阻塞)
mainHandler.postDelayed(() -> {
if (exoPlayer != null) {
try {
exoPlayer.release();
} catch (Exception e) {
Logger.e(TAG, "Error releasing ExoPlayer: " + e.getMessage());
}
exoPlayer = null;
}
exoPlayer = null;
}
}, 50);
// 清理 PlayerView
if (playerView != null) {
try {
playerView.setPlayer(null);
} catch (Exception e) {
LogUtils.e(TAG, "Error releasing PlayerView: " + e.getMessage());
// 延迟清理其他资源
mainHandler.postDelayed(() -> {
// 清理 PlayerView
if (playerView != null) {
try {
playerView.setPlayer(null);
} catch (Exception e) {
Logger.e(TAG, "Error releasing PlayerView: " + e.getMessage());
}
playerView = null;
}
playerView = null;
}
// 清理 binding
if (mBinding != null) {
mBinding = null;
}
}, 100);
// 清理 SVGAImageView
if (svgaSurface != null) {
@@ -931,7 +1044,7 @@ public class AvatarFrameView extends FrameLayout implements IAnimListener {
LogUtils.e(TAG, "Error in AvatarFrameView release: " + e.getMessage());
} finally {
// 建议进行垃圾回收
MemoryOptimizationUtils.forceGC();
// MemoryOptimizationUtils.forceGC();
}
}
public void clearQueue() {

View File

@@ -351,17 +351,15 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
// @Subscribe(threadMode = ThreadMode.MAIN)
public void setOnlineStatus(UserOnlineStatusBean isOnline) {
// iv_on_line.setVisibility(isOnline ? GONE : VISIBLE);
if (pitBean.getUser_id() != null && !pitBean.getUser_id().equals("0") && !pitBean.getUser_id().isEmpty()) {
//// for (UserOnlineStatusBean userOnlineStatus : userOnlineStatusBean) {
if (pitBean.getUser_id().equals(isOnline.getUser_id())) {
if (isOnline.getIs_online() == 1) {
iv_on_line.setVisibility(GONE);
} else {
iv_on_line.setVisibility(VISIBLE);
if (pitBean!=null) {
if (pitBean.getUser_id() != null && !pitBean.getUser_id().equals("0") && !pitBean.getUser_id().isEmpty()) {
if (pitBean.getUser_id().equals(isOnline.getUser_id())) {
if (isOnline.getIs_online() == 1) {
iv_on_line.setVisibility(GONE);
} else {
iv_on_line.setVisibility(VISIBLE);
}
}
//// }
}
}
}

View File

@@ -5,20 +5,25 @@ import static com.liulishuo.okdownload.OkDownloadProvider.context;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.alibaba.android.arouter.launcher.ARouter;
import com.blankj.utilcode.util.LogUtils;
import com.petterp.floatingx.FloatingX;
import com.petterp.floatingx.assist.FxGravity;
import com.petterp.floatingx.assist.helper.FxAppHelper;
import com.xscm.moduleutil.R;
import com.xscm.moduleutil.bean.XLHBean;
import com.xscm.moduleutil.event.MqttBean;
import com.xscm.moduleutil.utils.ARouteConstants;
import com.xscm.moduleutil.utils.ImageUtils;
import org.greenrobot.eventbus.EventBus;
@@ -39,7 +44,9 @@ public class PiaoPingManager {
private View piaoPingView;
private boolean isPiaoPingShown = false;
private Queue<MqttBean> messageQueue = new ConcurrentLinkedQueue<>(); // 消息队列
private Queue<XLHBean> XLHmessageQueue = new ConcurrentLinkedQueue<>(); // 消息队列
private boolean isAnimating = false; // 动画状态标记
private boolean XLHisAnimating = false; // 动画状态标记
private PiaoPingManager(Context context) {
windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
if (windowManager == null) return;
@@ -155,6 +162,8 @@ public class PiaoPingManager {
}
messageQueue.clear();
isAnimating = false; // 重置动画状态
XLHmessageQueue.clear();
XLHisAnimating = false;
}
@Subscribe(threadMode = ThreadMode.MAIN)
@@ -164,5 +173,103 @@ public class PiaoPingManager {
// FxAppHelper fxAppHelper = FxAppHelper.builder().setContext( context).setLayout(R.layout.item_piaoping).build();
// FloatingX.install(fxAppHelper).show();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(XLHBean event) {
showPiaoPingMessageXlh(event);
}
private void showPiaoPingMessageXlh(XLHBean event) {
// 创建 FloatingX 配置
// 添加到队列
XLHmessageQueue.offer(event);
// 如果当前没有动画正在进行,则开始处理
if (!XLHisAnimating) {
processNextMessageXlh();
}
}
private void processNextMessageXlh() {
if (XLHmessageQueue.isEmpty()) {
XLHisAnimating = false;
return;
}
XLHisAnimating = true;
XLHBean xlhBean = XLHmessageQueue.poll();
displayMessageXlh(xlhBean);
}
@SuppressLint({"MissingInflatedId", "LocalSuppress"})
private void displayMessageXlh(XLHBean xlhBean) {
// 获取悬浮窗视图并设置内容
View floatingView = LayoutInflater.from(context).inflate(R.layout.item_piaoping_xlh, new FrameLayout(context), false);
TextView textView = floatingView.findViewById(R.id.tv_name);
ImageView xlh_image = floatingView.findViewById(R.id.im_xlh);
// if (xlhBean.getFrom_type() == 1){
// xlh_image.setImageResource(R.mipmap.xlh_jjks);
// }else {
// xlh_image.setImageResource(R.mipmap.xlh_zsks);
// }
xlh_image.setImageDrawable(xlhBean.getFrom_type() == 1 ? context.getResources().getDrawable(R.mipmap.xlh_jjks) : context.getResources().getDrawable(R.mipmap.xlh_zsks));
textView.setText(xlhBean.getText());
// 先将视图放置在屏幕右侧外部,避免闪现问题
floatingView.setTranslationX(10000); // 先放到屏幕外
FxAppHelper fxAppHelper = FxAppHelper.builder()
.setContext(context)
.setLayoutView(floatingView)
.setGravity(FxGravity.RIGHT_OR_TOP)
.setX(0)
.setY(100)
.build();
FloatingX.install(fxAppHelper).show();
// 添加点击事件监听器
floatingView.setOnClickListener(v -> {
// 点击时执行跳转操作
handleItemClick(xlhBean);
});
// 首先从右侧滑入到屏幕中央
floatingView.post(() -> {
// 确保初始位置在屏幕右侧外部
floatingView.setTranslationX(floatingView.getWidth());
// 第一阶段:从右到屏幕右侧边缘(缓慢进入)
ObjectAnimator animator1 = ObjectAnimator.ofFloat(floatingView, "translationX",
floatingView.getWidth(), 0f);
animator1.setDuration(1500); // 延长动画时间到1.5秒
animator1.setInterpolator(new DecelerateInterpolator(2.0f)); // 更平缓的减速效果
animator1.start();
// 第二阶段延迟1秒后从当前位置向左滑出
floatingView.postDelayed(() -> {
ObjectAnimator animator2 = ObjectAnimator.ofFloat(floatingView, "translationX",
0f, -floatingView.getWidth());
animator2.setDuration(1500); // 延长动画时间到1.5秒
animator2.setInterpolator(new DecelerateInterpolator(2.0f)); // 更平缓的减速效果
animator2.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
// 动画结束后移除悬浮窗
FloatingX.uninstallAll();
// 处理下一个消息
processNextMessageXlh();
}
});
animator2.start();
}, 4000); // 停留1秒
});
}
private void handleItemClick(XLHBean xlhBean) {
// 这里可以根据实际需求实现跳转逻辑
// 例如:跳转到礼物详情页面、用户主页等
ARouter.getInstance().build(ARouteConstants.ROOM_DETAILS).withString("from", "我的界面").withString("roomId", xlhBean.getRoom_id()).navigation();
}
}

View File

@@ -71,7 +71,7 @@ public class RoomMakeWheatView extends BaseWheatView {
mIvRipple.stopAnimation();
mIvRipple.setVisibility(VISIBLE);
mTvName.setText(bean.getNickname());
ImageUtils.loadCenterCrop(bean.getAvatar(), mRiv);
ImageUtils.loadHeadCC(bean.getAvatar(), mRiv);
if (TextUtils.isEmpty(pitBean.getDress_picture())) {
mIvFrame.setVisibility(INVISIBLE);
} else {

View File

@@ -23,7 +23,7 @@ public class RoomSingSongWheatView extends BaseWheatView {
public ImageView mIvTagBoss;
public TextView mTvTime;
public TextView tv_time_pk;
public boolean isClickListenerSet = false;
private boolean showBoss;//显示老板标识
public RoomSingSongWheatView(Context context) {

View File

@@ -227,6 +227,7 @@ public class WheatLayoutManager {
return metrics.widthPixels;
}
public void updateSingleWheat(RoomPitBean pitBean, int pitNumber) {
if (pitList == null || pitList.isEmpty() || pitNumber < 1 || pitNumber > 10) return;
if (isSingleMode && this.currentSinglePit != pitNumber) return;