1:红包功能完成
This commit is contained in:
@@ -14,6 +14,7 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.media.MediaPlayer;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
@@ -57,6 +58,7 @@ import com.xscm.moduleutil.base.RoomManager;
|
||||
import com.xscm.moduleutil.bean.XLHBean;
|
||||
import com.xscm.moduleutil.event.HourlyBean;
|
||||
import com.xscm.moduleutil.event.MqttBean;
|
||||
import com.xscm.moduleutil.event.RedBean;
|
||||
import com.xscm.moduleutil.utils.ARouteConstants;
|
||||
import com.xscm.moduleutil.utils.BackgroundManager;
|
||||
import com.xscm.moduleutil.utils.ColorManager;
|
||||
@@ -446,12 +448,16 @@ public abstract class BaseAppCompatActivity<VDB extends ViewDataBinding> extends
|
||||
// 在类中添加以下成员变量
|
||||
private final List<MqttBean.ListBean> mqttMessageQueue = new ArrayList<>(); // MQTT消息队列
|
||||
private final List<XLHBean> xlhMessageQueue = new ArrayList<>(); // XLH消息队列
|
||||
private final List<RedBean> redMessageQueue = new ArrayList<>(); // 红包队列
|
||||
private boolean isMqttPlaying = false; // MQTT播放状态标志
|
||||
private boolean isXlhPlaying = false; // XLH播放状态标志
|
||||
private boolean isRedPlaying = false; // XLH播放状态标志
|
||||
private final Object mqttQueueLock = new Object(); // MQTT队列同步锁
|
||||
private final Object xlhQueueLock = new Object(); // XLH队列同步锁
|
||||
private final Object RedQueueLock = new Object(); // XLH队列同步锁
|
||||
private View currentMqttView = null; // 当前正在播放的MQTT视图
|
||||
private View currentXlhView = null; // 当前正在播放的XLH视图
|
||||
private View currentRedView = null; // 当前正在播放的XLH视图
|
||||
|
||||
private final List<HourlyBean> hourlyMessageQueue = new ArrayList<>(); // 小时榜消息队列
|
||||
private final Map<Integer, View> currentHourlyViews = new HashMap<>(); // 当前显示的小时榜视图
|
||||
@@ -711,6 +717,166 @@ public abstract class BaseAppCompatActivity<VDB extends ViewDataBinding> extends
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onEvent(RedBean event){
|
||||
LogUtils.e("收到红包", event);
|
||||
if (event==null) return;
|
||||
if (SpUtil.getFloatingScreen()==1){
|
||||
|
||||
synchronized (RedQueueLock) {
|
||||
redMessageQueue.add(event);
|
||||
if (!isRedPlaying) {
|
||||
isRedPlaying = true;
|
||||
processNextRedMessage();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
redMessageQueue.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void processNextRedMessage() {
|
||||
RedBean redBean;
|
||||
synchronized (RedQueueLock) {
|
||||
if (redMessageQueue.isEmpty()) {
|
||||
isRedPlaying = false;
|
||||
return;
|
||||
}
|
||||
redBean = redMessageQueue.remove(0);
|
||||
}
|
||||
showPiaoPingMessageRed(redBean);
|
||||
}
|
||||
|
||||
private void showPiaoPingMessageRed(RedBean redBean){
|
||||
try {
|
||||
// 清理之前的视图(如果存在)
|
||||
if (currentRedView != null && currentRedView.getParent() != null) {
|
||||
ViewGroup parent = (ViewGroup) currentRedView.getParent();
|
||||
parent.removeView(currentRedView);
|
||||
}
|
||||
|
||||
if (decorView2 == null) {
|
||||
decorView2 = (ViewGroup) getWindow().getDecorView();
|
||||
}
|
||||
|
||||
currentRedView = LayoutInflater.from(this).inflate(R.layout.item_piaoping_red, null);
|
||||
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
|
||||
FrameLayout.LayoutParams.MATCH_PARENT,
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT);
|
||||
layoutParams.topMargin = com.sunfusheng.marqueeview.DisplayUtil.dip2px(this, 140);
|
||||
layoutParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
|
||||
currentRedView.setLayoutParams(layoutParams);
|
||||
decorView2.addView(currentRedView);
|
||||
|
||||
updateRedFloatingViewData(currentRedView, redBean);
|
||||
// 播放红包音效
|
||||
playRedPacketSound();
|
||||
resetAndStartXlhAnimation(currentRedView, () -> {
|
||||
// 清理当前视图
|
||||
if (currentRedView != null && currentRedView.getParent() != null) {
|
||||
ViewGroup parent = (ViewGroup) currentRedView.getParent();
|
||||
parent.removeView(currentRedView);
|
||||
}
|
||||
currentRedView = null;
|
||||
|
||||
// 处理队列中的下一条消息
|
||||
synchronized (RedQueueLock) {
|
||||
isRedPlaying = false;
|
||||
processNextRedMessage();
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
LogUtils.e("显示红包飘屏失败", e);
|
||||
// 出现异常时继续处理队列
|
||||
synchronized (RedQueueLock) {
|
||||
isRedPlaying = false;
|
||||
processNextRedMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
// 在类中添加成员变量
|
||||
private MediaPlayer redPacketMediaPlayer = null;
|
||||
private boolean isRedPacketMediaPrepared = false;
|
||||
// 添加播放红包音效的方法
|
||||
private void playRedPacketSound() {
|
||||
try {
|
||||
if (!isRedPacketMediaPrepared) {
|
||||
// 第一次初始化MediaPlayer
|
||||
if (redPacketMediaPlayer == null) {
|
||||
redPacketMediaPlayer = MediaPlayer.create(this, R.raw.red_packet_come); // 假设音效文件名为red_packet_sound.mp3
|
||||
redPacketMediaPlayer.setOnPreparedListener(mp -> {
|
||||
isRedPacketMediaPrepared = true;
|
||||
mp.start();
|
||||
});
|
||||
redPacketMediaPlayer.setOnCompletionListener(mp -> {
|
||||
// 播放完成后重置,以便下次重新播放
|
||||
try {
|
||||
mp.seekTo(0);
|
||||
} catch (Exception e) {
|
||||
LogUtils.e("MediaPlayer重置失败", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (redPacketMediaPlayer != null) {
|
||||
redPacketMediaPlayer.prepareAsync(); // 异步准备
|
||||
}
|
||||
} else {
|
||||
// 已经准备好了,直接重新播放
|
||||
if (redPacketMediaPlayer != null && !redPacketMediaPlayer.isPlaying()) {
|
||||
redPacketMediaPlayer.seekTo(0);
|
||||
redPacketMediaPlayer.start();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtils.e("播放红包音效失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateRedFloatingViewData(View view, RedBean redBean){
|
||||
TextView textView = view.findViewById(R.id.tv_name);
|
||||
|
||||
if (redBean != null) {
|
||||
String fullText = redBean.getText();
|
||||
if (redBean.getNickname() != null && redBean.getRoom_name() != null) {
|
||||
SpannableStringBuilder builder = new SpannableStringBuilder(fullText);
|
||||
|
||||
// 为用户名设置蓝色
|
||||
int userNameStart = fullText.indexOf(redBean.getNickname());
|
||||
if (userNameStart >= 0) {
|
||||
builder.setSpan(
|
||||
new ForegroundColorSpan(ContextCompat.getColor(this, R.color.colorPrimary)),
|
||||
userNameStart,
|
||||
userNameStart + redBean.getNickname().length(),
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
);
|
||||
}
|
||||
|
||||
// 为房间名设置蓝色
|
||||
int roomNameStart = fullText.indexOf(redBean.getRoom_name());
|
||||
if (roomNameStart >= 0) {
|
||||
builder.setSpan(
|
||||
new ForegroundColorSpan(ContextCompat.getColor(this, R.color.colorPrimary)),
|
||||
roomNameStart,
|
||||
roomNameStart + redBean.getRoom_name().length(),
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
);
|
||||
}
|
||||
|
||||
textView.setText(builder);
|
||||
} else {
|
||||
textView.setText(fullText);
|
||||
}
|
||||
} else {
|
||||
textView.setText("");
|
||||
}
|
||||
|
||||
view.setOnClickListener(v -> {
|
||||
// 点击时执行跳转操作
|
||||
handleRedItemClick(redBean);
|
||||
});
|
||||
}
|
||||
|
||||
// 处理下一个MQTT消息
|
||||
private void processNextMqttMessage() {
|
||||
MqttBean.ListBean mqttBean;
|
||||
@@ -737,8 +903,9 @@ public abstract class BaseAppCompatActivity<VDB extends ViewDataBinding> extends
|
||||
showPiaoPingMessageXlh(xlhBean);
|
||||
}
|
||||
|
||||
ViewGroup decorView;
|
||||
ViewGroup decorView1;
|
||||
ViewGroup decorView;//礼物的
|
||||
ViewGroup decorView1;//巡乐会的
|
||||
ViewGroup decorView2;//红包的
|
||||
|
||||
private void showFloatingMessage(MqttBean.ListBean mqttBean) {
|
||||
|
||||
@@ -977,7 +1144,7 @@ public abstract class BaseAppCompatActivity<VDB extends ViewDataBinding> extends
|
||||
LogUtils.e("XLH动画执行失败", e);
|
||||
onAnimationEnd.run();
|
||||
}
|
||||
}, 3000);
|
||||
}, 5000);
|
||||
} catch (Exception e) {
|
||||
LogUtils.e("XLH动画启动失败", e);
|
||||
onAnimationEnd.run();
|
||||
@@ -1031,6 +1198,15 @@ public abstract class BaseAppCompatActivity<VDB extends ViewDataBinding> extends
|
||||
|
||||
}
|
||||
|
||||
private void handleRedItemClick(RedBean redBean) {
|
||||
// 这里可以根据实际需求实现跳转逻辑
|
||||
// 例如:跳转到礼物详情页面、用户主页等
|
||||
// 使用缓存数据进入房间
|
||||
RoomManager.getInstance().fetchRoomDataAndEnter(getApplicationContext(), redBean.getRoom_id(), "");
|
||||
// ARouter.getInstance().build(ARouteConstants.ROOM_DETAILS).withString("from", "我的界面").withString("roomId", xlhBean.getRoom_id()).navigation();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onEvent(ChatInfo event) {
|
||||
|
||||
@@ -213,24 +213,6 @@ public abstract class BaseMvpActivity<P extends IPresenter, VDB extends ViewData
|
||||
return resources;
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void userInfoEvent(UserInfo event) {
|
||||
// V2TIMUserFullInfo userFullInfo = new V2TIMUserFullInfo();
|
||||
// userFullInfo.setNickname(event.getNickname());
|
||||
// userFullInfo.setFaceUrl(event.getAvatar());
|
||||
// userFullInfo.setAllowType(event.getSex());
|
||||
// V2TIMManager.getInstance().setSelfInfo(userFullInfo, new V2TIMCallback() {
|
||||
// @Override
|
||||
// public void onSuccess() {
|
||||
// LogUtils.e("@@@", "成功");
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onError(int code, String desc) {
|
||||
// LogUtils.e("@@@", "描述"+desc);
|
||||
// }
|
||||
// });
|
||||
}
|
||||
/**
|
||||
* 显示全局飘屏消息(支持任意位置飘过)
|
||||
*
|
||||
|
||||
@@ -450,8 +450,8 @@ public class CommonAppContext extends MultiDexApplication implements Applicatio
|
||||
// startService(mqttServiceIntent);
|
||||
// }
|
||||
|
||||
// mqttConnect=MqttConnect.getInstance(this,"tcp://1.13.181.248","android-"+ MqttClient.generateClientId());
|
||||
mqttConnect=MqttConnect.getInstance(this,"tcp://62.234.12.147","android-"+ MqttClient.generateClientId());
|
||||
mqttConnect=MqttConnect.getInstance(this,"tcp://1.13.181.248","android-"+ MqttClient.generateClientId());
|
||||
// mqttConnect=MqttConnect.getInstance(this,"tcp://62.234.12.147","android-"+ MqttClient.generateClientId());
|
||||
mqttConnect.mqttClient();
|
||||
|
||||
// 每次启动应用时重置状态
|
||||
|
||||
@@ -9,7 +9,7 @@ import lombok.Data;
|
||||
public class RedPacketInfo {
|
||||
private int id;
|
||||
private String remark;// 备注
|
||||
private String password;// 开始时间
|
||||
private String password;// 口令
|
||||
private int countdown;//0:立即开抢,其他:倒计时抢
|
||||
private String conditions;//条件
|
||||
private String total_amount;//红包总金额
|
||||
@@ -27,26 +27,26 @@ public class RedPacketInfo {
|
||||
|
||||
private boolean isAvailable;//是否可以领取
|
||||
|
||||
private String left_amount;//33.00",
|
||||
private String left_amount;//33.00",
|
||||
private int left_count;
|
||||
private long end_time;
|
||||
private long createtime;
|
||||
private String updatetime;
|
||||
|
||||
private int is_qiang;
|
||||
|
||||
// 获取剩余时间
|
||||
public long remainingTime() {
|
||||
long needTime = 0;
|
||||
// 获取当前时间戳(毫秒)
|
||||
long currentTimeMillis = System.currentTimeMillis();
|
||||
long currentTimeMillis = System.currentTimeMillis() / 1000;
|
||||
// 计算剩余时间
|
||||
needTime = start_time - currentTimeMillis;
|
||||
return needTime;
|
||||
}
|
||||
|
||||
// 判断红包是否可以领取
|
||||
public boolean canOpenNow(){
|
||||
return remainingTime()<=0;
|
||||
public boolean canOpenNow() {
|
||||
return remainingTime() <= 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import java.util.List;
|
||||
|
||||
@Data
|
||||
public class RedpacketDetail {
|
||||
private RedPacketInfo redPacket_info;
|
||||
private RedPacketInfo redpacket_info;
|
||||
|
||||
private List<Records> records;
|
||||
private MyRecord my_record;
|
||||
|
||||
@@ -64,6 +64,7 @@ public class UserInfo implements Serializable {
|
||||
|
||||
private int heartId; // "heartId": 4,
|
||||
private int heartNum; //
|
||||
private String red_num;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,13 +2,16 @@ package com.xscm.moduleutil.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*@author qx
|
||||
*@data 2025/9/2
|
||||
*@description: 巡乐会开始后推送的信息
|
||||
*/
|
||||
@Data
|
||||
public class XLHBean {
|
||||
public class XLHBean implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String text;
|
||||
private String room_id;
|
||||
|
||||
|
||||
@@ -2,11 +2,14 @@ package com.xscm.moduleutil.event;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 小时榜飘屏
|
||||
*/
|
||||
@Data
|
||||
public class HourlyBean {
|
||||
public class HourlyBean implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String room_id;
|
||||
private String room_name;
|
||||
private String text;
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.xscm.moduleutil.event;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class RedBean implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String room_id;
|
||||
private String room_name;
|
||||
private String text;
|
||||
private String nickname;
|
||||
}
|
||||
@@ -4,8 +4,14 @@ package com.xscm.moduleutil.event;
|
||||
*/
|
||||
public enum RedEnvelopeStatus {
|
||||
|
||||
READY_TO_OPEN, // 可以直接打开
|
||||
COUNTDOWN_TO_OPEN, // 倒计时后可打开
|
||||
CONDITION_TO_OPEN, // 满足条件后可打开
|
||||
COUNTDOWN_AND_CONDITION // 先倒计时,再满足条件后可打开
|
||||
/// 打开红包
|
||||
QXRedBagDrawTypeOpen,
|
||||
/// 仅倒计时
|
||||
QXRedBagDrawTypeTimeDown,
|
||||
/// 仅收藏房间
|
||||
QXRedBagDrawTypeCollect,
|
||||
/// 手慢了被领完了
|
||||
QXRedBagDrawTypeFinished,
|
||||
/// 发送评论领红包
|
||||
QXRedBagDrawTypePwdSend,
|
||||
}
|
||||
|
||||
@@ -387,6 +387,10 @@ public interface ApiServer {
|
||||
@POST(Constants.POST_GZ)
|
||||
Call<BaseModel<String>> userGuanz(@Field("user_id") String userId, @Field("type") String type);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.POST_FOLLOW_ROOM)
|
||||
Call<BaseModel<String>> followRoom(@Field("room_id") String roomId, @Field("type") String type);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.ACCEPT_PK)
|
||||
Call<BaseModel<String>> acceptPk(@Field("pk_id") String pk_id, @Field("type") String type);
|
||||
|
||||
@@ -3429,6 +3429,20 @@ public class RetrofitClient {
|
||||
});
|
||||
}
|
||||
|
||||
public void followRoom(String room_id, String type, BaseObserver<String> observer) {
|
||||
sApiServer.followRoom(room_id, type).enqueue(new Callback<BaseModel<String>>() {
|
||||
@Override
|
||||
public void onResponse(Call<BaseModel<String>> call, Response<BaseModel<String>> response) {
|
||||
onNextRetu(response, observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<BaseModel<String>> call, Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void acceptPk(String pk_id, String type, BaseObserver<String> observer) {
|
||||
sApiServer.acceptPk(pk_id, type).enqueue(new Callback<BaseModel<String>>() {
|
||||
@Override
|
||||
@@ -3653,7 +3667,6 @@ public class RetrofitClient {
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
ToastUtils.showShort(string.getMsg());
|
||||
} else {
|
||||
ToastUtils.showShort(string.getMsg());
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ public class MqttConnect {
|
||||
public static String shutdown = "";
|
||||
public static String update_app = "";
|
||||
public static String qx_hour_ranking = "";
|
||||
|
||||
public static String qx_redpacket_arrive="";//红包飘屏的主题
|
||||
Handler handler = new Handler(Looper.getMainLooper());
|
||||
String[] topic;
|
||||
int[] qos = {1,2,3,0,0,0,0,0,0,0,0,0,0}; // 消息质量
|
||||
@@ -47,11 +49,13 @@ public class MqttConnect {
|
||||
update_app = "qx_xunlehui"; // 发送更新APP
|
||||
// qx_hour_ranking = "qx_hour_ranking";
|
||||
qx_hour_ranking = "qx_hour_ranking";
|
||||
qx_redpacket_arrive="qx_redpacket_arrive";
|
||||
|
||||
ArrayList<String> topicList = new ArrayList<>();
|
||||
topicList.add(shutdown);
|
||||
topicList.add(update_app);
|
||||
topicList.add(qx_hour_ranking);
|
||||
topicList.add(qx_redpacket_arrive);
|
||||
topic = topicList.toArray(new String[0]);
|
||||
}
|
||||
|
||||
@@ -87,6 +91,7 @@ public class MqttConnect {
|
||||
sub(shutdown);
|
||||
sub(update_app);
|
||||
sub(qx_hour_ranking);
|
||||
sub(qx_redpacket_arrive);
|
||||
// uiTip("MQTT连接成功");
|
||||
}catch (MqttException e){
|
||||
// uiTip("MQTT连接失败,准备重连。。。:"+e.getMessage());
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.orhanobut.logger.Logger;
|
||||
import com.xscm.moduleutil.bean.MqttXlhEnd;
|
||||
import com.xscm.moduleutil.bean.XLHBean;
|
||||
import com.xscm.moduleutil.event.HourlyBean;
|
||||
import com.xscm.moduleutil.event.RedBean;
|
||||
import com.xscm.moduleutil.event.RoomGiftRunable;
|
||||
import com.xscm.moduleutil.utils.SpUtil;
|
||||
|
||||
@@ -63,9 +64,49 @@ public class MqttInitCallback implements MqttCallback {
|
||||
receiveXlhMessage(messageStr);
|
||||
}else if (topic.equals("qx_hour_ranking")){
|
||||
receiveQXHourRanking(topic, messageStr);
|
||||
}else if (topic.equals("qx_redpacket_arrive")){
|
||||
receiveRed(topic, messageStr);
|
||||
}
|
||||
}
|
||||
|
||||
private void receiveRed(String topic, String messageStr) {
|
||||
try {
|
||||
JSONObject jsonObject = JSON.parseObject(messageStr);
|
||||
String message = jsonObject.getString("msg");
|
||||
// 将事件处理放到主线程执行
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
processRedMessage(topic, message);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Log.e("MQTT", "解析MQTT消息异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void processRedMessage(String topic, String message) {
|
||||
try {
|
||||
// 如果 data 是集合字符串
|
||||
// 解析为集合
|
||||
RedBean dataList = JSON.parseObject(message, RedBean.class);
|
||||
|
||||
// 在主线程处理集合数据
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
processDataRed(dataList);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Log.e("MQTT", "解析MQTT消息异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void processDataRed(RedBean dataList) {
|
||||
// 遍历集合并发送每个元素
|
||||
// for (HourlyBean dataItem : dataList) {
|
||||
// EventBus.getDefault().post(dataItem);
|
||||
// }
|
||||
|
||||
// 或者发送整个集合
|
||||
EventBus.getDefault().post(dataList);
|
||||
}
|
||||
|
||||
private void receiveQXHourRanking(String topic, String data) {
|
||||
try {
|
||||
JSONObject jsonObject = JSON.parseObject(data);
|
||||
|
||||
@@ -2,12 +2,16 @@ package com.xscm.moduleutil.utils;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
import com.xscm.moduleutil.bean.RedPacketInfo;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 红包管理器单例类
|
||||
@@ -20,7 +24,7 @@ public class QXRedPacketManager {
|
||||
|
||||
// 私有构造函数,防止外部实例化
|
||||
private QXRedPacketManager() {
|
||||
this.redPackets = new HashMap<>();
|
||||
this.redPackets = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,6 +57,8 @@ public class QXRedPacketManager {
|
||||
this.redPackets.put(model.getRedpacket_id(), model);
|
||||
}
|
||||
|
||||
// 在添加数据后启动定时器(如果尚未启动)
|
||||
startCheckTimer();
|
||||
if (this.delegate != null && this.delegate instanceof QXRedPacketManagerDelegate) {
|
||||
((QXRedPacketManagerDelegate) this.delegate).onRedPacketsAdded(redPackets, this.redPackets.size());
|
||||
}
|
||||
@@ -70,6 +76,8 @@ public class QXRedPacketManager {
|
||||
|
||||
this.redPackets.put(redPacket.getRedpacket_id(), redPacket);
|
||||
|
||||
// 在添加数据后启动定时器(如果尚未启动)
|
||||
startCheckTimer();
|
||||
if (this.delegate != null && this.delegate instanceof QXRedPacketManagerDelegate) {
|
||||
((QXRedPacketManagerDelegate) this.delegate).onRedPacketAdded(redPacket, this.redPackets.size());
|
||||
}
|
||||
@@ -111,6 +119,10 @@ public class QXRedPacketManager {
|
||||
* 开始检查定时器
|
||||
*/
|
||||
public void startCheckTimer() {
|
||||
// 如果定时器已经在运行,直接返回
|
||||
if (checkTimerRunnable != null && checkTimerHandler != null) {
|
||||
return;
|
||||
}
|
||||
if (checkTimerRunnable == null) {
|
||||
checkTimerRunnable = new Runnable() {
|
||||
@Override
|
||||
@@ -128,9 +140,35 @@ public class QXRedPacketManager {
|
||||
* 检查并更新红包状态
|
||||
*/
|
||||
private void checkAndUpdateRedPackets() {
|
||||
// 添加空值检查
|
||||
if (this.redPackets == null || this.redPackets.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<RedPacketInfo> packets = new ArrayList<>(this.redPackets.values());
|
||||
|
||||
for (RedPacketInfo packet : packets) {
|
||||
long packetTime = packet.remainingTime();
|
||||
LogUtils.e("红包剩余时间:" + packet.getRedpacket_time());
|
||||
long redpacketTime = 0;
|
||||
try {
|
||||
if (packet.getRedpacket_time() != null) {
|
||||
redpacketTime = Long.parseLong(packet.getRedpacket_time());
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
LogUtils.e("红包时间格式错误: " + packet.getRedpacket_time());
|
||||
}
|
||||
if (packetTime <= -redpacketTime) {
|
||||
|
||||
removeRedPacket(packet.getRedpacket_id());
|
||||
}
|
||||
if (packet.getCountdown()==0){
|
||||
continue;
|
||||
}
|
||||
|
||||
if (this.delegate != null && this.delegate instanceof QXRedPacketManagerDelegate) {
|
||||
((QXRedPacketManagerDelegate) this.delegate).didUpdateRedPacketTime(packet, packetTime);
|
||||
}
|
||||
|
||||
boolean wasAvailable = packet.isAvailable();
|
||||
packet.setAvailable(packet.canOpenNow());
|
||||
|
||||
@@ -140,12 +178,6 @@ public class QXRedPacketManager {
|
||||
((QXRedPacketManagerDelegate) this.delegate).onRedPacketUpdated(packet, this.redPackets.size());
|
||||
}
|
||||
}
|
||||
|
||||
// 倒计时结束的红包可以设置自动移除
|
||||
if (packet.getCountdown() > 0 && packet.remainingTime() <= -(Long.getLong(packet.getRedpacket_time()))) {
|
||||
// 倒计时结束10秒后自动移除
|
||||
removeRedPacket(packet.getRedpacket_id());
|
||||
}
|
||||
}
|
||||
|
||||
// 继续执行定时任务
|
||||
@@ -157,6 +189,7 @@ public class QXRedPacketManager {
|
||||
*/
|
||||
public void removeAllRedPackets() {
|
||||
this.redPackets.clear();
|
||||
endCheckTimer();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -179,24 +212,6 @@ public class QXRedPacketManager {
|
||||
this.delegate = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置委托对象
|
||||
*
|
||||
* @param delegate 委托对象
|
||||
*/
|
||||
public void setDelegate(QXRedPacketManagerDelegate delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取委托对象
|
||||
*
|
||||
* @return 委托对象
|
||||
*/
|
||||
public QXRedPacketManagerDelegate getDelegate() {
|
||||
return this.delegate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 委托接口
|
||||
*/
|
||||
@@ -232,8 +247,29 @@ public class QXRedPacketManager {
|
||||
* @param remainingCount 剩余数量
|
||||
*/
|
||||
void onRedPacketUpdated(RedPacketInfo packet, int remainingCount);
|
||||
|
||||
/**
|
||||
* 更新红包时间回调
|
||||
*
|
||||
* @param packet 红包模型
|
||||
* @param packetTime 红包剩余时间
|
||||
*/
|
||||
void didUpdateRedPacketTime(RedPacketInfo packet, long packetTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* -- SETTER --
|
||||
* 设置委托对象
|
||||
*
|
||||
*
|
||||
* -- GETTER --
|
||||
* 获取委托对象
|
||||
*
|
||||
@param delegate 委托对象
|
||||
* @return 委托对象
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private QXRedPacketManagerDelegate delegate;
|
||||
}
|
||||
|
||||
|
||||
@@ -248,6 +248,7 @@ public class Constants {
|
||||
public static final String GET_USER_HOME_ZONE = "/api/User/user_home_zone";//获取用户动态
|
||||
public static final String GET_LIKE_LIST = "/api/UserZone/like_list";//获取点赞列表
|
||||
public static final String POST_GZ = "/api/User/follow";//关注、回关、取关
|
||||
public static final String POST_FOLLOW_ROOM = "/api/User/follow_room";//收藏
|
||||
public static final String GET_ALBUM_DETAIL = "/api/User/get_album_detail";//相册详情
|
||||
public static final String UP_ALBUM = "/api/User/add_album_content";//添加相册图片
|
||||
public static final String MOVE_ALBUM = "/api/User/move_album_images";//移动相册图片
|
||||
|
||||
Reference in New Issue
Block a user