diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml index 2a9fa158..a49c568c 100644 --- a/.idea/deploymentTargetSelector.xml +++ b/.idea/deploymentTargetSelector.xml @@ -4,10 +4,10 @@ - + diff --git a/app/src/main/java/com/qxcm/qxlive/AppContext.java b/app/src/main/java/com/qxcm/qxlive/AppContext.java index 2beeb0b4..3e03f245 100644 --- a/app/src/main/java/com/qxcm/qxlive/AppContext.java +++ b/app/src/main/java/com/qxcm/qxlive/AppContext.java @@ -20,7 +20,7 @@ public class AppContext extends CommonAppContext { super.onCreate(); ToastUtils.init(this); ARouter.init(this); -// ServiceUtils.startService(MyMqttService.class);/**/ + ServiceUtils.startService(MyMqttService.class);/**/ /* mqttClient = MyMQTTClient.getInstance(this); mqttClient.initialize("tcp://81.70.45.221:1883"); diff --git a/moduleUtil/build.gradle b/moduleUtil/build.gradle index 9549da85..ecefdacd 100644 --- a/moduleUtil/build.gradle +++ b/moduleUtil/build.gradle @@ -197,13 +197,13 @@ dependencies { api 'com.github.princekin-f:EasyFloat:2.0.4' //MQTT // api 'org.eclipse.paho:org.eclipse.paho.mqttv5.client:1.2.5' - api 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.1' - api 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1' +// api 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.1' +// api 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1' // api 'com.github.hannesa2:paho.mqtt.android:3.3.5' // api 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5' api 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5' -// api 'io.github.mayzs:paho.mqtt.android:1.1.2' + api 'io.github.mayzs:paho.mqtt.android:1.2.1' //2. 云normal SDK, diff --git a/moduleUtil/src/main/AndroidManifest.xml b/moduleUtil/src/main/AndroidManifest.xml index 6da923ac..2be35ce8 100644 --- a/moduleUtil/src/main/AndroidManifest.xml +++ b/moduleUtil/src/main/AndroidManifest.xml @@ -1,19 +1,22 @@ - + - + + + android:foregroundServiceType="specialUse" /> - - - - - - - - + + + + + + + \ No newline at end of file diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/activity/BaseMvpActivity.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/activity/BaseMvpActivity.java index 5763c54e..7ce0fca9 100644 --- a/moduleUtil/src/main/java/com/qxcm/moduleutil/activity/BaseMvpActivity.java +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/activity/BaseMvpActivity.java @@ -29,11 +29,14 @@ import com.qxcm.moduleutil.R; import com.qxcm.moduleutil.base.CommonAppContext; import com.qxcm.moduleutil.bean.UserBean; import com.qxcm.moduleutil.bean.UserInfo; +import com.qxcm.moduleutil.event.MqttBean; import com.qxcm.moduleutil.event.UnreadCountEvent; +import com.qxcm.moduleutil.utils.ImageUtils; import com.qxcm.moduleutil.utils.LanguageUtil; import com.qxcm.moduleutil.utils.location.LocationProvider; import com.qxcm.moduleutil.utils.location.LocationServiceFactory; import com.qxcm.moduleutil.utils.location.SystemLocationProvider; +import com.qxcm.moduleutil.widget.PiaoPingManager; import com.tencent.imsdk.v2.V2TIMCallback; import com.tencent.imsdk.v2.V2TIMManager; import com.tencent.imsdk.v2.V2TIMUserFullInfo; @@ -202,85 +205,86 @@ public abstract class BaseMvpActivity

= Build.VERSION_CODES.O ? +// WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : +// WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, +// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | +// WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | +// WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, +// PixelFormat.TRANSLUCENT); +// +// // 设置 Gravity 为左上角 +// layoutParams.gravity = Gravity.TOP | Gravity.START; +// +// // Y 轴随机位置 +//// layoutParams.y = (int) ((Math.random() * (screenHeight - 200))); +// +// // 初始 X 设为负值,确保 View 在屏幕左侧外 +// layoutParams.x = -screenWidth; +// +// View piaoPingView = LayoutInflater.from(this).inflate(R.layout.item_piaoping, null); +// TextView textView = piaoPingView.findViewById(R.id.tv_name); +// TextView textView2 = piaoPingView.findViewById(R.id.tv_to_name); +// textView2.setText("送给"+mqttBean.getList().getToUserName()); +// textView.setText(mqttBean.getList().getFromUserName()); +// ImageUtils.loadHeadCC(mqttBean.getList().getGift_picture(), piaoPingView.findViewById(R.id.iv_piaoping)); +// TextView tv_time = piaoPingView.findViewById(R.id.tv_num); +// tv_time.setText(mqttBean.getList().getNumber()); +// windowManager.addView(piaoPingView, layoutParams); +// +// piaoPingView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { +// @Override +// public void onGlobalLayout() { +// piaoPingView.getViewTreeObserver().removeOnGlobalLayoutListener(this); +// +// // 设置锚点为左上角,避免偏移干扰 +// piaoPingView.setPivotX(0); +// piaoPingView.setPivotY(0); +// +// // 启动动画:从左外滑入 -> 右外滑出 +// ObjectAnimator animator = ObjectAnimator.ofFloat( +// piaoPingView, +// "translationX", +// 0f, // 初始偏移为 0(此时 View 在左侧外) +// screenWidth // 向右移动整个屏幕宽度 +// ); +// animator.setDuration(2000); // 整个动画的时长为2秒 +// +// // 强制 GPU 渲染 +// piaoPingView.setLayerType(View.LAYER_TYPE_HARDWARE, null); +// +// // 延迟显示2秒后开始滑出屏幕的动画 +// piaoPingView.postDelayed(new Runnable() { +// @Override +// public void run() { +// animator.start(); +// } +// }, 3000); +// +// animator.addListener(new AnimatorListenerAdapter() { +// @Override +// public void onAnimationEnd(Animator animation) { +// windowManager.removeView(piaoPingView); +// } +// }); +// } +// }); +// } - /** - * 显示全局飘屏消息(支持任意位置飘过) - * - * @param message 漂浮内容 - * @param duration 动画时间(毫秒) - */ - public void showPiaoPingMessage(String message, long duration) { - WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); - if (windowManager == null) return; - - int screenWidth = getResources().getDisplayMetrics().widthPixels; - int screenHeight = getResources().getDisplayMetrics().heightPixels; - - WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams( - WindowManager.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.WRAP_CONTENT, - Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? - WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : - WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | - WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | - WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, - PixelFormat.TRANSLUCENT); - - // 设置 Gravity 为左上角 - layoutParams.gravity = Gravity.TOP | Gravity.START; - - // Y 轴随机位置 - layoutParams.y = (int) ((Math.random() * (screenHeight - 200))); - - // 初始 X 设为负值,确保 View 在屏幕左侧外 - layoutParams.x = -200; - - View piaoPingView = LayoutInflater.from(this).inflate(R.layout.item_piaoping, null); - TextView textView = piaoPingView.findViewById(R.id.tv_content); - textView.setText(message); - - windowManager.addView(piaoPingView, layoutParams); - - piaoPingView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - piaoPingView.getViewTreeObserver().removeOnGlobalLayoutListener(this); - - int viewWidth = piaoPingView.getWidth(); - - // 设置锚点为左上角,避免偏移干扰 - piaoPingView.setPivotX(0); - piaoPingView.setPivotY(0); - - // 更新 x 坐标为 -screenWidth,确保 View 完全在屏幕左侧外 - layoutParams.x = -screenWidth; - windowManager.updateViewLayout(piaoPingView, layoutParams); - - // 启动动画:从左外滑入 -> 右外滑出 - ObjectAnimator animator = ObjectAnimator.ofFloat( - piaoPingView, - "translationX", - 0f, // 初始偏移为 0(此时 View 在左侧外) - screenWidth + viewWidth // 向右移动整个屏幕宽度 + View 宽度 - ); - animator.setDuration(duration); - animator.addUpdateListener(animation -> { - float value = (float) animation.getAnimatedValue(); - }); - animator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - windowManager.removeView(piaoPingView); - } - }); - - // 强制 GPU 渲染 - piaoPingView.setLayerType(View.LAYER_TYPE_HARDWARE, null); - - animator.start(); - } - }); - } } diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/base/CommonAppContext.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/base/CommonAppContext.java index 9fc88371..a47eba98 100644 --- a/moduleUtil/src/main/java/com/qxcm/moduleutil/base/CommonAppContext.java +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/base/CommonAppContext.java @@ -1,5 +1,8 @@ package com.qxcm.moduleutil.base; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ObjectAnimator; import android.app.Activity; import android.app.ActivityManager; import android.app.Application; @@ -9,6 +12,7 @@ import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.Signature; +import android.graphics.PixelFormat; import android.media.MediaRouter; import android.os.Build; import android.os.Bundle; @@ -16,7 +20,13 @@ import android.os.Handler; import android.text.TextUtils; import android.util.Base64; import android.util.Log; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewTreeObserver; +import android.view.WindowManager; import android.webkit.WebView; +import android.widget.TextView; import androidx.multidex.MultiDex; import androidx.multidex.MultiDexApplication; @@ -31,19 +41,19 @@ import com.blankj.utilcode.util.ProcessUtils; import com.blankj.utilcode.util.ServiceUtils; import com.lahm.library.EasyProtectorLib; import com.lahm.library.EmulatorCheckCallback; +import com.qxcm.moduleutil.R; import com.qxcm.moduleutil.bean.UserBean; import com.qxcm.moduleutil.event.AppLifecycleEvent; import com.qxcm.moduleutil.interfaces.AppLifecycleUtil; -import com.qxcm.moduleutil.rtc.RtcManager; -import com.qxcm.moduleutil.service.EMqttService; -import com.qxcm.moduleutil.service.MyMqttService; import com.qxcm.moduleutil.utils.FloatWindowHelper; +import com.qxcm.moduleutil.utils.ImageUtils; import com.qxcm.moduleutil.utils.SpUtil; import com.qxcm.moduleutil.utils.UtilConfig; import com.qxcm.moduleutil.utils.config.EnvironmentEnum; import com.qxcm.moduleutil.utils.config.EnvironmentPrefs; import com.qxcm.moduleutil.widget.CommonAppConfig; import com.qxcm.moduleutil.widget.CustomRefreshHeader; +import com.qxcm.moduleutil.widget.PiaoPingManager; import com.scwang.smartrefresh.layout.SmartRefreshLayout; import com.scwang.smartrefresh.layout.api.DefaultRefreshFooterCreator; import com.scwang.smartrefresh.layout.api.DefaultRefreshHeaderCreator; @@ -55,6 +65,8 @@ import com.tencent.qcloud.tuicore.TUILogin; import com.tencent.qcloud.tuicore.interfaces.TUICallback; import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; import java.lang.reflect.Method; import java.security.MessageDigest; @@ -111,9 +123,11 @@ public class CommonAppContext extends MultiDexApplication { // RtcManager.instance(this); EnvironmentPrefs prefs = new EnvironmentPrefs(this); currentEnvironment = prefs.getSelectedEnvironment(); + piaoPingManager = PiaoPingManager.getInstance(this); + piaoPingManager.subscribe(); // startInitSdk(); } - +private PiaoPingManager piaoPingManager; private void initARouter() { if(true) { ARouter.openDebug(); @@ -349,9 +363,7 @@ public class CommonAppContext extends MultiDexApplication { Intent intent = new Intent("com.example.action.LAUNCH_PAGE"); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); getApplicationContext().startActivity(intent); -// ServiceUtils.stopService(MyMqttService.class); - ServiceUtils.stopService(EMqttService.class); -// MyMqttService.stopService(getApplicationContext()); + piaoPingManager.unsubscribe(); } public static boolean isAlipayInstalled(Context context) { @@ -384,5 +396,4 @@ public class CommonAppContext extends MultiDexApplication { } }); } - } diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/bean/room/RoomInfoResp.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/bean/room/RoomInfoResp.java index 1c6288c4..913ede64 100644 --- a/moduleUtil/src/main/java/com/qxcm/moduleutil/bean/room/RoomInfoResp.java +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/bean/room/RoomInfoResp.java @@ -27,6 +27,7 @@ public class RoomInfoResp implements Serializable { private RoomAuction room_auction;//拍卖房信息 private RoomCpUserBean cp_user; private PkRoomInfo pk_info; + private List song_pit_list; //弹出麦位操作弹出 diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/event/MqttBean.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/event/MqttBean.java new file mode 100644 index 00000000..e57193c5 --- /dev/null +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/event/MqttBean.java @@ -0,0 +1,106 @@ +package com.qxcm.moduleutil.event; + +import lombok.Data; + +/** + * @Author lxj$ + * @Time $ $ + * @Description 从声望获取到的参数$ + */ +@Data +public class MqttBean { + private String room_id; + private ListBean list; + + public String getRoom_id() { + return room_id == null ? "" : room_id; + } + + public void setRoom_id(String room_id) { + this.room_id = room_id == null ? "" : room_id; + } + + public ListBean getList() { + return list; + } + + public void setList(ListBean list) { + this.list = list; + } + + @Data + public static class ListBean { + private String text; + private String gift_picture; + private String room_id; + private String fromUserName; + private String toUserName; + private String giftName; + private String roomId; + private String number; + + public String getText() { + return text == null ? "" : text; + } + + public void setText(String text) { + this.text = text == null ? "" : text; + } + + public String getGift_picture() { + return gift_picture == null ? "" : gift_picture; + } + + public void setGift_picture(String gift_picture) { + this.gift_picture = gift_picture == null ? "" : gift_picture; + } + + public String getRoom_id() { + return room_id == null ? "" : room_id; + } + + public void setRoom_id(String room_id) { + this.room_id = room_id == null ? "" : room_id; + } + + public String getFromUserName() { + return fromUserName == null ? "" : fromUserName; + } + + public void setFromUserName(String fromUserName) { + this.fromUserName = fromUserName == null ? "" : fromUserName; + } + + public String getToUserName() { + return toUserName == null ? "" : toUserName; + } + + public void setToUserName(String toUserName) { + this.toUserName = toUserName == null ? "" : toUserName; + } + + public String getGiftName() { + return giftName == null ? "" : giftName; + } + + public void setGiftName(String giftName) { + this.giftName = giftName == null ? "" : giftName; + } + + public String getRoomId() { + return roomId == null ? "" : roomId; + } + + public void setRoomId(String roomId) { + this.roomId = roomId == null ? "" : roomId; + } + + public String getNumber() { + return number == null ? "" : number; + } + + public void setNumber(String number) { + this.number = number == null ? "" : number; + } + } +} diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/event/RoomGiftGiveEvent.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/event/RoomGiftGiveEvent.java index ba0c7e5c..439e14bd 100644 --- a/moduleUtil/src/main/java/com/qxcm/moduleutil/event/RoomGiftGiveEvent.java +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/event/RoomGiftGiveEvent.java @@ -3,6 +3,9 @@ package com.qxcm.moduleutil.event; import com.qxcm.moduleutil.bean.RoonGiftModel; +import lombok.Data; + +@Data public class RoomGiftGiveEvent { public String userId; public String room_id; diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/event/RoomGiftRunable.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/event/RoomGiftRunable.java new file mode 100644 index 00000000..407c31ee --- /dev/null +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/event/RoomGiftRunable.java @@ -0,0 +1,54 @@ +package com.qxcm.moduleutil.event; + +import android.content.Intent; +import android.os.Build; +import android.provider.Settings; + +import com.blankj.utilcode.util.GsonUtils; +import com.blankj.utilcode.util.ServiceUtils; +import com.google.gson.Gson; +import com.qxcm.moduleutil.base.CommonAppContext; +import com.qxcm.moduleutil.service.EMqttService; + +import org.greenrobot.eventbus.EventBus; + +import java.util.ArrayList; +import java.util.List; + +/** + * @Author $ + * @Time $ $ + * @Description $ + */ +public class RoomGiftRunable implements Runnable { + + private String data; + private static final List mqttCache = new ArrayList<>(); + private static final int MAX_CACHE_SIZE = 6; + private static final Object lock = new Object(); + public RoomGiftRunable(String data) { + this.data = data; + } + + @Override + public void run() { + MqttBean mqttBean= GsonUtils.fromJson(data, MqttBean.class); + // 线程安全地添加到缓存 + synchronized (lock) { + if (mqttCache.size() >= MAX_CACHE_SIZE) { + mqttCache.remove(0); // 移除第一条数据 + } + mqttCache.add(mqttBean); // 添加新数据 + } + EventBus.getDefault().post(mqttBean); + + } + + // 提供方法获取缓存数据 + public static List getMqttCache() { + synchronized (lock) { + return new ArrayList<>(mqttCache); + } + } + +} diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/service/EMqttService.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/service/EMqttService.java index 1b6b834f..1515cd27 100644 --- a/moduleUtil/src/main/java/com/qxcm/moduleutil/service/EMqttService.java +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/service/EMqttService.java @@ -1,78 +1,52 @@ package com.qxcm.moduleutil.service; -import android.annotation.SuppressLint; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ObjectAnimator; import android.app.Service; -import android.content.BroadcastReceiver; -import android.content.Context; import android.content.Intent; -import android.content.IntentFilter; +import android.graphics.PixelFormat; +import android.os.Build; import android.os.IBinder; -import android.util.Log; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewTreeObserver; +import android.view.WindowManager; +import android.widget.TextView; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; -import com.blankj.utilcode.util.NetworkUtils; -import com.blankj.utilcode.util.ThreadUtils; -import com.blankj.utilcode.util.ToastUtils; -import com.orhanobut.logger.Logger; -import com.qxcm.moduleutil.base.CommonAppContext; -import com.qxcm.moduleutil.bean.UserBean; -import com.qxcm.moduleutil.event.BossMsgEvent; -import com.qxcm.moduleutil.event.QDZMqttEvent; -import com.qxcm.moduleutil.utils.GsonUtils; -import com.qxcm.moduleutil.utils.SpUtil; -import com.tencent.qcloud.tuicore.TUIConstants; - -import org.eclipse.paho.android.service.MqttAndroidClient; -import org.eclipse.paho.client.mqttv3.IMqttActionListener; -import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; -import org.eclipse.paho.client.mqttv3.IMqttToken; -import org.eclipse.paho.client.mqttv3.MqttCallback; -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.lang.reflect.Field; -import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; +import com.qxcm.moduleutil.R; +import com.qxcm.moduleutil.event.MqttBean; +import com.qxcm.moduleutil.utils.ImageUtils; -public class EMqttService extends Service implements NetworkUtils.OnNetworkStatusChangedListener { - private final static String TAG = "EMQTT消息"; - - private static final int qos = 2; - private static final String HOST = "tcp://81.70.45.221"; - @SuppressLint("StaticFieldLeak") - private static MqttAndroidClient mqttAndroidClient; - private MqttConnectOptions mMqttConnectOptions; - - private ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1); - - private static final String TOPIC_BOSS = "boss"; - private static final String TOPIC_ROOM = "qx_room_topic"; - private static final String TOPIC_QIANG_TANG_GUO = "red_envelope_single_room_real_time_data"; // 抢糖果 - - public static String sRoomId = "qx_room_topic"; - public static String sUserId; - private BroadcastReceiver unreadCountReceiver; +public class EMqttService extends Service { + private WindowManager windowManager; + private View piaoPingView; @Override public void onCreate() { super.onCreate(); - Logger.e(TAG, "服务创建成功"); - NetworkUtils.registerNetworkStatusChangedListener(this); -// scheduledExecutorService.scheduleWithFixedDelay(connectTask, 0, 10, TimeUnit.SECONDS); + windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); } -// private final Runnable connectTask = this::doClientConnection; @Override public int onStartCommand(Intent intent, int flags, int startId) { - return super.onStartCommand(intent, flags, startId); + if (intent != null && intent.hasExtra("mqttBean")) { + MqttBean mqttBean = (MqttBean) intent.getSerializableExtra("mqttBean"); + showPiaoPingMessage(mqttBean); + } + return START_NOT_STICKY; + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (piaoPingView != null) { + windowManager.removeView(piaoPingView); + } } @Override @@ -80,304 +54,76 @@ public class EMqttService extends Service implements NetworkUtils.OnNetworkStatu return null; } - public static void subscribeRoom(String roomId) { - subscribe("qx_room_topic"); - } + public void showPiaoPingMessage(MqttBean mqttBean) { + int screenWidth = getResources().getDisplayMetrics().widthPixels; + int screenHeight = getResources().getDisplayMetrics().heightPixels; - public static void cleanSubscribeRoom(String roomId) { - cleanSubscribe("qx_room_topic"); - } + WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT, + Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? + WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : + WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | + WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | + WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, + PixelFormat.TRANSLUCENT); - public static void subscribeUser(String userId) { - sUserId = userId; - subscribe("user_" + userId); - } + // 设置 Gravity 为左上角 + layoutParams.gravity = Gravity.TOP | Gravity.START; - public static void cleanSubscribeUser() { - cleanSubscribe("user_" + sUserId); - sUserId = null; - } + // Y 轴随机位置 + layoutParams.y = (int) ((Math.random() * (screenHeight - 200))); - /** - * 订阅主题 - */ - public static void subscribe(String topic) { - try { - if (isAlreadyConnected()) { - IMqttToken subToken = mqttAndroidClient.subscribe(topic, qos); - subToken.setActionCallback(new IMqttActionListener() { + // 初始 X 设为负值,确保 View 在屏幕左侧外 + layoutParams.x = -screenWidth; + + piaoPingView = LayoutInflater.from(this).inflate(R.layout.item_piaoping, null); + TextView textView = piaoPingView.findViewById(R.id.tv_name); + textView.setText(mqttBean.getList().getText()); + ImageUtils.loadHeadCC(mqttBean.getList().getGift_picture(), piaoPingView.findViewById(R.id.iv_piaoping)); + TextView tv_time = piaoPingView.findViewById(R.id.tv_num); + tv_time.setText(mqttBean.getList().getNumber()); + windowManager.addView(piaoPingView, layoutParams); + + piaoPingView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + piaoPingView.getViewTreeObserver().removeOnGlobalLayoutListener(this); + + // 设置锚点为左上角,避免偏移干扰 + piaoPingView.setPivotX(0); + piaoPingView.setPivotY(0); + + // 启动动画:从左外滑入 -> 右外滑出 + ObjectAnimator animator = ObjectAnimator.ofFloat( + piaoPingView, + "translationX", + 0f, // 初始偏移为 0(此时 View 在左侧外) + screenWidth // 向右移动整个屏幕宽度 + ); + animator.setDuration(2000); // 整个动画的时长为2秒 + + // 强制 GPU 渲染 + piaoPingView.setLayerType(View.LAYER_TYPE_HARDWARE, null); + + // 延迟显示2秒后开始滑出屏幕的动画 + piaoPingView.postDelayed(new Runnable() { @Override - public void onSuccess(IMqttToken asyncActionToken) { - Logger.e(TAG, "主题订阅成功", topic); + public void run() { + animator.start(); } + }, 2000); + animator.addListener(new AnimatorListenerAdapter() { @Override - public void onFailure(IMqttToken asyncActionToken, Throwable exception) { - Logger.e(TAG, "主题订阅失败"); - ThreadUtils.runOnUiThreadDelayed(() -> subscribe(topic), 1000); + public void onAnimationEnd(Animator animation) { + windowManager.removeView(piaoPingView); + stopSelf(); } }); } - } catch (Exception e) { - e.printStackTrace(); - } - } - - public static void cleanSubscribe(String topic) { - try { - if (isAlreadyConnected()) { - IMqttToken subToken = mqttAndroidClient.unsubscribe(topic); - subToken.setActionCallback(new IMqttActionListener() { - @Override - public void onSuccess(IMqttToken asyncActionToken) { - Logger.e(TAG, "取消主题成功"); - } - - @Override - public void onFailure(IMqttToken asyncActionToken, Throwable exception) { - Logger.e(TAG, "取消主题失败"); - } - }); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - /** - * 初始化客户端连接 - */ - private String clientId = ""; - - private void init() throws MqttException { - UserBean user = CommonAppContext.getInstance().getUser(); - if (mqttAndroidClient == null) { - clientId = "android-" + user.getUser_id() + "-" + MqttClient.generateClientId(); - mqttAndroidClient = new MqttAndroidClient(this, HOST, clientId, MqttAndroidClient.Ack.AUTO_ACK); - } - mMqttConnectOptions = new MqttConnectOptions(); - mMqttConnectOptions.setCleanSession(true); - mMqttConnectOptions.setConnectionTimeout(10); - mMqttConnectOptions.setKeepAliveInterval(60); - mMqttConnectOptions.setUserName("public"); - mMqttConnectOptions.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1); - - mqttAndroidClient.connect(mMqttConnectOptions, null, iMqttActionListener); - mqttAndroidClient.setCallback(mqttCallback); - - } - - private synchronized void doClientConnection() throws MqttException { - Logger.e("doClientConnection", "doClientConnection"); - if (!isAlreadyConnected() && isConnectIsNomarl()) { - releaseMQTT(); - init(); - } else { - releaseMQTT(); - init(); - } - } - - /** - * 是否已连接 - */ - public static boolean isAlreadyConnected() { - return mqttAndroidClient != null && mqttAndroidClient.isConnected(); - } - - /** - * 网络是否可用 - */ - private boolean isConnectIsNomarl() { - if (NetworkUtils.isConnected()) { - return true; - } else { - Log.i(TAG, "没有可用网络"); - return false; - } - } - - /** - * 连接状态监听 - */ - private final IMqttActionListener iMqttActionListener = new IMqttActionListener() { - @Override - public void onSuccess(IMqttToken arg0) { - long time = 0; - Logger.e(TAG, "链接状态成功"); - EventBus.getDefault().post(EmqttState.CONNECTED); - if (sRoomId != null) { - subscribeRoom(sRoomId); - } - subscribe(TOPIC_BOSS); - subscribe(TOPIC_ROOM); - subscribe(TOPIC_QIANG_TANG_GUO); - subscribeUser(CommonAppContext.getInstance().getUser().getUser_id() + ""); - } - - @Override - public void onFailure(IMqttToken arg0, Throwable arg1) { - arg1.printStackTrace(); - if (arg1 instanceof MqttException) { - MqttException mqttException = (MqttException) arg1; - Logger.e(TAG, "链接状态失败:" + mqttException.getMessage()); - } -// ThreadUtils.runOnUiThreadDelayed(connectTask, 1000); - } - }; - - /** - * 消息回调 - */ - private final MqttCallback mqttCallback = new MqttCallback() { - @Override - public void connectionLost(Throwable cause) { - Logger.e(TAG, "链接断开,请检查网络"); - try { - doClientConnection(); - } catch (MqttException e) { - throw new RuntimeException(e); - } - } - - @Override - public void messageArrived(String topic, MqttMessage message) { - Logger.e(TAG, "收到的消息", "主题:" + topic + " 内容:" + message.toString()); - if (TOPIC_BOSS.equals(topic)) { - if (EventBus.getDefault().hasSubscriberForEvent(BossMsgEvent.class)) { - EventBus.getDefault().post(new BossMsgEvent(message.toString())); - } - return; - } - if (TOPIC_QIANG_TANG_GUO.equals(topic)) { - if (EventBus.getDefault().hasSubscriberForEvent(QDZMqttEvent.class)) { - EventBus.getDefault().post(new QDZMqttEvent(message.toString())); - } - return; - } - receiveMessage(topic, message.toString()); - } - - @Override - public void deliveryComplete(IMqttDeliveryToken token) { - // 发送完成回调 - } - }; - - @Override - public void onDestroy() { - try { - NetworkUtils.unregisterNetworkStatusChangedListener(this); - scheduledExecutorService.shutdownNow(); - scheduledExecutorService = null; - - cleanSubscribeRoom(sRoomId); - cleanSubscribeUser(); - cleanSubscribe(TOPIC_BOSS); - cleanSubscribe(TOPIC_ROOM); - cleanSubscribe(TOPIC_QIANG_TANG_GUO); - - releaseMQTT(); - - if (mqttAndroidClient != null) { - mqttAndroidClient.setCallback(null); - mqttAndroidClient.disconnect(); - mqttAndroidClient = null; - } - } catch (Exception e) { - e.printStackTrace(); - } - super.onDestroy(); - } - - public synchronized void releaseMQTT() { - if (mqttAndroidClient != null) { - try { -// stopAlarmPingSender(mqttAndroidClient); // 防止BroadcastReceiver泄漏 - mqttAndroidClient.disconnect(); - mqttAndroidClient.unregisterResources(); - mqttAndroidClient = null; - } catch (Exception e) { - e.printStackTrace(); - } finally { - mqttAndroidClient = null; - } - } - } - - /** - * 停止 Paho SDK 的 AlarmPingSender - */ - private void stopAlarmPingSender(MqttAndroidClient client) { - try { - Field field = MqttAndroidClient.class.getDeclaredField("client"); - field.setAccessible(true); - Object internalClient = field.get(client); - - Field pingSenderField = internalClient.getClass().getDeclaredField("pingSender"); - pingSenderField.setAccessible(true); - Object pingSender = pingSenderField.get(internalClient); - -// if (pingSender instanceof AlarmpingSender) { -// ((AlarmPingSender) pingSender).stop(); -// } - } catch (Exception e) { - e.printStackTrace(); - } - } - - private void receiveMessage(String topic, String data) { - JSONObject jsonObject; - try { - jsonObject = JSON.parseObject(data); - } catch (Exception e) { - e.printStackTrace(); - return; - } - - int type = jsonObject.getIntValue("type"); - String message = jsonObject.getString("msg"); - - if (TOPIC_ROOM.equals(topic)) { - if (type == 10000) { - // 全服红包 - } - } - - switch (type) { - // 根据业务逻辑处理不同的消息类型 - } - } - - private void sendEvent(String message, Class tClass) { - EventBus.getDefault().post(JSON.parseObject(message, tClass)); - } - - private void sendEventList(String message, Class tClass) { - List list = JSON.parseArray(message, tClass); - EventBus.getDefault().post(list); - } - - private void sendKtEvent(String message, Class tClass) { - EventBus.getDefault().post(GsonUtils.GsonToBean(message, tClass)); - } - - @Override - public void onConnected(NetworkUtils.NetworkType networkType) { - try { - doClientConnection(); - } catch (MqttException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onDisconnected() { - // 可选:做网络断开后的清理工作 - } - - public enum EmqttState { - CONNECTED, - DISCONNECTED + }); } } + diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/service/MyMqttService.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/service/MyMqttService.java index 6a4d3b0d..70e79fc7 100644 --- a/moduleUtil/src/main/java/com/qxcm/moduleutil/service/MyMqttService.java +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/service/MyMqttService.java @@ -1,6 +1,7 @@ package com.qxcm.moduleutil.service; + import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; @@ -15,12 +16,15 @@ import android.os.IBinder; import android.util.Log; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.blankj.utilcode.util.LogUtils; import com.blankj.utilcode.util.ServiceUtils; import com.orhanobut.logger.Logger; import com.qxcm.moduleutil.R; import com.qxcm.moduleutil.base.CommonAppContext; import com.qxcm.moduleutil.event.BossMsgEvent; +import com.qxcm.moduleutil.event.RoomGiftRunable; import org.eclipse.paho.android.service.MqttAndroidClient; import org.eclipse.paho.client.mqttv3.IMqttActionListener; @@ -35,7 +39,7 @@ import org.greenrobot.eventbus.EventBus; import org.jetbrains.annotations.Nullable; -public class MyMqttService extends Service { +public class MyMqttService extends Service implements MyEmqttConnectListener,MyEmqttMesgListener,MyEmqttSubscribeListener{ private final static String TAG = "lxj"; @@ -57,13 +61,13 @@ public class MyMqttService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { -// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // API 31+ -// // 设置前台服务类型为 "connectedDevice" 或其他合适类型 -// setForegroundServiceBehavior(ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST); -// } -// // ⚠️ 必须在这个方法开始就调用 startForeground() -// Notification notification = createNotification(); -// startForeground(NOTIFICATION_ID, notification); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // API 31+ + // 设置前台服务类型为 "connectedDevice" 或其他合适类型 + setForegroundServiceBehavior(ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST); + } + // ⚠️ 必须在这个方法开始就调用 startForeground() + Notification notification = createNotification(); + startForeground(NOTIFICATION_ID, notification); return super.onStartCommand(intent, flags, startId); } @@ -82,23 +86,23 @@ public class MyMqttService extends Service { } } -// private Notification createNotification() { -// // 创建你的前台通知 -// Notification.Builder builder = null; -// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { -// builder = new Notification.Builder(this, "channel_id") -// .setContentTitle("MQTT Service") -// .setSmallIcon(R.mipmap.default_avatar); -// } -// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { -// NotificationChannel channel = new NotificationChannel( -// "channel_id", "MQTT Channel", -// NotificationManager.IMPORTANCE_LOW); -// NotificationManager manager = getSystemService(NotificationManager.class); -// manager.createNotificationChannel(channel); -// } -// return builder.build(); -// } + private Notification createNotification() { + // 创建你的前台通知 + Notification.Builder builder = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + builder = new Notification.Builder(this, "channel_id") + .setContentTitle("MQTT Service") + .setSmallIcon(R.mipmap.default_avatar); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannel channel = new NotificationChannel( + "channel_id", "MQTT Channel", + NotificationManager.IMPORTANCE_LOW); + NotificationManager manager = getSystemService(NotificationManager.class); + manager.createNotificationChannel(channel); + } + return builder.build(); + } /** * 开启服务 @@ -208,16 +212,17 @@ public class MyMqttService extends Service { * 初始化 */ private void init() throws MqttException { - String CLIENTID = "android-" + CommonAppContext.getInstance().getUser().getUser_id() + "-" + MqttClient.generateClientId(); - mqttAndroidClient = new MqttAndroidClient(this, HOST, CLIENTID, MqttAndroidClient.Ack.AUTO_ACK); + String CLIENTID = "android-" + MqttClient.generateClientId(); + mqttAndroidClient = new MqttAndroidClient(this, HOST, CLIENTID); mqttAndroidClient.setCallback(mqttCallback); //设置监听订阅消息的回调 mMqttConnectOptions = new MqttConnectOptions(); - mMqttConnectOptions.setCleanSession(false); //设置是否清除缓存 + mMqttConnectOptions.setCleanSession(true); //设置是否清除缓存 mMqttConnectOptions.setConnectionTimeout(10); //设置超时时间,单位:秒 mMqttConnectOptions.setKeepAliveInterval(10); //设置心跳包发送间隔,单位:秒 mMqttConnectOptions.setUserName("public"); //设置用户名 // mMqttConnectOptions.setPassword(new char[0]); //设置密码 mMqttConnectOptions.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1); + if (!mqttAndroidClient.isConnected()) { doClientConnection(); } @@ -320,9 +325,11 @@ public class MyMqttService extends Service { } Logger.e(TAG, "收到的消息", "主题:" + topic + " 收到的消息:" + message.toString()); //收到其他客户端的消息后,响应给对方告知消息已到达或者消息有问题等 - if (TOPIC_BOSS.equals(topic)) { - EventBus.getDefault().post(new BossMsgEvent(message.toString())); - } + receiveMessage(topic,message.toString()); +// if (TOPIC_BOSS.equals(topic)) { +// EventBus.getDefault().post(new BossMsgEvent(message.toString())); +// } + } @Override @@ -352,7 +359,165 @@ public class MyMqttService extends Service { } }; + private void receiveMessage(String topic, String data) { + JSONObject jsonObject = null; + try { + String newdata = data;//TextLengthUtil.decode(data); + jsonObject = JSON.parseObject(newdata); + } catch (Exception e) { + e.printStackTrace(); + return; + } + int type = jsonObject.getIntValue("type"); + String message = jsonObject.getString("msg"); + 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://用户开关麦 +// EventBus.getDefault().post(JSON.parseObject(message, WheatVoiceModel.class)); + break; + case 5019://推送所有人-横幅礼物通知c + 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); +// sendEventList(message, RoomPitBean.class); + 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; + } + } @Override public void onDestroy() { try { @@ -384,6 +549,30 @@ public class MyMqttService extends Service { } + @Override + public void onConnectSuccess() { + + } + + @Override + public void onConnectFailure() { + + } + + @Override + public void messageArrived(String topic, String mesg) { + + } + + @Override + public void onSubscribeSuccess(String topic) { + + } + + @Override + public void onSubscribeFailure() { + + } } diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/PiaoPingManager.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/PiaoPingManager.java new file mode 100644 index 00000000..7c0db8e8 --- /dev/null +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/PiaoPingManager.java @@ -0,0 +1,100 @@ +package com.qxcm.moduleutil.widget; + +import static com.liulishuo.okdownload.OkDownloadProvider.context; + +import android.content.Context; +import android.graphics.PixelFormat; +import android.os.Build; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.WindowManager; +import android.widget.TextView; + +import com.qxcm.moduleutil.R; +import com.qxcm.moduleutil.event.MqttBean; +import com.qxcm.moduleutil.utils.ImageUtils; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; +/** + * @Author + * @Time 2025/7/18 21:52 + * @Description 飘屏管理器 + */ +public class PiaoPingManager { + private static PiaoPingManager instance; + private WindowManager windowManager; + private View piaoPingView; + private boolean isPiaoPingShown = false; + + private PiaoPingManager(Context context) { + windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + if (windowManager == null) return; + + // 创建飘屏消息的布局 + LayoutInflater inflater = LayoutInflater.from(context); + piaoPingView = inflater.inflate(R.layout.item_piaoping, null); + } + + public static synchronized PiaoPingManager getInstance(Context context) { + if (instance == null) { + instance = new PiaoPingManager(context.getApplicationContext()); + } + return instance; + } + + public void showPiaoPingMessage(MqttBean mqttBean) { + if (isPiaoPingShown || piaoPingView == null || windowManager == null) return; + + // 设置布局参数 + WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT, + Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? + WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : + WindowManager.LayoutParams.TYPE_PHONE, + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, + PixelFormat.TRANSLUCENT); + + layoutParams.gravity = Gravity.TOP; + layoutParams.y = 100; // 设置垂直位置 + + // 设置消息内容 + View piaoPingView = LayoutInflater.from(context.getApplicationContext()).inflate(R.layout.item_piaoping, null); + TextView textView = piaoPingView.findViewById(R.id.tv_name); + TextView textView2 = piaoPingView.findViewById(R.id.tv_to_name); + textView2.setText("送给"+mqttBean.getList().getToUserName()); + textView.setText(mqttBean.getList().getFromUserName()); + ImageUtils.loadHeadCC(mqttBean.getList().getGift_picture(), piaoPingView.findViewById(R.id.iv_piaoping)); + TextView tv_time = piaoPingView.findViewById(R.id.tv_num); + tv_time.setText("x"+mqttBean.getList().getNumber()); + + // 添加到窗口管理器 + windowManager.addView(piaoPingView, layoutParams); + isPiaoPingShown = true; + + // 设置定时任务,一段时间后移除飘屏消息 + piaoPingView.postDelayed(() -> { + if (piaoPingView != null) { + windowManager.removeView(piaoPingView); + isPiaoPingShown = false; + } + }, 3000); // 3秒后移除 + } + + public void subscribe() { + EventBus.getDefault().register(this); + } + + public void unsubscribe() { + EventBus.getDefault().unregister(this); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageReceived(MqttBean mqttBean) { + showPiaoPingMessage(mqttBean); + } +} + diff --git a/moduleUtil/src/main/res/layout/item_piaoping.xml b/moduleUtil/src/main/res/layout/item_piaoping.xml index 8d05b0eb..d565ca78 100644 --- a/moduleUtil/src/main/res/layout/item_piaoping.xml +++ b/moduleUtil/src/main/res/layout/item_piaoping.xml @@ -1,13 +1,67 @@ - \ No newline at end of file + + + + + + + + + + + + + \ No newline at end of file diff --git a/moduleUtil/src/main/res/mipmap-xxxhdpi/gift_p_b.png b/moduleUtil/src/main/res/mipmap-xxxhdpi/gift_p_b.png new file mode 100644 index 00000000..58147914 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxxhdpi/gift_p_b.png differ diff --git a/modulemain/src/main/java/com/qxcm/modulemain/activity/MainActivity.java b/modulemain/src/main/java/com/qxcm/modulemain/activity/MainActivity.java index 935fb5c9..b72256bd 100644 --- a/modulemain/src/main/java/com/qxcm/modulemain/activity/MainActivity.java +++ b/modulemain/src/main/java/com/qxcm/modulemain/activity/MainActivity.java @@ -74,16 +74,16 @@ public class MainActivity extends BaseMvpActivity= Build.VERSION_CODES.M) { - if (!Settings.canDrawOverlays(this)) { - Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, - Uri.parse("package:" + getPackageName())); - startActivityForResult(intent, 100); - } - } else { - // 对于低于 Android 6.0 的设备,无需请求悬浮窗权限 - // 可在此处添加针对旧版本的处理逻辑(如果需要) - } +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { +// if (!Settings.canDrawOverlays(this)) { +// Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, +// Uri.parse("package:" + getPackageName())); +// startActivityForResult(intent, 100); +// } +// } else { +// // 对于低于 Android 6.0 的设备,无需请求悬浮窗权限 +// // 可在此处添加针对旧版本的处理逻辑(如果需要) +// } // 每11秒执行一次飘屏消息 @@ -97,21 +97,20 @@ public class MainActivity extends BaseMvpActivity= Build.VERSION_CODES.M) { - if (Settings.canDrawOverlays(this)) { - ToastUtils.showShort("已获得悬浮窗权限"); -// showPiaoPingMessage("测试飘屏", 3000); - showPiaoPingMessage("这是一个飘屏消息", 10000); // 5秒飘过 - } else { - ToastUtils.showShort("未获得悬浮窗权限,功能无法使用"); - } - } - } - } +// @Override +// protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { +// super.onActivityResult(requestCode, resultCode, data); +// if (requestCode == 100) { +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { +// if (Settings.canDrawOverlays(this)) { +// ToastUtils.showShort("已获得悬浮窗权限"); +//// showPiaoPingMessage("测试飘屏", 3000); +// } else { +// ToastUtils.showShort("未获得悬浮窗权限,功能无法使用"); +// } +// } +// } +// } @Subscribe(threadMode = ThreadMode.MAIN) public void onUserInfoEvent(String event) { diff --git a/moduleroom/src/main/java/com/example/moduleroom/activity/RoomActivity.java b/moduleroom/src/main/java/com/example/moduleroom/activity/RoomActivity.java index d04c1085..2646a6d1 100644 --- a/moduleroom/src/main/java/com/example/moduleroom/activity/RoomActivity.java +++ b/moduleroom/src/main/java/com/example/moduleroom/activity/RoomActivity.java @@ -11,6 +11,7 @@ import android.content.res.Configuration; import android.graphics.Rect; import android.os.Build; import android.os.Bundle; +import android.os.CountDownTimer; import android.os.Handler; import android.text.TextUtils; import android.util.Log; @@ -35,6 +36,8 @@ import com.alibaba.android.arouter.facade.annotation.Autowired; import com.alibaba.android.arouter.facade.annotation.Route; import com.alibaba.android.arouter.launcher.ARouter; import com.blankj.utilcode.util.GsonUtils; +import com.blankj.utilcode.util.LogUtils; +import com.blankj.utilcode.util.ThreadUtils; import com.blankj.utilcode.util.ToastUtils; import com.chad.library.adapter.base.BaseQuickAdapter; import com.example.moduleroom.R; @@ -54,13 +57,18 @@ import com.qxcm.moduleutil.base.CommonAppContext; import com.qxcm.moduleutil.bean.HeadlineBean; import com.qxcm.moduleutil.bean.HeadlineEvent; import com.qxcm.moduleutil.bean.UserInfo; +import com.qxcm.moduleutil.bean.room.RankInfo; import com.qxcm.moduleutil.bean.room.RoomOnline; import com.qxcm.moduleutil.databinding.RoomDialogMusicWindowOpenBinding; +import com.qxcm.moduleutil.dialog.RechargeDialogFragment; import com.qxcm.moduleutil.event.ColoseCardEvent; import com.qxcm.moduleutil.event.EffectEvent; import com.qxcm.moduleutil.event.MusicEvent; +import com.qxcm.moduleutil.event.RoomGiftGiveEvent; import com.qxcm.moduleutil.event.RoomOutEvent; import com.qxcm.moduleutil.event.RoomWheatEvent; +import com.qxcm.moduleutil.http.BaseObserver; +import com.qxcm.moduleutil.http.RetrofitClient; import com.qxcm.moduleutil.interfaces.OnMusicItemClickListener; import com.qxcm.moduleutil.listener.MessageListenerSingleton; import com.qxcm.moduleutil.adapter.LikeUserAdapter; @@ -84,8 +92,11 @@ import com.qxcm.moduleutil.rtc.AgoraManager; import com.qxcm.moduleutil.rtc.MusicPlayBean; import com.qxcm.moduleutil.rtc.RtcCore; import com.qxcm.moduleutil.utils.ARouteConstants; +import com.qxcm.moduleutil.utils.DialogUtils; import com.qxcm.moduleutil.utils.ImageUtils; import com.qxcm.moduleutil.utils.SpUtil; +import com.qxcm.moduleutil.utils.logger.DataLogger; +import com.qxcm.moduleutil.widget.CircularProgressView; import com.qxcm.moduleutil.widget.CustomMusicFloatingView; import com.qxcm.moduleutil.widget.MusicView; import com.qxcm.moduleutil.widget.SilentCountDownTimer; @@ -102,6 +113,7 @@ import java.util.ArrayList; import java.util.List; import io.agora.musiccontentcenter.Music; +import io.reactivex.disposables.Disposable; import pub.devrel.easypermissions.AppSettingsDialog; import pub.devrel.easypermissions.EasyPermissions; @@ -139,6 +151,7 @@ public class RoomActivity extends BaseMvpActivity toggleFullScreen()); ivExitFullscreen.setOnClickListener(v -> exitFullScreen()); + } + + @Override + protected void initView() { + super.initView(); + circularProgress = mBinding.giftShowProgress; + circularProgress.setProgress(0); + mBinding.giftShowLayout.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onGiftGiveProgressClcik(); + LogUtils.e("xj", "onSubscribe2222"); + } + }); + } + + private void onGiftGiveProgressClcik() { + if (giftGiveEvent == null || giftGiveEvent.roonGiftModel == null) { + return; + } +// if (giftCountTimer != null) { +// giftCountTimer.cancel(); +// giftCountTimer = null; +// } + RetrofitClient.getInstance().roomGift(giftGiveEvent.getRoom_id(), giftGiveEvent.getRoonGiftModel().getGift_id(), giftGiveEvent.getNum(), giftGiveEvent.getUserId(),"1",giftGiveEvent.getPit(), new BaseObserver(){ + @Override + public void onSubscribe(Disposable d) { +// showGiftGiveProgress(); +// LogUtils.e("xj", "onSubscribe"); + + } + + @Override + public void onNext(String s) { + showGiftGiveProgress(); + } + + @Override + public void onError(Throwable e) { + super.onError(e); + String msg = e.getMessage(); + if (!TextUtils.isEmpty(msg) && msg.contains("当前余额不足")) { + com.hjq.toast.ToastUtils.show("当前余额不足,请充值"); + ThreadUtils.runOnUiThreadDelayed(() -> { + RechargeDialogFragment.show(roomId, getSupportFragmentManager()); +// DialogUtils.showDialogFragment(ARouter.getInstance().build(ARouteConstants.RECHARGE_DIALOG).navigation()); + }, 1400); + } + hideGiftGiveProgress(); + } + }); + } + + private RoomGiftGiveEvent giftGiveEvent; + + @Subscribe(threadMode = ThreadMode.MAIN) + public void roomGiveGiftEvent(RoomGiftGiveEvent event) { + if (isFinishing() || event == null || event.roonGiftModel == null) { + return; + } + giftGiveEvent = event; + showGiftGiveProgress(); + } + private int giftProgress=0; + private CountDownTimer giftCountTimer; + + private void startGiftProgressTime() { + giftProgress = 0; + if (giftCountTimer != null) { + giftCountTimer.cancel(); + } + LogUtils.e("xj2", "onSubscribe"); + giftCountTimer = new CountDownTimer(1000 * 10, 50) { + + @Override + public void onTick(long millisUntilFinished) { + if (!isFinishing()) { + circularProgress.setProgress(1000 - (int) (millisUntilFinished / 10)); + } + } + + @Override + public void onFinish() { + circularProgress.setProgress(1000); + hideGiftGiveProgress(); + } + }; + giftCountTimer.start(); + } + + private void showGiftGiveProgress() { + ImageUtils.loadImageView(giftGiveEvent.roonGiftModel.getBase_image(), mBinding.giftShowProgressImg); + circularProgress.setProgress(1000);// 显示进度条,2025年7月19日11:23:37将这个从下面的方法提起到这里, + startGiftProgressTime(); + mBinding.giftShowLayout.setVisibility(View.VISIBLE); + } + + private void hideGiftGiveProgress() { + mBinding.giftShowLayout.setVisibility(View.GONE); + if (giftCountTimer != null) { + giftCountTimer.cancel(); + giftCountTimer = null; + } + } + private void toggleFullScreen() { if (isFullScreen) { exitFullScreen(); @@ -276,11 +394,9 @@ public class RoomActivity extends BaseMvpActivity adapter; + BaseQuickAdapter adapter; private RoomOnline online; @@ -108,7 +108,7 @@ public class RoomKtvFragment extends BaseMvpFragment(R.layout.item_room_charm_rank) { + adapter = new BaseQuickAdapter(R.layout.item_room_charm_rank) { @Override - protected void convert(BaseViewHolder helper, RoomCharmRankBean item) { + protected void convert(BaseViewHolder helper, RoomPitBean item) { - RoomPitBean bean = new RoomPitBean(); - bean.setUser_id(item.getUser_id()); - bean.setRoom_id(roomInfoResp.getRoom_info().getRoom_id()); - bean.setNickname(item.getNickname()); - bean.setAvatar(item.getAvatar()); - bean.setDress(item.getDress()); - bean.setCharm(item.getCharm()); - bean.setPit_number("0"); +// RoomPitBean bean = new RoomPitBean(); +// bean.setUser_id(item.getUser_id()); +// bean.setRoom_id(roomInfoResp.getRoom_info().getRoom_id()); +// bean.setNickname(item.getNickname()); +// bean.setAvatar(item.getAvatar()); +// bean.setDress(item.getDress()); +// bean.setCharm(item.getCharm()); +// bean.setPit_number("0"); RoomDefaultWheatView mu_rank = helper.getView(R.id.mu_rank); - mu_rank.setData(bean); + mu_rank.setData(item); mu_rank.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -258,6 +257,9 @@ public class RoomKtvFragment extends BaseMvpFragment 0){ + adapter.setNewData(roomInfoResp.getSong_pit_list()); + } AgoraManager.getInstance(getActivity()).selectAudioTrack(0); isRotate = true; RoomDefaultWheatView muYc = mBinding.muYc; @@ -520,6 +522,7 @@ public class RoomKtvFragment extends BaseMvpFragment list) { - adapter.setNewData(list); +// adapter.setNewData(list); } @Override diff --git a/moduleroom/src/main/res/layout/item_room_charm_rank.xml b/moduleroom/src/main/res/layout/item_room_charm_rank.xml index d97ee0a8..34c37fc7 100644 --- a/moduleroom/src/main/res/layout/item_room_charm_rank.xml +++ b/moduleroom/src/main/res/layout/item_room_charm_rank.xml @@ -13,6 +13,6 @@ app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" - app:room_wheat_number="0"/> + app:room_wheat_number="9999"/> \ No newline at end of file diff --git a/modulevoice/src/main/java/com/example/modulevoice/fragment/VoiceCategoryFragment.java b/modulevoice/src/main/java/com/example/modulevoice/fragment/VoiceCategoryFragment.java index 252523e7..07d04b23 100644 --- a/modulevoice/src/main/java/com/example/modulevoice/fragment/VoiceCategoryFragment.java +++ b/modulevoice/src/main/java/com/example/modulevoice/fragment/VoiceCategoryFragment.java @@ -9,6 +9,7 @@ import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentStatePagerAdapter; + import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -27,6 +28,8 @@ import com.qxcm.moduleutil.base.BaseMvpFragment; import com.qxcm.moduleutil.bean.BannerModel; import com.qxcm.moduleutil.bean.RoomTypeModel; import com.qxcm.moduleutil.bean.TopRoom; +import com.qxcm.moduleutil.event.MqttBean; +import com.qxcm.moduleutil.event.RoomGiftRunable; import com.qxcm.moduleutil.utils.ARouteConstants; import com.qxcm.moduleutil.utils.ImageUtils; import com.stx.xhb.xbanner.XBanner; @@ -34,12 +37,14 @@ import com.sunfusheng.marqueeview.MarqueeView; import com.zhpan.bannerview.constants.PageStyle; import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; import java.util.ArrayList; import java.util.List; /** - *声播 + * 声播 */ public class VoiceCategoryFragment extends BaseMvpFragment implements VoiceCategoryContacts.View { @@ -51,7 +56,9 @@ public class VoiceCategoryFragment extends BaseMvpFragment roomList; - CarouselBannerAdapter carouselBannerAdapter ; + private List mqttList; + private List info; + CarouselBannerAdapter carouselBannerAdapter; public static VoiceCategoryFragment newInstance() { return new VoiceCategoryFragment(); @@ -84,7 +91,7 @@ public class VoiceCategoryFragment extends BaseMvpFragment info = new ArrayList<>(); - info.add("1. 大家好,我是孙福生。"); - info.add("2. 欢迎大家关注我哦!"); - info.add("3. GitHub帐号:sfsheng0322"); - info.add("4. 新浪微博:孙福生微博"); - info.add("5. 个人博客:sunfusheng.com"); - info.add("6. 微信公众号:孙福生"); - mBinding.marqueeView.startWithList(info); - mBinding.marqueeView.setOnItemClickListener(new MarqueeView.OnItemClickListener() { - @Override - public void onItemClick(int position, TextView textView) { - - ToastUtils.show("点击了第 " + position + " 个 item"); - } - }); +// mBinding.marqueeView.setOnItemClickListener(new MarqueeView.OnItemClickListener() { +// @Override +// public void onItemClick(int position, TextView textView) { +// +// ToastUtils.show("点击了第 " + position + " 个 item"); +// } +// }); mBinding.tvWg.setOnClickListener(v -> { - ToastUtils.show("点击了第 " + mBinding.marqueeView.getPosition() + " 个 item"); + ARouter.getInstance().build(ARouteConstants.ROOM_DETAILS).withString("form", "首页热门列表").withString("roomId", mqttList.get(mBinding.marqueeView.getPosition()).getRoomId()).navigation(); }); - mBinding.rl.setVisibility(GONE); + } + @Subscribe(threadMode = ThreadMode.MAIN) + public void onEvent(MqttBean event) { + + List cachedMqttBeans = RoomGiftRunable.getMqttCache(); + if (cachedMqttBeans == null || cachedMqttBeans.isEmpty()){ + mBinding.rl.setVisibility(GONE); + }else { + mBinding.rl.setVisibility(View.VISIBLE); + } + if (mqttList == null){ + mqttList = new ArrayList<>(); + info = new ArrayList<>(); + } + mqttList.clear(); + info.clear(); + // 处理缓存数据 + for (MqttBean mqttBean : cachedMqttBeans) { + // 处理每一条 mqttBean 数据 + mqttList.add(mqttBean.getList()); + info.add(mqttBean.getList().getFromUserName()+"送给"+mqttBean.getList().getToUserName()+"\n"+mqttBean.getList().getGiftName()); + } + +// if (mqttList == null) { +// info = new ArrayList<>(); +// mqttList = new ArrayList<>(); +// } +// if (mqttList.size() < 6) { +//// info.add(event.getList().getFromUserName()+"送给"+event.getList().getToUserName()+"\n"+event.getList().getGiftName()); +// mqttList.add(event.getList()); +// } else { +// mqttList.remove(0); // 移除第一条数据 +// info.remove(0); // 移除第一条数据 +// mqttList.add(event.getList()); +// } +// info.add(event.getList().getFromUserName()+"送给"+event.getList().getToUserName()+"\n"+event.getList().getGiftName()); + mBinding.marqueeView.startWithList(info); } // @@ -188,6 +223,11 @@ public class VoiceCategoryFragment extends BaseMvpFragment list) { @@ -208,14 +248,14 @@ public class VoiceCategoryFragment extends BaseMvpFragment topRooms,int type) { + public void setTopRoom(List topRooms, int type) { // if (topRooms == null || topRooms.isEmpty() || topRooms.size() < 1) { // mBinding.constraintLayout.setVisibility(View.GONE); // return; // }else { mBinding.constraintLayout.setVisibility(View.VISIBLE); // } - roomList= topRooms; + roomList = topRooms; mBinding.bannerViewPager.create(topRooms); // 刷新数据并启动自动播放 } diff --git a/settings.gradle b/settings.gradle index b9b5301f..7db68eb5 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,21 +7,9 @@ pluginManagement { includeGroupByRegex("androidx.*") } } - maven { url "https://maven.aliyun.com/repository/public/" } - maven { url "https://maven.aliyun.com/repository/central" } - maven { url "https://maven.aliyun.com/repository/gradle-plugin" } - maven { url 'https://maven.aliyun.com/repository/google' } // Google专属库 - maven { url "https://jitpack.io" } - maven { url "https://mvn.mob.com/android" } maven { url 'https://mirrors.cloud.tencent.com/nexus/repository/maven' } maven { url "https://mirrors.tencent.com/nexus/repository/maven-public/" } - mavenCentral() - gradlePluginPortal() - } -} -dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) - repositories { + maven { url 'https://mirrors.cloud.tencent.com/nexus/repository/maven_public/' } maven { url "https://maven.aliyun.com/repository/public/" } maven { url "https://maven.aliyun.com/repository/central" } @@ -29,9 +17,24 @@ dependencyResolutionManagement { maven { url 'https://maven.aliyun.com/repository/google' } // Google专属库 maven { url "https://jitpack.io" } maven { url "https://mvn.mob.com/android" } + mavenCentral() + gradlePluginPortal() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { maven { url 'https://mirrors.cloud.tencent.com/nexus/repository/maven' } maven { url "https://mirrors.tencent.com/nexus/repository/maven-public/" } - flatDir { dirs 'libs' } // 如果需要 flatDir,放在这里 + maven { url 'https://mirrors.cloud.tencent.com/nexus/repository/maven_public/' } + + maven { url "https://maven.aliyun.com/repository/public/" } + maven { url "https://maven.aliyun.com/repository/central" } + maven { url "https://maven.aliyun.com/repository/gradle-plugin" } + maven { url 'https://maven.aliyun.com/repository/google' } // Google专属库 + maven { url "https://jitpack.io" } + maven { url "https://mvn.mob.com/android" } + flatDir { dirs 'libs' } // 如果需要 flatDir,放在这里 google() mavenCentral() }