初版定稿

This commit is contained in:
2025-07-12 19:08:21 +08:00
parent 2d510ffe2a
commit 4a7e96473a
256 changed files with 325199 additions and 296285 deletions

View File

@@ -101,10 +101,26 @@ public abstract class BaseMvpActivity<P extends IPresenter, VDB extends ViewData
@Override
public void onSuccess() {
LogUtils.e("@@@","成功");
V2TIMUserFullInfo userFullInfo = new V2TIMUserFullInfo();
userFullInfo.setNickname(userBean.getNickname());
userFullInfo.setFaceUrl(userBean.getAvatar());
userFullInfo.setAllowType(userBean.getSex());
V2TIMManager.getInstance().setSelfInfo(userFullInfo, new V2TIMCallback() {
@Override
public void onSuccess() {
LogUtils.e("@@@", "成功");
}
@Override
public void onError(int code, String desc) {
LogUtils.e("@@@", "描述"+desc);
}
});
initLocation();
}
});
}
private SystemLocationProvider locationProvider;
private void initLocation() {

View File

@@ -1,14 +1,24 @@
package com.qxcm.moduleutil.activity;
import static android.view.View.GONE;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.webkit.GeolocationPermissions;
import android.webkit.JavascriptInterface;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
@@ -21,25 +31,44 @@ import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import com.alibaba.android.arouter.facade.annotation.Autowired;
import com.alibaba.android.arouter.launcher.ARouter;
import com.blankj.utilcode.util.LogUtils;
import com.qxcm.moduleutil.R;
import com.qxcm.moduleutil.base.CommonAppContext;
import com.qxcm.moduleutil.databinding.ActivityWebViewBinding;
import com.qxcm.moduleutil.utils.ARouteConstants;
import com.tencent.imsdk.v2.V2TIMConversation;
import com.tencent.mm.opensdk.modelbiz.WXOpenCustomerServiceChat;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.tencent.qcloud.tuicore.TUIConstants;
import com.tencent.qcloud.tuikit.tuichat.classicui.page.TUIC2CChatActivity;
import com.tencent.qcloud.tuikit.tuichat.classicui.page.TUIGroupChatActivity;
import java.util.Map;
import java.util.Objects;
/**
*@author qx
*@data 2025/6/3
*@description: webview公共方法
* @author qx
* @data 2025/6/3
* @description: webview公共方法
*/
public class WebViewActivity extends BaseAppCompatActivity<ActivityWebViewBinding> {
public String title;
public String url;
private ValueCallback<Uri> mUploadMessage;
private ValueCallback<Uri[]> mUploadCallbackAboveL;
private final int REQUEST_FILE_PICKER = 1;
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void initData() {
WebSettings webSettings = mBinding.webView.getSettings();
webSettings.setUseWideViewPort(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setJavaScriptEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE); //关闭webview中缓存
//增加JSBridge
mBinding.webView.addJavascriptInterface(new WebAppInterface(this), "Android");
// mBinding.webView.addJavascriptInterface(new WebViewBridgeConfig(title), WebViewBridgeConfig.NAME);
@@ -47,28 +76,126 @@ public class WebViewActivity extends BaseAppCompatActivity<ActivityWebViewBindin
webSettings.setSupportZoom(false);
webSettings.setDomStorageEnabled(true);
webSettings.setBlockNetworkImage(false);//解决图片不显示
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
mBinding.webView.setHorizontalScrollBarEnabled(false);//水平不显示
mBinding.webView.setVerticalScrollBarEnabled(false); //垂直不显示
mBinding.webView.requestFocus();
mBinding.webView.loadUrl(url);
// mBinding.webView.evaluateJavascript("javascript:window.Android.closeWeb()", new ValueCallback<String>() {
//
// @Override
// public void onReceiveValue(String value) {
// LogUtils.e("value: " + value);
// }
// });
mBinding.webView.setWebChromeClient(new WebChromeClient() {
//配置权限同样在WebChromeClient中实现
@Override
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
callback.invoke(origin, true, false);
super.onGeolocationPermissionsShowPrompt(origin, callback);
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
}
// For Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
mUploadMessage = uploadMsg;
// showFileChooser();
}
// For Android > 4.1.1
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
mUploadMessage = uploadMsg;
// showFileChooser();
}
// For Android > 5.0支持多张上传
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> uploadMsg, WebChromeClient.FileChooserParams
fileChooserParams) {
mUploadCallbackAboveL = uploadMsg;
showFileChooser();
return true;
}
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
// tvTitle.setText(title);
}
});
}
private void showFileChooser() {
// 这里可以扩展为显示对话框让用户选择“拍照”或“从相册选择”
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(Intent.createChooser(intent, "选择图片"), REQUEST_FILE_PICKER);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_FILE_PICKER) {
if (mUploadMessage != null) {
Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
} else if (mUploadCallbackAboveL != null) {
Uri[] results = null;
if (resultCode == Activity.RESULT_OK && data != null) {
String dataString = data.getDataString();
ClipData clipData = data.getClipData();
if (clipData != null) {
results = new Uri[clipData.getItemCount()];
for (int i = 0; i < clipData.getItemCount(); i++) {
ClipData.Item item = clipData.getItemAt(i);
results[i] = item.getUri();
}
}
if (dataString != null)
results = new Uri[]{Uri.parse(dataString)};
}
mUploadCallbackAboveL.onReceiveValue(results);
mUploadCallbackAboveL = null;
}
}
}
@Override
protected void initView() {
title = getIntent().getStringExtra("title");
url = getIntent().getStringExtra("url");
mBinding.topBar.setTitle(title);
if (title.equals("举报") || title.equals("等级") || title.equals("公会") || title.equals("邀请") || title.equals("反馈")) {
mBinding.topBar.setVisibility(GONE);
// mBinding.webView.setPadding(0,20,0,0);
} else {
mBinding.topBar.setVisibility(VISIBLE);
mBinding.topBar.setTitle(title);
}
}
@Override
protected int getLayoutId() {
return R.layout.activity_web_view;
}
public class WebAppInterface {
Context mContext;
@@ -81,5 +208,64 @@ public class WebViewActivity extends BaseAppCompatActivity<ActivityWebViewBindin
public void showToast(String toast) {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
}
@JavascriptInterface
public void closeWeb() {
LogUtils.e("value: ");
finish();
}
@JavascriptInterface
public void customerService() {
String appId = CommonAppContext.getInstance().getCurrentEnvironment().getWxAppId(); // 填移动应用(App)的 AppId
IWXAPI api = WXAPIFactory.createWXAPI(mContext, appId);
// 判断当前版本是否支持拉起客服会话
WXOpenCustomerServiceChat.Req req = new WXOpenCustomerServiceChat.Req();
req.corpId = "ww1de4300858c0b461"; // 企业ID
req.url = "https://work.weixin.qq.com/kfid/kfcb3d23a59c188a0e7"; // 客服URL
api.sendReq(req);
}
@JavascriptInterface
public void jumpRoomPage(String room_id) {
ARouter.getInstance().build(ARouteConstants.ROOM_DETAILS).withString("form", "首页").withString("roomId", room_id).navigation();
}
@JavascriptInterface
public void jumpWebPage(String objects) {
// ARouter.getInstance().build(ARouteConstants.USER_HOME_PAGE).navigation();
ARouter.getInstance().build(ARouteConstants.USER_HOME_PAGE).withString("userId", objects).navigation();
}
@JavascriptInterface
public void enterGroupChat(String group_id,String cover,String guild_name) {
Intent intent = new Intent(mContext, TUIGroupChatActivity.class);
intent.putExtra(TUIConstants.TUIChat.CHAT_ID, group_id);
intent.putExtra(TUIConstants.TUIChat.CHAT_TYPE, V2TIMConversation.V2TIM_GROUP);
mContext.startActivity(intent);
}
@JavascriptInterface
public void chatWithUser(String user_id,String nickname) {
Intent intent = new Intent(mContext, TUIC2CChatActivity.class);
intent.putExtra(TUIConstants.TUIChat.CHAT_ID, user_id);
intent.putExtra(TUIConstants.TUIChat.CHAT_TYPE, V2TIMConversation.V2TIM_C2C);
mContext.startActivity(intent);
}
@JavascriptInterface
public void exchange(){
ARouter.getInstance().build(ARouteConstants.CURRENCY).navigation();
}
}
@JavascriptInterface
public void closeWeb() {
//做原生操作
// Intent intent = new Intent(mContext, ListActivity.class);
// intent.putExtra("menuName", msg);
// startActivity(intent);
LogUtils.e("closeWeb");
}
}

View File

@@ -39,7 +39,7 @@ public class BalanceRechargeAdapter extends BaseMultiItemQuickAdapter<RechargeBe
if (type == ITEM_TYPE_NORMAL) {
// 正常 item 显示逻辑
helper.setText(R.id.tv_gold_num, item.getGoldNum());
helper.setText(R.id.tv_gold_num, item.getCoins());
helper.setText(R.id.tv_money, String.format("¥%s", item.getMoney()));
if (selectedPosition == helper.getAdapterPosition()) {
helper.setBackgroundRes(R.id.cl_item, com.qxcm.moduleutil.R.drawable.bg_10_white_sele);

View File

@@ -96,7 +96,11 @@ import java.util.List;
}
return super.getItemPosition(object);
}
public void updateFragments(List<Fragment> newFragments) {
this.mFragmentList.clear();
this.mFragmentList.addAll(newFragments);
notifyDataSetChanged();
}
@Override
public long getItemId(int position) {
return mItemIdList.get(position);

View File

@@ -74,7 +74,8 @@ public class GiftRoomAdapter extends BaseAdapter {
private static class MyGestureDetector extends GestureDetector {
private static WeakReference<GiftRoomAdapter> sAdapter = new WeakReference<>(null);
private static RoonGiftModel sGiftModel;
private GiftRoomAdapter mAdapter;
private RoonGiftModel mGiftModel;
public void setGiftModel(GiftRoomAdapter adapter, RoonGiftModel gift) {
sAdapter = new WeakReference<>(adapter);
sGiftModel = gift;
@@ -100,6 +101,38 @@ public class GiftRoomAdapter extends BaseAdapter {
}
}
// private static class MyGestureDetector extends GestureDetector {
// private GiftRoomAdapter mAdapter;
// private RoonGiftModel mGiftModel;
//
// public MyGestureDetector(Context context) {
// super(context, new SimpleOnGestureListener() {
// @Override
// public boolean onSingleTapConfirmed(MotionEvent e) {
// if (mAdapter != null && mGiftModel != null) {
// EventBus.getDefault().post(new RoomGiftClickToEvent(mAdapter, mGiftModel, 1));
// }
// return true;
// }
//
// @Override
// public boolean onDoubleTap(MotionEvent e) {
// if (mAdapter != null && mGiftModel != null) {
// EventBus.getDefault().post(new RoomGiftClickToEvent(mAdapter, mGiftModel, 2));
// }
// return true;
// }
// });
// setOnDoubleTapListener(getListener());
// }
//
// public void setGiftModel(GiftRoomAdapter adapter, RoonGiftModel giftModel) {
// this.mAdapter = adapter;
// this.mGiftModel = giftModel;
// }
// }
@Override
@SuppressLint({"SetTextI18n", "ClickableViewAccessibility"})
public View getView(int position, View convertView, ViewGroup parent) {
@@ -115,17 +148,29 @@ public class GiftRoomAdapter extends BaseAdapter {
viewHolder.ivDownOn = (ImageView) convertView.findViewById(R.id.iv_down_on);
viewHolder.cl_iv_down_on = (ConstraintLayout) convertView.findViewById(R.id.cl_iv_down_on);
// viewHolder.tv_gift_num = convertView.findViewById(R.id.tv_gift_num);
// viewHolder.tv_gift_change_love_values = convertView.findViewById(R.id.tv_gift_change_love_values);
viewHolder.item_layout.setOnTouchListener((v, event) -> {
gestureDetector.setGiftModel(GiftRoomAdapter.this, giftModel);
gestureDetector.onTouchEvent(event);
return true;
});
// viewHolder.tv_gift_change_love_values = convertView.findViewById(R.id.tv_gift_change_love_values);
// viewHolder.item_layout.setOnTouchListener((v, event) -> {
// gestureDetector.setGiftModel(GiftRoomAdapter.this, giftModel);
// gestureDetector.onTouchEvent(event);
//
// return true;
// });
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.item_layout.setOnClickListener(v -> {
// RoonGiftModel clickedModel = (RoonGiftModel) v.getTag();
EventBus.getDefault().post(new RoomGiftClickToEvent(this, giftModel, 1));
});
/*
* 在给View绑定显示的数据时计算正确的position = position + curIndex * pageSize
*/

View File

@@ -35,6 +35,8 @@ 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.SpUtil;
import com.qxcm.moduleutil.utils.UtilConfig;
@@ -49,6 +51,8 @@ import com.scwang.smartrefresh.layout.api.RefreshFooter;
import com.scwang.smartrefresh.layout.api.RefreshHeader;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.footer.ClassicsFooter;
import com.tencent.qcloud.tuicore.TUILogin;
import com.tencent.qcloud.tuicore.interfaces.TUICallback;
import org.greenrobot.eventbus.EventBus;
@@ -101,9 +105,13 @@ public class CommonAppContext extends MultiDexApplication {
UtilConfig.checkInEmulator();
}
}
// ServiceUtils.startService(EMqttService.class);
// MyMqttService.startService(getApplicationContext());
// ServiceUtils.startService(MyMqttService.class);
// RtcManager.instance(this);
EnvironmentPrefs prefs = new EnvironmentPrefs(this);
currentEnvironment = prefs.getSelectedEnvironment();
// startInitSdk();
}
private void initARouter() {
@@ -293,7 +301,21 @@ public class CommonAppContext extends MultiDexApplication {
}
public void startInitSdk() {
UserBean userBean = SpUtil.getUserBean();
if (userBean != null){
// 在用户 UI 点击登录的时候调用
TUILogin.login(getBaseContext(), CommonAppContext.getInstance().getCurrentEnvironment().getSdkAppId(), "u"+userBean.getUser_id(), userBean.getTencent_im(), new TUICallback() {
@Override
public void onError(final int code, final String desc) {
LogUtils.e("@@@1",code,"描述:",desc);
}
@Override
public void onSuccess() {
LogUtils.e("@@@","成功");
}
});
}
}
public void setUser(UserBean userBean) {
@@ -327,6 +349,9 @@ 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());
}
public static boolean isAlipayInstalled(Context context) {

View File

@@ -0,0 +1,23 @@
package com.qxcm.moduleutil.bean;
import lombok.Data;
/**
*@author qx
*@data 2025/7/11
*@description:支付的时候,返回的参数
*/
@Data
public class AppPay {
private String ali;
private WxBean wx;
@Data
public static class WxBean {
private String appid;
private String noncestr;
private String partnerid;
private String prepayid;
private String timestamp;
private String sign;
}
}

View File

@@ -17,72 +17,17 @@ public class BannerModel extends SimpleBannerInfo {
* detail_pictures : null
*/
private String ad_id;
private String bid;
private String aid;
private String type;
private String title;
private String item_id;
private String link_url;
private String content;
private String show_type;
private String image;
private String url;
private ArrayList<String> detail_pictures;
public String getAd_id() {
return ad_id;
}
public void setAd_id(String ad_id) {
this.ad_id = ad_id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getItem_id() {
return item_id;
}
public void setItem_id(String item_id) {
this.item_id = item_id;
}
public String getLink_url() {
return link_url;
}
public void setLink_url(String link_url) {
this.link_url = link_url;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public ArrayList<String> getDetail_pictures() {
return detail_pictures;
}
public void setDetail_pictures(ArrayList<String> detail_pictures) {
this.detail_pictures = detail_pictures;
}
@Override
public Object getXBannerUrl() {
return content;
return image;
}
}

View File

@@ -0,0 +1,28 @@
package com.qxcm.moduleutil.bean;
import lombok.Data;
/**
* @author qx
* @data 2025/7/11
* @description:支付或者提现方式和状态
*/
@Data
public class BindType {
private AllData ali;
private AllData wx;
private AllData bank;
private AllData ali_tl;
private AllData wx_tl;
@Data
public static class AllData {
private String name;//名称
private String icon;//图标
private String is_with_draw_open;//提现状态是否打开
private String is_bind;//是否绑定 1是 0否
private String type;// 支付 | 提现类型
private String is_pay_open;//是否开启 1是 0否
}
}

View File

@@ -10,14 +10,51 @@ import lombok.Data;
*/
@Data
public class GiftBoxBean {
private String newDataJinbi;
private List<GiftBean> giftList;
private String user_gold;//累计获取的金币
private List<GiftBean> gift_box_list;
private TaskDataBean tasks;
@Data
public static class GiftBean {
private String giftName; //初级礼盒、高级礼盒
private String giftTitle; //最高可以获得的金币数
private String getGiftTypeName; //满多少个金币
private String giftTypeNumber; //当前的百分比
private String giftTypeStatus; //是否已经可以
// private String giftName; //初级礼盒、高级礼盒
// private String giftTitle; //最高可以获得的金币数
// private String getGiftTypeName; //满多少个金币
// private String giftTypeNumber; //当前的百分比
// private String giftTypeStatus; //是否已经可以
private String id;//礼盒ID
private String name;//礼盒名称
private String title; //标题
private String icon ;//图标
private String highest_gain;//最高获得金币数
private String meet;//满多少金币可抽
private String unlock_progress;// //解锁进度
private String all_number;// //今日可抽奖次数
private String taday_number;////今日剩余抽奖次数
private String taday_number_left;// //今日剩余抽奖次数
private String status;////状态:0 '未解锁 1已解锁 2抽奖次数已用完
private String status_str;//"已解锁(0/2)"
}
@Data
public static class TaskDataBean {
private List<DailyTasksBean> daily_tasks;
private List<DailyTasksBean> daily_tasks_special;
private List<DailyTasksBean> usual_tasks;
@Data
public static class DailyTasksBean {
private int task_id;////任务Id
private String task_name;//任务名称
private String icon;//图标
private int gold_reward; //奖励金币
private int target_quantity;//目标完成数量
private int task_type;//任务类型 1每日任务 2每日特殊任务 3平台常规任务
private int task_status;//任务状态1完成 2去领取 3已领取
private String task_type_str; //任务状态
private int processing_type;//跳转状态:
private String processing_type_str;//跳转状态
private String from_id;
}
}
}

View File

@@ -0,0 +1,15 @@
package com.qxcm.moduleutil.bean;
import lombok.Data;
/**
*@author qx
*@data 2025/7/12
*@description: 礼盒记录
*/
@Data
public class GiftBoxRecordBean {
private String gift_bag_name;
private String gift_name;
private String createtime;
}

View File

@@ -0,0 +1,13 @@
package com.qxcm.moduleutil.bean;
import lombok.Data;
/**
*@author qx
*@data 2025/7/12
*@description: 开启礼盒后获取的礼物名称
*/
@Data
public class GiftName {
private String gift_name;
}

View File

@@ -0,0 +1,16 @@
package com.qxcm.moduleutil.bean;
import lombok.Data;
/**
*@author qx
*@data 2025/7/12
*@description: 获取背包礼物列表
*/
@Data
public class GiftPackBean {
private String gift_id;
private String gift_name;
private String base_image;
private String gift_price;
private String num;
}

View File

@@ -0,0 +1,22 @@
package com.qxcm.moduleutil.bean;
import lombok.Data;
/**
*@author qx
*@data 2025/7/10
*@description:发布头条需要的参数
*/
@Data
public class HeadlineBean {
private String countdown;
private String now_money;
private String next_money;
private String id;
private String user_id;//用户ID
private String content;//内容
private String money;//花了多钱发的这个头条
private String nickname;//昵称
private String avatar;//头像
}

View File

@@ -0,0 +1,84 @@
package com.qxcm.moduleutil.bean;
import java.util.List;
import lombok.Data;
/**
*@author qx
*@data 2025/7/11
*@description: 榜单实体类
*/
@Data
public class PlaceholderBean {
private MyRanking my_ranking;//自己的排行信息
private List<ListsBean> lists;//榜单信息
@Data
public static class MyRanking {
private String avatar;
private String nickname;
private String user_id;
private String user_code;//
private String sex;//性别
private List<String> icon;//
private String total;//值
private String rank;//排名
private String diff;//差上榜需要这么多
private String room_name;
private String room_id;
private String room_cover;
private int id;//公会id
private String guild_special_id;
private String guild_name;
private String cover;
private int num;
private int expenditure;
private String intro;
private String createtime;
private String updatetime;
private String delete_time;
private int is_show;
private int status;
private String user_id1;
private String user_avatar;
private String user_avatar1;
}
@Data
public static class ListsBean {
private String user_id;
private String nickname;
private String avatar;
private String total;
private String rank;
private List<String> icon;
private String room_name;
private String room_id;
private String room_cover;
private int id;//公会id
private String guild_special_id;
private String guild_name;
private String cover;
private int num;
private int expenditure;
private String intro;
private String createtime;
private String updatetime;
private String delete_time;
private int is_show;
private int status;
private int income;
private String user_id1;
private String user_avatar;
private String user_avatar1;
}
}

View File

@@ -16,4 +16,10 @@ public class RealNameBean {
private String apiVersion;
private String licence;
private String faceId;
private String id;
private String mobile;
private int is_real;
private String real_name;
private String card_id;
}

View File

@@ -18,7 +18,7 @@ import lombok.Data;
@Data
public class RechargeBean implements MultiItemEntity {
private int itemViewType;
private String goldNum;
private String coins;
private String money;
private boolean isCustom; // 是否为自定义项

View File

@@ -4,8 +4,15 @@ import lombok.Data;
@Data
public class RevenueBean {
private String title;
private String time;
private String money;
private String type;
private String id;
private String user_id;
private String change_type;
private String change_type_name;
private String change_value;
private String remarks;
private String createtime;
// private String title;
// private String time;
// private String money;
// private String type;
}

View File

@@ -0,0 +1,21 @@
package com.qxcm.moduleutil.bean;
import lombok.Data;
/**
*@author qx
*@data 2025/7/8
*@description: 这是在打开获取我的房间时添加的title名称和图标
*/
@Data
public class RoomData {
private String title;//例如:我的电影房
private int titleIcon;//例如我的电影房前面的图标
private int titleType;//例如我的足迹,后面的图标
public RoomData(String title, int titleIcon, int titleType) {
this.title = title;
this.titleIcon = titleIcon;
this.titleType = titleType;
}
}

View File

@@ -4,6 +4,8 @@ import com.chad.library.adapter.base.entity.MultiItemEntity;
import java.util.List;
import lombok.Data;
public class RoomDetails {
/**
* list : [{"total_price":416,"total_earning":83.2,"time":"2025-03-07","list":[{"user_head_picture":"https://osschumeng.oss-cn-beijing.aliyuncs.com/admin_images/67932634b1555.png","user_nickname":"用户10137552","get_user_nickname":"用户10137840","gift_name":"退烧药","gift_number":"3","total_price":"297.00","time":"2025-03-07","earning":59.4},{"user_head_picture":"https://osschumeng.oss-cn-beijing.aliyuncs.com/admin_images/67932634b1555.png","user_nickname":"用户10137552","get_user_nickname":"用户10137840","gift_name":"征婚帖","gift_number":"1","total_price":"19.00","time":"2025-03-07","earning":3.8},{"user_head_picture":"https://osschumeng.oss-cn-beijing.aliyuncs.com/admin_images/67932634b1555.png","user_nickname":"用户10137552","get_user_nickname":"用户10137840","gift_name":"香槟","gift_number":"1","total_price":"99.00","time":"2025-03-07","earning":19.8},{"user_head_picture":"https://osschumeng.oss-cn-beijing.aliyuncs.com/admin_images/67932634b1555.png","user_nickname":"钊","get_user_nickname":"用户10137840","gift_name":"小心心","gift_number":"1","total_price":"1.00","time":"2025-03-07","earning":0.2}]}]
@@ -113,7 +115,8 @@ public class RoomDetails {
return itemViewType;
}
public static class RoomDetail implements MultiItemEntity{
@Data
public static class RoomDetail implements MultiItemEntity {
/**
* user_head_picture : https://osschumeng.oss-cn-beijing.aliyuncs.com/admin_images/67932634b1555.png
* user_nickname : 用户10137552
@@ -125,84 +128,17 @@ public class RoomDetails {
* earning : 59.4
*/
private int itemViewType = 2;
private String user_head_picture;
private String user_nickname;
private String get_user_nickname;
private String sender_nickname;
private String sender_avatar;
private String receive_nickname;
private String receive_avatar;
private String gift_name;
private int gift_number;
private int number;
private double total_price;
private String time;
private double earning;
public String getUser_head_picture() {
return user_head_picture;
}
public void setUser_head_picture(String user_head_picture) {
this.user_head_picture = user_head_picture;
}
public String getUser_nickname() {
return user_nickname;
}
public void setUser_nickname(String user_nickname) {
this.user_nickname = user_nickname;
}
public String getGet_user_nickname() {
return get_user_nickname;
}
public void setGet_user_nickname(String get_user_nickname) {
this.get_user_nickname = get_user_nickname;
}
public String getGift_name() {
return gift_name;
}
public void setGift_name(String gift_name) {
this.gift_name = gift_name;
}
public int getGift_number() {
return gift_number;
}
public void setGift_number(int gift_number) {
this.gift_number = gift_number;
}
public double getTotal_price() {
return total_price;
}
public void setTotal_price(double total_price) {
this.total_price = total_price;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public double getEarning() {
return earning;
}
public void setEarning(double earning) {
this.earning = earning;
}
public void setItemViewType(int itemViewType) {
this.itemViewType = itemViewType;
}
@Override
public int getItemType() {
return itemViewType;

View File

@@ -66,6 +66,7 @@ public class RoomMessageEvent {
@Data
public static class text {
private long position;
private int is_mute;
}
}

View File

@@ -0,0 +1,25 @@
package com.qxcm.moduleutil.bean;
import com.chad.library.adapter.base.entity.MultiItemEntity;
import java.util.List;
import lombok.Data;
/**
*@author qx
*@data 2025/7/12
*@description: 这个是每日任务
*/
@Data
public class TaskItem {
public String title;
public List<GiftBoxBean.TaskDataBean.DailyTasksBean> tasks;
public TaskItem(String title, List<GiftBoxBean.TaskDataBean.DailyTasksBean> dailyTasks) {
this.title = title;
this.tasks = dailyTasks;
}
}

View File

@@ -16,6 +16,7 @@ public class TopRoom implements MultiItemEntity {
private String room_cover;//房间封面
private String room_password;//房间密码
private String hot_value;//火热值
private String label_icon;
private List<UserList> user_list;
@Override

View File

@@ -0,0 +1,15 @@
package com.qxcm.moduleutil.bean;
import lombok.Data;
/**
*@author qx
*@data 2025/7/11
*@description: 钱包相关配置接口
*/
@Data
public class WalletConfig {
private String coin_exchange_rate;
private String withdrawal_service_fee;
private String rmb_coin_ratio;
}

View File

@@ -0,0 +1,17 @@
package com.qxcm.moduleutil.bean;
import lombok.Data;
/**
*@author qx
*@data 2025/7/12
*@description: 提现记录实体
*/
@Data
public class WithdrawalBean {
private String name;
private String money;
private String status;
private String status_str;
private String createtime;
}

View File

@@ -1,11 +1,14 @@
package com.qxcm.moduleutil.bean.details;
import lombok.Data;
public class RoomDeatil extends BaseMultiItemEntity {
private String user_head_picture;
private String user_nickname;
private String get_user_nickname;
private String sender_nickname;
private String sender_avatar;
private String receive_nickname;
private String receive_avatar;
private String gift_name;
private int gift_number;
private int number;
private double total_price;
private String time;
private double earning;
@@ -14,29 +17,36 @@ public class RoomDeatil extends BaseMultiItemEntity {
super(BaseMultiItemEntity.TYPE_B);
}
// 添加相应的 getter 和 setter 方法
public String getUser_head_picture() {
return user_head_picture;
public String getSender_nickname() {
return sender_nickname;
}
public void setUser_head_picture(String user_head_picture) {
this.user_head_picture = user_head_picture;
public void setSender_nickname(String sender_nickname) {
this.sender_nickname = sender_nickname;
}
public String getUser_nickname() {
return user_nickname;
public String getSender_avatar() {
return sender_avatar;
}
public void setUser_nickname(String user_nickname) {
this.user_nickname = user_nickname;
public void setSender_avatar(String sender_avatar) {
this.sender_avatar = sender_avatar;
}
public String getGet_user_nickname() {
return get_user_nickname;
public String getReceive_nickname() {
return receive_nickname;
}
public void setGet_user_nickname(String get_user_nickname) {
this.get_user_nickname = get_user_nickname;
public void setReceive_nickname(String receive_nickname) {
this.receive_nickname = receive_nickname;
}
public String getReceive_avatar() {
return receive_avatar;
}
public void setReceive_avatar(String receive_avatar) {
this.receive_avatar = receive_avatar;
}
public String getGift_name() {
@@ -47,12 +57,12 @@ public class RoomDeatil extends BaseMultiItemEntity {
this.gift_name = gift_name;
}
public int getGift_number() {
return gift_number;
public int getNumber() {
return number;
}
public void setGift_number(int gift_number) {
this.gift_number = gift_number;
public void setNumber(int number) {
this.number = number;
}
public double getTotal_price() {
@@ -78,4 +88,6 @@ public class RoomDeatil extends BaseMultiItemEntity {
public void setEarning(double earning) {
this.earning = earning;
}
// 添加相应的 getter 和 setter 方法
}

View File

@@ -74,6 +74,7 @@ public class EMMessageInfo implements MultiItemEntity {
public static final int QXRoomMessageTypeRoomPKDisconnect = 1033;
///关闭对方麦克风
public static final int QXRoomMessageTypeMuteRemoteAudio = 125;
public static final int QXRoomMessageTypeMuteLocalAudio = 126;
private RoomMessageEvent emMessage;
private int custom = 0;

View File

@@ -1,5 +1,6 @@
package com.qxcm.moduleutil.bean.room;
import com.qxcm.moduleutil.bean.HeadlineBean;
import com.qxcm.moduleutil.bean.MusicSongBean;
import java.io.Serializable;
@@ -87,6 +88,8 @@ public class RoomBean implements Serializable {
private String room_up_pit_type;
private int online_number;
private HeadlineBean head_line;
private String room_code;
private String popularity;

View File

@@ -1,5 +1,7 @@
package com.qxcm.moduleutil.bean.room;
import java.io.Serializable;
import lombok.Data;
/**
@@ -8,7 +10,7 @@ import lombok.Data;
*@description: Cp电影房用户信息
*/
@Data
public class RoomCpUserBean {
public class RoomCpUserBean implements Serializable {
private String time_day;
private String user_id;
private String nickname;

View File

@@ -59,6 +59,7 @@ public class RoomPitBean implements Serializable {
private int is_online;//是否在线 : 1在线 2离线
private String to_pit_number;
private boolean is_pk;//是否是在pk模式中
private boolean isMute;//是否打开麦圈
}

View File

@@ -19,6 +19,8 @@ import com.qxcm.moduleutil.adapter.BalanceRechargeAdapter;
import com.qxcm.moduleutil.base.BaseMvpDialogFragment;
import com.qxcm.moduleutil.bean.RechargeBean;
import com.qxcm.moduleutil.databinding.FragmentRechargeDialogBinding;
import com.qxcm.moduleutil.presenter.RechargeDialogContacts;
import com.qxcm.moduleutil.presenter.RechargeDialogPresenter;
import java.util.ArrayList;
import java.util.List;
@@ -28,7 +30,7 @@ import java.util.List;
*@data 2025/6/12
*@description: 充值弹框
*/
public class RechargeDialogFragment extends BaseMvpDialogFragment<IPresenter, FragmentRechargeDialogBinding> {
public class RechargeDialogFragment extends BaseMvpDialogFragment<RechargeDialogPresenter, FragmentRechargeDialogBinding> implements RechargeDialogContacts.View {
private BalanceRechargeAdapter rechargeAdapter;
private String money = "0";
private int type = 1;
@@ -47,56 +49,78 @@ public class RechargeDialogFragment extends BaseMvpDialogFragment<IPresenter, Fr
}
@Override
protected IPresenter bindPresenter() {
return null;
protected RechargeDialogPresenter bindPresenter() {
return new RechargeDialogPresenter(this, getContext());
}
@Override
protected void initData() {
List<RechargeBean> rechargeList = new ArrayList<>();
RechargeBean bean1 = new RechargeBean();
bean1.setGoldNum("60");
bean1.setMoney("6");
bean1.setItemViewType(0);
rechargeList.add(bean1);
RechargeBean bean2 = new RechargeBean();
bean2.setGoldNum("100");
bean2.setMoney("10");
bean2.setItemViewType(0);
rechargeList.add(bean2);
RechargeBean bean3 = new RechargeBean();
bean3.setGoldNum("300");
bean3.setMoney("30");
bean3.setItemViewType(0);
rechargeList.add(bean3);
RechargeBean bean4 = new RechargeBean();
bean4.setGoldNum("500");
bean4.setMoney("50");
bean4.setItemViewType(0);
rechargeList.add(bean4);
MvpPre.recharge();
// List<RechargeBean> rechargeList = new ArrayList<>();
// RechargeBean bean1 = new RechargeBean();
// bean1.setGoldNum("60");
// bean1.setMoney("6");
// bean1.setItemViewType(0);
// rechargeList.add(bean1);
// RechargeBean bean2 = new RechargeBean();
// bean2.setGoldNum("100");
// bean2.setMoney("10");
// bean2.setItemViewType(0);
// rechargeList.add(bean2);
//
// RechargeBean bean3 = new RechargeBean();
// bean3.setGoldNum("300");
// bean3.setMoney("30");
// bean3.setItemViewType(0);
// rechargeList.add(bean3);
// RechargeBean bean4 = new RechargeBean();
// bean4.setGoldNum("500");
// bean4.setMoney("50");
// bean4.setItemViewType(0);
// rechargeList.add(bean4);
//
// RechargeBean bean5 = new RechargeBean();
// bean5.setGoldNum("680");
// bean5.setMoney("68");
// bean5.setItemViewType(0);
// rechargeList.add(bean5);
// RechargeBean bean6 = new RechargeBean();
// bean6.setGoldNum("1280");
// bean6.setMoney("128");
// bean6.setItemViewType(0);
// rechargeList.add(bean6);
//
// // 在数据源最后添加一个自定义项
// RechargeBean customItem = new RechargeBean();
// customItem.setGoldNum("自定义");
// customItem.setMoney("");
// customItem.setItemViewType(1);
// rechargeList.add(customItem);
RechargeBean bean5 = new RechargeBean();
bean5.setGoldNum("680");
bean5.setMoney("68");
bean5.setItemViewType(0);
rechargeList.add(bean5);
RechargeBean bean6 = new RechargeBean();
bean6.setGoldNum("1280");
bean6.setMoney("128");
bean6.setItemViewType(0);
rechargeList.add(bean6);
// 在数据源最后添加一个自定义项
}
@Override
protected void initView() {
}
@Override
protected int getLayoutId() {
return R.layout.fragment_recharge_dialog;
}
@Override
public void setRechargeData(List<RechargeBean> rechargeData) {
RechargeBean customItem = new RechargeBean();
customItem.setGoldNum("自定义");
customItem.setCoins("自定义");
customItem.setMoney("");
customItem.setItemViewType(1);
rechargeList.add(customItem);
rechargeAdapter = new BalanceRechargeAdapter(rechargeList);
rechargeAdapter.setNewData(rechargeList);
rechargeData.add(customItem);
rechargeAdapter = new BalanceRechargeAdapter(rechargeData);
rechargeAdapter.setNewData(rechargeData);
rechargeAdapter.setListener(new BalanceRechargeAdapter.OnRechargeItemClickListener() {
@Override
public void onClick(RechargeBean rechargeBean) {
@@ -113,17 +137,6 @@ public class RechargeDialogFragment extends BaseMvpDialogFragment<IPresenter, Fr
});
mBinding.rvComment.setLayoutManager(new GridLayoutManager(getContext(), 3));
mBinding.rvComment.setAdapter(rechargeAdapter);
money = bean1.getMoney();
mBinding.tvPayment.setText(String.format("立即支付(%s元)", money));
}
@Override
protected void initView() {
}
@Override
protected int getLayoutId() {
return R.layout.fragment_recharge_dialog;
}
}

View File

@@ -0,0 +1,16 @@
package com.qxcm.moduleutil.event;
/**
* 项目名称 qipao-android
* 包名com.yutang.xqipao.data.even
* 创建人 王欧
* 创建时间 2020/7/18 9:42 AM
* 描述 describe
*/
public class BossMsgEvent {
public String msg;
public BossMsgEvent(String msg) {
this.msg = msg;
}
}

View File

@@ -0,0 +1,8 @@
package com.qxcm.moduleutil.event;
import lombok.Data;
@Data
public class CabinEvent {
private boolean joined;
}

View File

@@ -0,0 +1,8 @@
package com.qxcm.moduleutil.event;
/**
*@author qx
*@data 2025/7/11
*@description: 关闭屏幕共享
*/
public class ColoseCardEvent {
}

View File

@@ -0,0 +1,36 @@
package com.qxcm.moduleutil.event;
/**
* Copyright (c) 1
*
* @Description
* @Author 1
* @Copyright Copyright (c) 1
* @Date $date$ $time$
*/
public class PayEvent {
public PayEvent(int type, String content) {
this.type = type;
this.content = content;
}
int type;
String content;
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}

View File

@@ -0,0 +1,3 @@
package com.qxcm.moduleutil.event
data class QDZMqttEvent(var json: String)

View File

@@ -2,25 +2,39 @@ package com.qxcm.moduleutil.http;
import com.qxcm.moduleutil.bean.AlbumBean;
import com.qxcm.moduleutil.bean.AppPay;
import com.qxcm.moduleutil.bean.BannerModel;
import com.qxcm.moduleutil.bean.BindType;
import com.qxcm.moduleutil.bean.BlackUserBean;
import com.qxcm.moduleutil.bean.CircleListBean;
import com.qxcm.moduleutil.bean.CommentBean;
import com.qxcm.moduleutil.bean.ExpandColumnBean;
import com.qxcm.moduleutil.bean.GiftBoxBean;
import com.qxcm.moduleutil.bean.GiftBoxRecordBean;
import com.qxcm.moduleutil.bean.GiftLabelBean;
import com.qxcm.moduleutil.bean.GiftName;
import com.qxcm.moduleutil.bean.GiftPackBean;
import com.qxcm.moduleutil.bean.HeadlineBean;
import com.qxcm.moduleutil.bean.HeatedBean;
import com.qxcm.moduleutil.bean.HostBean;
import com.qxcm.moduleutil.bean.MusicSongBean;
import com.qxcm.moduleutil.bean.MyBagDataBean;
import com.qxcm.moduleutil.bean.MyCpRoom;
import com.qxcm.moduleutil.bean.MyFootResp;
import com.qxcm.moduleutil.bean.MyRoomBean;
import com.qxcm.moduleutil.bean.NewsDataBean;
import com.qxcm.moduleutil.bean.PersonaltyBean;
import com.qxcm.moduleutil.bean.PlaceholderBean;
import com.qxcm.moduleutil.bean.RealNameBean;
import com.qxcm.moduleutil.bean.RechargeBean;
import com.qxcm.moduleutil.bean.RevenueBean;
import com.qxcm.moduleutil.bean.RewardUserBean;
import com.qxcm.moduleutil.bean.RoomBgBean;
import com.qxcm.moduleutil.bean.RoomCharmRankBean;
import com.qxcm.moduleutil.bean.RoomDetails;
import com.qxcm.moduleutil.bean.RoomRelationBean;
import com.qxcm.moduleutil.bean.RoomSearchResp;
import com.qxcm.moduleutil.bean.RoomSubsidy;
import com.qxcm.moduleutil.bean.RoomTime;
import com.qxcm.moduleutil.bean.RoomTypeModel;
import com.qxcm.moduleutil.bean.RoonGiftModel;
@@ -30,6 +44,8 @@ import com.qxcm.moduleutil.bean.UserBean;
import com.qxcm.moduleutil.bean.UserInfo;
import com.qxcm.moduleutil.bean.UserTagBean;
import com.qxcm.moduleutil.bean.WalletBean;
import com.qxcm.moduleutil.bean.WalletConfig;
import com.qxcm.moduleutil.bean.WithdrawalBean;
import com.qxcm.moduleutil.bean.room.AuctionBean;
import com.qxcm.moduleutil.bean.room.RoomApplyListBean;
import com.qxcm.moduleutil.bean.room.RoomAuction;
@@ -66,9 +82,66 @@ public interface ApiServer {
@POST(Constants.USER_LOGIN)
Call<BaseModel<List<UserBean>>> userLogin(@Field("user_login") String user_login, @Field("password") String password);
@FormUrlEncoded
@POST(Constants.EARNINGS_NUM)
Call<BaseModel<String>> exchangeCoin(@Field("earnings_num") String earnings_num);
@POST(Constants.UPLOAD_NICK_NAME)
Call<ResponseBody> upUserNickname();
@FormUrlEncoded
@POST(Constants.dailyTasksOpenBox)
Observable<BaseModel<GiftName>> dailyTasksOpenBox(@Field("gift_box_id") String gift_box_id);
@FormUrlEncoded
@POST(Constants.SEND_HEADLINE)
Call<BaseModel<String>> sendHeadine(@Field("content") String content ,@Field("money") String money);
@FormUrlEncoded
@POST(Constants.POST_WITHDRAWAL)
Call<ResponseBody> withdrawal(@Field("number") String number,@Field("type") String type,@Field("sms_code") String sms_code);
@GET(Constants.CURRENT_HEADLINE)
Observable<BaseModel<HeadlineBean>> currentHeadline();
@GET(Constants.GET_TASKS_LIHEN)
Call<ResponseBody> tasksLihen();
@FormUrlEncoded
@POST(Constants.POST_LOG_LIST)
Observable<BaseModel<List<RevenueBean>>> getRevenueData(@Field("page") String page, @Field("page_limit") String page_limit, @Field("in_out_type") String in_out_type, @Field("start_time") String start_time, @Field("end_time") String end_time, @Field("gift_type") String gift_type);
@FormUrlEncoded
@POST(Constants.POST_WEALTH_RANKING)
Observable<BaseModel<PlaceholderBean>> wealthRanking(@Field("ranking_type") String ranking_type, @Field("type") String type);
@GET(Constants.GUILD_RANKING)
Observable<BaseModel<PlaceholderBean>> guildRanking();
@GET(Constants.GET_WITHDRAWAL_LIST)
Observable<BaseModel<List<WithdrawalBean>>> withdrawalList(@Query("page") String page, @Query("page_limit") String page_limit,@Query("search_stime") String search_stime, @Query("search_etime") String search_etime);
@FormUrlEncoded
@POST(Constants.POST_ROOM_RANKING)
Observable<BaseModel<PlaceholderBean>> roomRanking( @Field("type") String type);
@FormUrlEncoded
@POST(Constants.POST_LOVE_RANKING)
Observable<BaseModel<PlaceholderBean>> loveRanking( @Field("type") String type);
@GET(Constants.GET_REAL_NAME)
Observable<BaseModel<RealNameBean>> realNameInfo();
@GET(Constants.GET_DAILY_TASK_BOX)
Observable<BaseModel<List<GiftBoxRecordBean>>> dailyTasksBoxRecord();
@GET(Constants.GET_MY_BAG_DATA)
Observable<BaseModel<List<MyBagDataBean>>> packIncome(@Query("page") String page, @Query("page_limit") String page_size);
@GET(Constants.GET_MY_BAG_OUTCOME)
Observable<BaseModel<List<MyBagDataBean>>> packOutcome(@Query("page") String page, @Query("page_limit") String page_size);
@GET(Constants.GET_GIFT_PACK)
Observable<BaseModel<List<GiftPackBean>>> giftPack();
@FormUrlEncoded
@POST(Constants.ADD_BLACK_LIST)
Call<ResponseBody> addBlackList(@Field("user_id") String user_id);
@@ -85,6 +158,9 @@ public interface ApiServer {
@POST(Constants.POST_END_PK)
Call<ResponseBody> endPk(@Field("pk_id") String is_pk,@Field("type") String type,@Field("user_id") String user_id);
@GET(Constants.GET_RECHARGE)
Observable<BaseModel<List<RechargeBean>>> recharge();
@FormUrlEncoded
@POST(Constants.POST_START_PK)
Call<ResponseBody> startPk(@Field("pk_id") String pk_id,@Field("pk_times") String pk_times);
@@ -117,7 +193,7 @@ public interface ApiServer {
Call<BaseModel<String>> getRealNameResult(@Field("orderNo") String order_no);
@FormUrlEncoded
@POST(Constants.URL_LOGIN)
Observable<BaseModel<List<UserBean>>> oauthLogin(@Field("login_token") String login_token);
Call<BaseModel<List<UserBean>>> oauthLogin(@Field("login_token") String login_token);
@FormUrlEncoded
@POST(Constants.URL_AUTH_CODE)
@@ -149,7 +225,7 @@ public interface ApiServer {
Call<BaseModel<String> > editAlbum(@Field("album_id") String album_id,@Field("name") String name, @Field("pwd")String pwd, @Field("image") String image);
@GET(Constants.GET_SJ_ROOM_NAME)
Observable<BaseModel<String>> sjRoomName();
Call<ResponseBody> sjRoomName();
@FormUrlEncoded
@POST(Constants.POST_FOLLOW_LIST)
@@ -164,6 +240,11 @@ public interface ApiServer {
@FormUrlEncoded
@POST(Constants.GET_MY_ROOM)
Call<BaseModel<List<MyRoomBean>>> getMyRoom(@Field("type")String type,@Field("page") String page, @Field("page_limit") String page_limit);
@FormUrlEncoded
@POST(Constants.POST_MY_ROOM_BEAN)
Call<BaseModel<List<BannerModel>>> getBanners(@Field("type")String type);
@FormUrlEncoded
@POST(Constants.GET_TOP_ROOM)
Call<BaseModel<List<TopRoom>>> getTopRooms( @Field("page") String page, @Field("page_limit") String page_limit,@Field("is_top")String is_top,@Field("label_id")String label_id);
@@ -274,6 +355,10 @@ public interface ApiServer {
@GET(Constants.GET_PERSONALTY)
Observable<BaseModel<List<PersonaltyBean>>> getPersonaltyList();
@FormUrlEncoded
@POST(Constants.GET_SUBSIDY)
Observable<BaseModel<RoomSubsidy>> getSubsidy(@Field("room_id") String roomId);
@GET(Constants.GET_DECORATE)
Observable<BaseModel<List<ZhuangBanShangChengBean>>> getDecorateList(@Query("type") String type);
@@ -337,6 +422,10 @@ public interface ApiServer {
@GET(Constants.GET_WALLET)
Observable<BaseModel<WalletBean>> wallet();
@FormUrlEncoded
@POST(Constants.POST_APPLY_Pay)
Observable<BaseModel<AppPay>> appPay(@Field("user_id") String user_id, @Field("money") String money, @Field("coin") String coin, @Field("type") String type);
@FormUrlEncoded
@POST(Constants.POST_APPLY_LIST)
Observable<BaseModel<RoomApplyListBean>> roomApplyListBean(@Field("room_id")String room_id);
@@ -345,6 +434,17 @@ public interface ApiServer {
@POST(Constants.GET_ROOM_USER)
Observable<BaseModel<UserInfo>> getRoomUserInfo(@Field("room_id") String roomId,@Field("user_id") String userId);
@FormUrlEncoded
@POST(Constants.POST_BIND_TYPE)
Observable<BaseModel<BindType>> bindType(@Field("user_id") String userId);
@GET(Constants.GET_WALLET_CONFIG)
Observable<BaseModel<WalletConfig>> getWalletConfig();
@FormUrlEncoded
@POST(Constants.POST_BIND)
Call<BaseModel<String>> bind(@Field("user_id") String userId, @Field("type") String type, @Field("alipay_account") String alipay_account, @Field("bank_card_number")String bank_card_number, @Field("bank_card") String bank_card, @Field("open_bank") String open_bank);
@FormUrlEncoded
@POST(Constants.POST_SONG_LIST)
Observable<BaseModel<List<MusicSongBean>>> songList(@Field("room_id") String room_id);
@@ -454,6 +554,10 @@ public interface ApiServer {
@GET(Constants.GET_ROOM_BJ)
Observable<BaseModel<RoomBgBean>> getBackgroundList();
@FormUrlEncoded
@POST(Constants.POST_CHARM_LIST)
Observable<BaseModel<RoomDetails>> getCharmList(@Field("room_id") String room_id,@Field("start_time") String start_time,@Field("end_time") String end_time);
@FormUrlEncoded
@POST(Constants.POST_SET_UPLOAD_BG_IMG)
Call<BaseModel<String>> setUploadBgImg(@Field("id") String id,@Field("image_url") String image_url);

View File

@@ -7,6 +7,7 @@ import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ServiceInfo;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.IBinder;
@@ -19,7 +20,12 @@ import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import androidx.annotation.Nullable;
import com.alibaba.android.arouter.launcher.ARouter;
import com.lzf.easyfloat.EasyFloat;
import com.lzf.easyfloat.enums.ShowPattern;
import com.lzf.easyfloat.enums.SidePattern;
import com.qxcm.moduleutil.R;
import com.qxcm.moduleutil.base.CommonAppContext;
import com.qxcm.moduleutil.event.RoomOutEvent;
@@ -30,153 +36,90 @@ import com.qxcm.moduleutil.widget.GifAvatarOvalView;
import org.greenrobot.eventbus.EventBus;
public class FloatingWindowService extends Service {
private WindowManager windowManager;
private View floatingView;
private static final int NOTIFICATION_ID = 1;
private View floatView;
@SuppressLint("WrongConstant")
@Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
// 加载悬浮窗布局
floatingView = LayoutInflater.from(this).inflate(R.layout.floating_window_layout, null);
// 设置 WindowManager.LayoutParams
int layoutType;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
layoutType = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
// Android 14API 34及以上需要指定具体的 foregroundServiceType
startForeground(NOTIFICATION_ID, buildNotification(), ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// Android 10 - 13 使用通用类型
startForeground(NOTIFICATION_ID, buildNotification(), ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST);
} else {
layoutType = WindowManager.LayoutParams.TYPE_PHONE;
startForeground(NOTIFICATION_ID, buildNotification());
}
// 初始化浮窗(建议使用 ApplicationContext
if (floatView == null) {
EasyFloat.with(getApplicationContext())
.setLayout(R.layout.floating_layout)
.setTag("testFloat")
.setShowPattern(ShowPattern.ALL_TIME)
.setDragEnable(true)
.setSidePattern(SidePattern.RESULT_HORIZONTAL)
.setGravity(Gravity.END)
.show();
}
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
layoutType,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
layoutParams.gravity = Gravity.TOP | Gravity.START;
layoutParams.x = 100;
layoutParams.y = 100;
// 添加悬浮窗到窗口
windowManager.addView(floatingView, layoutParams);
// 关闭按钮点击事件
// ImageView closeButton = floatingView.findViewById(R.id.iv_guanbi);
// closeButton.setOnClickListener(v -> stopSelf());
setupFloatingViewBehavior();
// 创建通知防止服务被杀死
// Notification notification = new Notification.Builder(this, "channel_id")
// .setContentTitle("浮窗运行中")
// .setSmallIcon(R.mipmap.ic_launcher)
// .build();
// startForeground(NOTIFICATION_ID, notification);
}
private Notification buildNotification() {
String channelId = "floating_window_service";
String channelName = "悬浮窗服务";
private static final int NOTIFICATION_ID = 1;
@SuppressLint("ForegroundService")
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 创建前台通知(必须)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String channelId = "floating_window_service";
NotificationChannel channel = new NotificationChannel(
channelId,
"悬浮窗服务",
channelName,
NotificationManager.IMPORTANCE_LOW
);
channel.setShowBadge(false); // 不显示角标
channel.setSound(null, null); // 禁止声音
channel.enableVibration(false); // 禁止震动
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.createNotificationChannel(channel);
Notification notification = new Notification.Builder(this, channelId)
.setContentTitle("悬浮窗正在运行")
.setSmallIcon(R.mipmap.default_avatar) // 替换为你自己的图标资源
.build();
startForeground(NOTIFICATION_ID, notification);
} else {
Notification notification = new Notification.Builder(this)
.setContentTitle("悬浮窗正在运行")
.setSmallIcon(R.mipmap.default_avatar)
.build();
startForeground(NOTIFICATION_ID, notification);
NotificationManager manager = getSystemService(NotificationManager.class);
if (manager != null) {
manager.createNotificationChannel(channel);
}
}
Notification.Builder builder = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder = new Notification.Builder(this, channelId)
.setContentTitle("悬浮窗运行中")
.setContentText("点击打开应用")
.setSmallIcon(R.mipmap.default_avatar) // ✅ 必须有效存在
.setAutoCancel(true)
.setOngoing(true);
}
return builder.build();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
private void setupFloatingViewBehavior() {
ImageView ivGuanbi = floatingView.findViewById(R.id.iv_guanbi);
GifAvatarOvalView riv = floatingView.findViewById(R.id.riv);
// 点击关闭按钮
ivGuanbi.setOnClickListener(v -> topAndReleaseResources());
// 动画任务
final Runnable mRivAnimationTask = () -> {
Animation rivRotateAnimation = AnimationUtils.loadAnimation(this, R.anim.rotate_anim);
riv.startAnimation(rivRotateAnimation);
};
// 模拟播放状态(可替换为真实数据)
boolean isPlaying = CommonAppContext.getInstance().isPlaying;
if (isPlaying) {
ImageLoader.loadHead(this, riv, CommonAppContext.getInstance().playCover);
riv.postDelayed(mRivAnimationTask, 1000);
floatingView.setVisibility(View.VISIBLE);
} else {
floatingView.setVisibility(View.GONE);
}
// 点击头像跳转房间详情
riv.setOnClickListener(v -> {
String roomId = CommonAppContext.getInstance().playId;
if (!TextUtils.isEmpty(roomId)) {
ARouter.getInstance().build(ARouteConstants.ROOM_DETAILS).withString("form", "首页").withString("roomId", CommonAppContext.getInstance().playId).navigation();
// Intent intent = new Intent(Intent.ACTION_VIEW);
// intent.setPackage(getPackageName());
// intent.setData(Uri.parse("customscheme://roomdetails?form=首页&roomId=" + roomId));
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// startActivity(intent);
}
});
}
private void topAndReleaseResources() {
// 停止动画
// if (riv != null) {
//// riv.clearAnimation();
// }
// 移除回调任务(如果有的话)
if (floatingView != null) {
// riv.removeCallbacks(mRivAnimationTask);
}
// 调用关闭逻辑(可调用 Presenter 或直接调用 SDK
// MvpPre.quitRoom(CommonAppContext.getInstance().playId);
// 设置全局状态为 false
CommonAppContext.getInstance().isPlaying = false;
CommonAppContext.getInstance().isShow = false;
EventBus.getDefault().post(new RoomOutEvent());
// 停止服务自身
stopSelf();
}
@Override
public void onDestroy() {
if (floatingView != null) {
windowManager.removeView(floatingView);
}
super.onDestroy();
// 停止浮窗
EasyFloat.dismiss("testFloat");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}

View File

@@ -5,5 +5,5 @@ public interface SoundLevelUpdateListener {
* 远端拉流音频声浪回调
*/
void onRemoteSoundLevelUpdate(String userId, int soundLevel);
// void onLocalSoundLevelUpdate(int volume);
void onLocalSoundLevelUpdate(int volume);
}

View File

@@ -14,6 +14,7 @@ import com.tencent.imsdk.v2.V2TIMMessage;
import com.tencent.imsdk.v2.V2TIMSendCallback;
import com.tencent.imsdk.v2.V2TIMSimpleMsgListener;
import com.tencent.imsdk.v2.V2TIMUserInfo;
import com.tencent.imsdk.v2.V2TIMValueCallback;
import org.greenrobot.eventbus.EventBus;
@@ -53,6 +54,9 @@ public class MessageListenerSingleton {
public void onRecvC2CCustomMessage(String msgID, V2TIMUserInfo sender, byte[] customData) {
// notifyMessageReceived("C2C 自定义(信令)消息:" + sender.getNickName());
LogUtils.d("C2C 自定义(信令)消息 " + sender.getNickName());
String message = new String(customData, StandardCharsets.UTF_8);
RoomMessageEvent event = GsonUtils.fromJson(message, RoomMessageEvent.class);
notifyMessageReceived(event);
}
@Override
@@ -263,6 +267,34 @@ public class MessageListenerSingleton {
);
}
public void sendCustomC2CMessage(String userId, byte[] binaryData) {
// 创建自定义群消息
V2TIMMessage v2TIMMessage = V2TIMManager.getMessageManager().createCustomMessage(binaryData);
v2TIMMessage.setExcludedFromUnreadCount( true);
v2TIMMessage.setExcludedFromContentModeration(true);
//
// // 发送消息
V2TIMManager.getMessageManager().sendMessage(v2TIMMessage,"u"+userId,null, V2TIMMessage.V2TIM_PRIORITY_HIGH,
true,
null,
sendCallback);
// API 返回 msgID按需使用
// V2TIMManager.getInstance().sendC2CTextMessage( binaryData,"u"+userId, new V2TIMValueCallback<V2TIMMessage>() {
// @Override
// public void onSuccess(V2TIMMessage message) {
// // 发送单聊文本消息成功
// LogUtils.e("发送成功");
// }
//
// @Override
// public void onError(int code, String desc) {
// // 发送单聊文本消息失败
// LogUtils.e("发送失败");
// }
// });
}
public static void reset(String roomId) {
if (instance != null) {
instance.listeners.clear();

View File

@@ -0,0 +1,20 @@
package com.qxcm.moduleutil.presenter;
import android.app.Activity;
import com.qxcm.moduleutil.activity.IPresenter;
import com.qxcm.moduleutil.activity.IView;
import com.qxcm.moduleutil.bean.RechargeBean;
import java.util.List;
public class RechargeDialogContacts {
public interface View extends IView<Activity> {
void setRechargeData(List<RechargeBean> rechargeData);
}
public interface IRechargePre extends IPresenter {
void recharge();//可选充值金额列表
}
}

View File

@@ -0,0 +1,31 @@
package com.qxcm.moduleutil.presenter;
import android.content.Context;
import com.qxcm.moduleutil.bean.RechargeBean;
import com.qxcm.moduleutil.http.BaseObserver;
import java.util.List;
import io.reactivex.disposables.Disposable;
public class RechargeDialogPresenter extends BasePresenter<RechargeDialogContacts.View> implements RechargeDialogContacts.IRechargePre{
public RechargeDialogPresenter(RechargeDialogContacts.View view, Context context) {
super(view, context);
}
@Override
public void recharge() {
api.recharge(new BaseObserver<List<RechargeBean>>() {
@Override
public void onSubscribe(Disposable d) {
addDisposable(d);
}
@Override
public void onNext(List<RechargeBean> rechargeBeans) {
MvpRef.get().setRechargeData(rechargeBeans);
}
});
}
}

View File

@@ -1,12 +1,20 @@
package com.qxcm.moduleutil.rtc;
import static io.agora.rtc2.video.VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_15;
import static io.agora.rtc2.video.VideoEncoderConfiguration.ORIENTATION_MODE.ORIENTATION_MODE_ADAPTIVE;
import static io.agora.rtc2.video.VideoEncoderConfiguration.STANDARD_BITRATE;
import static io.agora.rtc2.video.VideoEncoderConfiguration.VD_640x360;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceView;
import android.view.WindowManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -24,8 +32,11 @@ import com.liulishuo.okdownload.core.cause.EndCause;
import com.liulishuo.okdownload.core.cause.ResumeFailedCause;
import com.liulishuo.okdownload.core.listener.DownloadListener1;
import com.liulishuo.okdownload.core.listener.assist.Listener1Assist;
import com.orhanobut.logger.Logger;
import com.qxcm.moduleutil.base.CommonAppContext;
import com.qxcm.moduleutil.bean.RoomMessageEvent;
import com.qxcm.moduleutil.event.CabinEvent;
import com.qxcm.moduleutil.event.ColoseCardEvent;
import com.qxcm.moduleutil.interfaces.SoundLevelUpdateListener;
import com.qxcm.moduleutil.listener.MessageListenerSingleton;
import com.qxcm.moduleutil.utils.Md5Utils;
@@ -48,6 +59,7 @@ import io.agora.mediaplayer.IMediaPlayer;
import io.agora.mediaplayer.IMediaPlayerCustomDataProvider;
import io.agora.mediaplayer.IMediaPlayerObserver;
import io.agora.mediaplayer.data.CacheStatistics;
import io.agora.mediaplayer.data.PlayerPlaybackStats;
import io.agora.mediaplayer.data.PlayerUpdatedInfo;
import io.agora.mediaplayer.data.SrcInfo;
import io.agora.musiccontentcenter.IAgoraMusicContentCenter;
@@ -63,12 +75,15 @@ import io.agora.rtc2.RtcConnection;
import io.agora.rtc2.RtcEngine;
import io.agora.rtc2.RtcEngineConfig;
import io.agora.rtc2.RtcEngineEx;
import io.agora.rtc2.ScreenCaptureParameters;
import io.agora.rtc2.video.VideoCanvas;
import io.agora.rtc2.video.VideoEncoderConfiguration;
public class AgoraManager {
private static volatile AgoraManager instance;
private RtcEngineEx rtcEngine;
// private RtcEngineEx rtcEngineEx;
// private RtcEngineEx rtcEngineEx;
private Context context;
private boolean isLocalAudioEnabled = true; // 默认开启麦克风
private final List<IRtcEngineEventHandler> eventHandlers = new ArrayList<>();
@@ -81,6 +96,7 @@ public class AgoraManager {
private List<Music> musicList;
private boolean isBjMusic = false;
private List<SoundLevelUpdateListener> soundLevelUpdateListeners = new CopyOnWriteArrayList<>();
ChannelMediaOptions options;
private AgoraManager(Context context) {
this.context = context.getApplicationContext();
@@ -126,7 +142,11 @@ public class AgoraManager {
config.mEventHandler = getDefaultEventHandler();
config.mChannelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING;
config.mAudioScenario = Constants.AUDIO_SCENARIO_CHORUS;
rtcEngine =(RtcEngineEx) RtcEngine.create(config);
config.mAudioScenario = Constants.AudioScenario.getValue(Constants.AudioScenario.DEFAULT);
config.mAreaCode = 1;
rtcEngine = (RtcEngineEx) RtcEngine.create(config);
} catch (Exception e) {
Log.e("AgoraManager", "Failed to create RtcEngine", e);
}
@@ -143,6 +163,29 @@ public class AgoraManager {
rtcEngine.setParameters("{\"che.audio.custom_bitrate\":128000}");
rtcEngine.setParameters("{\"rtc.enable_nasa2\": true}");
rtcEngine.setParameters("{\"rtc.use_audio4\": true}");
rtcEngine.setParameters("{"
+ "\"rtc.report_app_scenario\":"
+ "{"
+ "\"appScenario\":" + 100 + ","
+ "\"serviceType\":" + 11 + ","
+ "\"appVersion\":\"" + RtcEngine.getSdkVersion() + "\""
+ "}"
+ "}");
rtcEngine.setParameters("{\"che.video.mobile_1080p\":true}");
/*Enable video module*/
rtcEngine.enableVideo();
// Setup video encoding configs
rtcEngine.setVideoEncoderConfiguration(new VideoEncoderConfiguration(
VD_640x360,
FRAME_RATE_FPS_15,
STANDARD_BITRATE,
ORIENTATION_MODE_ADAPTIVE
));
/*Set up to play remote sound with receiver*/
rtcEngine.setDefaultAudioRoutetoSpeakerphone(true);
}
return this;
@@ -161,12 +204,22 @@ public class AgoraManager {
}
mRoomId = roomId;
ChannelMediaOptions options = new ChannelMediaOptions();
options = new ChannelMediaOptions();
options.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER;
options.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING;
options.publishMicrophoneTrack = isMicrophoneEnabled; // 是否发布麦克风音频
options.enableAudioRecordingOrPlayout = true;
options.autoSubscribeAudio = true;
options.autoSubscribeVideo = true;
// 不发布摄像头采集的视频
options.publishCameraTrack = false;
// 在频道中发布屏幕采集的视频
options.publishScreenCaptureVideo = true;
// 在频道中发布屏幕采集的音频
options.publishScreenCaptureAudio = true;
// options.publishMediaPlayerId = 0;
rtcEngine.joinChannel(token, mRoomId, uid, options);
@@ -188,9 +241,8 @@ public class AgoraManager {
}
}
public void joinChannelEx(String token, String channelId,int uid) {
public void joinChannelEx(String token, String channelId, int uid) {
if (rtcEngine != null) {
ChannelMediaOptions options = new ChannelMediaOptions();
options.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER;
options.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING;
options.publishMicrophoneTrack = true; // 是否发布麦克风音频
@@ -199,12 +251,12 @@ public class AgoraManager {
RtcConnection connection = new RtcConnection();
connection.channelId = channelId;
connection.localUid = uid;
rtcEngine.joinChannelEx(token, connection, options,getDefaultEventHandler());
rtcEngine.joinChannelEx(token, connection, options, getDefaultEventHandler());
}
}
public void leaveChannelEx(String mRoomId, int uid){
if (rtcEngine != null){
public void leaveChannelEx(String mRoomId, int uid) {
if (rtcEngine != null) {
RtcConnection connection = new RtcConnection();
connection.channelId = mRoomId;
connection.localUid = uid;
@@ -212,8 +264,56 @@ public class AgoraManager {
}
}
public void isMute(int index){
if (rtcEngine!=null){
public void updateChannelMediaOptions() {
if (rtcEngine != null) {
options.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER;
// options.autoSubscribeVideo = true;
// options.autoSubscribeAudio = true;
//// 不发布摄像头采集的视频
// options.publishCameraTrack = false;
//// 不发布麦克风采集的视频
// options.publishMicrophoneTrack = false;
//// 在频道中发布屏幕采集的视频
// options.publishScreenCaptureVideo = true;
//// 在频道中发布屏幕采集的音频
// options.publishScreenCaptureAudio = true;
rtcEngine.setScreenCaptureScenario(Constants.ScreenScenarioType.SCREEN_SCENARIO_VIDEO);
rtcEngine.updateChannelMediaOptions(options);
}
}
public void post() {
if (rtcEngine != null) {
// rtcEngine.setParameters("{\"che.video.mobile_1080p\":true}");
// rtcEngine.setClientRole(Constants.CLIENT_ROLE_BROADCASTER);
//
// /*Enable video module*/
// rtcEngine.enableVideo();
// // Setup video encoding configs
// rtcEngine.setVideoEncoderConfiguration(new VideoEncoderConfiguration(
// VD_640x360,
// FRAME_RATE_FPS_15,
// STANDARD_BITRATE,
// ORIENTATION_MODE_ADAPTIVE
// ));
// /*Set up to play remote sound with receiver*/
// rtcEngine.setDefaultAudioRoutetoSpeakerphone(true);
ScreenCaptureParameters screenCaptureParameters = new ScreenCaptureParameters();
screenCaptureParameters.captureVideo = true;
screenCaptureParameters.videoCaptureParameters.width = 720;
screenCaptureParameters.videoCaptureParameters.height = 920;
screenCaptureParameters.videoCaptureParameters.framerate = 15;
screenCaptureParameters.captureAudio = true;
screenCaptureParameters.audioCaptureParameters.captureSignalVolume = 50;
rtcEngine.startScreenCapture(screenCaptureParameters);
}
}
public void isMute(int index) {
if (rtcEngine != null) {
}
}
@@ -234,6 +334,8 @@ public class AgoraManager {
if (rtcEngine != null) {
// rtcEngine.registerEventHandler(getDefaultEventHandler());
rtcEngine.leaveChannel();
rtcEngine.stopScreenCapture();
rtcEngine.stopPreview();
if (musicPlayer != null) {
musicPlayer.destroy();
}
@@ -256,19 +358,44 @@ public class AgoraManager {
* 设置是否开启本地麦克风
*/
@SuppressLint("SuspiciousIndentation")
public void setLocalAudioEnabled(boolean enabled) {
public void setLocalAudioEnabled(boolean enabled,String userId) {
if (rtcEngine != null) {
rtcEngine.enableLocalAudio(enabled); // 启用/禁用音频采集
this.isLocalAudioEnabled = enabled;
if (!enabled) {
for (SoundLevelUpdateListener listener : soundLevelUpdateListeners) {
if (listener != null) {
ThreadUtils.runOnUiThread(() -> {
// 远程用户音量变化
listener.onRemoteSoundLevelUpdate(userId, 0);
});
}
}
}
}
}
public void ClientRole(boolean enabled){
public void ClientRole(boolean enabled) {
if (rtcEngine != null) {
rtcEngine.setClientRole(enabled ? Constants.CLIENT_ROLE_BROADCASTER : Constants.CLIENT_ROLE_AUDIENCE);
}
}
/**
* 启用或者关闭远端音频流
*
* @param enabled
* @param uid
*/
public void muteLocalAudioStreamEx(boolean enabled, int uid) {
RtcConnection connection = new RtcConnection();
connection.channelId = mRoomId;
connection.localUid = uid;
rtcEngine.muteLocalAudioStreamEx(enabled, connection);
}
/**
* 启用/关闭本地音频流
*
@@ -323,11 +450,6 @@ public class AgoraManager {
return new IRtcEngineEventHandler() {
@Override
public void onJoinChannelSuccess(String channel, int uid, int elapsed) {
// for (IRtcEngineEventHandler handler : eventHandlers) {
// if (handler != null) {
// handler.onJoinChannelSuccess(channel, uid, elapsed);
musicContentCenter = IAgoraMusicContentCenter.create(rtcEngine);
contentCenterConfiguration = new MusicContentCenterConfiguration();
// 已开启音乐内容中心项目的 App ID
@@ -379,15 +501,17 @@ public class AgoraManager {
musicPlayer = musicContentCenter.createMusicPlayer();
musicPlayer.registerPlayerObserver(new IMediaPlayerObserver() {
@Override
public void onPlayerStateChanged(io.agora.mediaplayer.Constants.MediaPlayerState state, io.agora.mediaplayer.Constants.MediaPlayerError error) {
public void onPlayerStateChanged(io.agora.mediaplayer.Constants.MediaPlayerState state, io.agora.mediaplayer.Constants.MediaPlayerReason reason) {
if (state == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_OPEN_COMPLETED) {
musicContentCenter.getLyric(mSongCode, 1);
musicContentCenter.getSongSimpleInfo(mSongCode);
} else if (state == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_PLAYBACK_ALL_LOOPS_COMPLETED) {
nextSong();
}
LogUtils.e("@@@", "state: " + state + ", error: " + error);
LogUtils.e("@@@", "state: " + state);
}
@Override
@@ -447,12 +571,26 @@ public class AgoraManager {
LogUtils.e("@@@", "info: " + info);
}
@Override
public void onPlayerCacheStats(CacheStatistics stats) {
}
@Override
public void onPlayerPlaybackStats(PlayerPlaybackStats stats) {
}
// @Override
// public void onPlayerPlaybackStats(PlayerPlaybackStats stats) {
//
// }
@Override
public void onAudioVolumeIndication(int volume) {
LogUtils.e("@@@", "volume: " + volume);
}
});
ChannelMediaOptions options = new ChannelMediaOptions();
options.autoSubscribeVideo = true;
options.autoSubscribeAudio = true;
options.publishScreenCaptureVideo = false;
@@ -465,10 +603,11 @@ public class AgoraManager {
options.publishMediaPlayerAudioTrack = true;
rtcEngine.updateChannelMediaOptions(options);
// creatKtv(uid);
CabinEvent cabinEvent = new CabinEvent();
cabinEvent.setJoined(true);
EventBus.getDefault().post(cabinEvent);
}
// }
// }
@Override
public void onUserJoined(int uid, int elapsed) {
@@ -477,6 +616,10 @@ public class AgoraManager {
handler.onUserJoined(uid, elapsed);
}
}
SurfaceView renderView = new SurfaceView(context);
rtcEngine.setupRemoteVideo(new VideoCanvas(renderView, Constants.RENDER_MODE_FIT, uid));
EventBus.getDefault().post(renderView);
}
@Override
@@ -486,6 +629,9 @@ public class AgoraManager {
handler.onUserOffline(uid, reason);
}
}
SurfaceView renderView = null;
rtcEngine.setupRemoteVideo(new VideoCanvas(null, Constants.RENDER_MODE_FIT, uid));
EventBus.getDefault().post(renderView);
}
@Override
@@ -506,8 +652,9 @@ public class AgoraManager {
// // 本地用户音量变化
// listener.onLocalSoundLevelUpdate(volume);
// } else {
// 远程用户音量变化
listener.onRemoteSoundLevelUpdate(uid > 0 ? String.valueOf(uid) : SpUtil.getUserId() + "", volume);
// 远程用户音量变化
listener.onRemoteSoundLevelUpdate(uid > 0 ? String.valueOf(uid) : SpUtil.getUserId() + "", volume);
// listener.onRemoteSoundLevelUpdate( String.valueOf(uid), volume);
// }
});
}
@@ -515,8 +662,41 @@ public class AgoraManager {
}
}
@Override
public void onLocalVideoStateChanged(Constants.VideoSourceType source, int state, int reason) {
super.onLocalVideoStateChanged(source, state, reason);
if (state == Constants.LOCAL_VIDEO_STREAM_STATE_CAPTURING && source.getValue() == Constants.VIDEO_SOURCE_SCREEN_PRIMARY) {
options.publishScreenCaptureAudio = true;
options.publishScreenCaptureVideo = true;
options.publishCameraTrack = false;
rtcEngine.updateChannelMediaOptions(options);
}
}
@Override
public void onFirstRemoteAudioFrame(int uid, int elapsed) {
super.onFirstRemoteAudioFrame(uid, elapsed);
Log.i("RoomCabinFragment", "onFirstRemoteAudioFrame: uid->" + uid);
SurfaceView renderView = new SurfaceView(context);
rtcEngine.setupRemoteVideo(new VideoCanvas(renderView, Constants.RENDER_MODE_FIT, uid));
EventBus.getDefault().post(renderView);
}
// 可继续扩展其他回调...
@Override
public void onRemoteVideoStateChanged(int uid, int state, int reason, int elapsed) {
super.onRemoteVideoStateChanged(uid, state, reason, elapsed);
Log.i("RoomCabinFragment", "onRemoteVideoStateChanged:uid->" + uid + ", state->" + state);
if (state == Constants.LOCAL_VIDEO_STREAM_STATE_STOPPED) {
ColoseCardEvent renderView = new ColoseCardEvent();
EventBus.getDefault().post(renderView);
} else {
SurfaceView renderView = new SurfaceView(context);
rtcEngine.setupRemoteVideo(new VideoCanvas(renderView, Constants.RENDER_MODE_FIT, uid));
EventBus.getDefault().post(renderView);
}
}
};
}
@@ -568,22 +748,33 @@ public class AgoraManager {
}, 3000); // 3秒延迟
} else {
if (musicPlayer.getState() == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_PAUSED) {//暂停
LogUtils.e("lxj", "暂停");
musicPlayer.resume();
} else if (musicPlayer.getState() == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_IDLE) {//空闲
LogUtils.e("lxj", "空闲");
musicPlayer.open(mSongCode, 0);
isPreload(mSongCode, type);
} else if (musicPlayer.getState() == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_OPEN_COMPLETED) {//打开成功
LogUtils.e("lxj", "播放");
musicPlayer.play();
musicPlayer.selectAudioTrack(0);
} else if (musicPlayer.getState() == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_IDLE) {
LogUtils.e("lxj", "空闲");
musicPlayer.open(mSongCode, 0);
isPreload(mSongCode, type);
LogUtils.e("@@@", musicPlayer.getState());
// LogUtils.e("@@@", musicPlayer.getState());
// musicPlayer.pause() ;
} else if (musicPlayer.getState() == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_STOPPED) {
LogUtils.e("@@@", "关闭");
} else if (musicPlayer.getState() == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_PAUSING_INTERNAL) {
LogUtils.e("lxj", "关闭");
musicPlayer.pause();
} else if (musicPlayer.getState() == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_PLAYBACK_ALL_LOOPS_COMPLETED) {
LogUtils.e("lxj", "daki");
musicPlayer.open(mSongCode, 0);
isPreload(mSongCode, type);
} else if (musicPlayer.getState() == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_OPENING) {
LogUtils.e("lxj", musicPlayer.getState());
isPreload(mSongCode, type);
}
}
@@ -628,24 +819,33 @@ public class AgoraManager {
}, 3000); // 3秒延迟
} else {
if (musicPlayer.getState() == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_PAUSED) {//暂停
LogUtils.e("lxj", "暂停");
musicPlayer.resume();
} else if (musicPlayer.getState() == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_IDLE) {//空闲
LogUtils.e("lxj", "空闲");
musicPlayer.open(mSongCode, 0);
isPreload2(mSongCode, type);
} else if (musicPlayer.getState() == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_OPEN_COMPLETED) {//打开成功
LogUtils.e("lxj", "播放");
musicPlayer.play();
musicPlayer.selectAudioTrack(0);
} else if (musicPlayer.getState() == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_IDLE) {
LogUtils.e("lxj", "空闲");
musicPlayer.open(mSongCode, 0);
isPreload2(mSongCode, type);
// LogUtils.e("@@@", musicPlayer.getState());
// musicPlayer.pause() ;
} else if (musicPlayer.getState() == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_PAUSING_INTERNAL) {
LogUtils.e("@@@", "关闭");
LogUtils.e("lxj", "关闭");
musicPlayer.pause();
} else if (musicPlayer.getState() == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_PLAYBACK_ALL_LOOPS_COMPLETED) {
LogUtils.e("lxj", "daki");
musicPlayer.open(mSongCode, 0);
isPreload2(mSongCode, type);
} else if (musicPlayer.getState() == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_OPENING) {
LogUtils.e("lxj", musicPlayer.getState());
isPreload2(mSongCode, type);
}
}
} else if (type == 2) {
@@ -670,6 +870,12 @@ public class AgoraManager {
musicPlayer.play();
}
public void stopScreenCapture() {
if (rtcEngine != null) {
rtcEngine.stopScreenCapture();
}
}
public void stopMuisc() {
if (musicPlayer != null) {
// if (musicPlayer.getState() == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_PLAYING) {
@@ -788,9 +994,11 @@ public class AgoraManager {
public void nextSong() {
if (musicList.size() > 0) {
stopMuisc();
EventBus.getDefault().post(musicList.get(0));
isPreload2(musicList.get(0).songCode, 1);
musicList.remove(musicList.get(0));
new Handler(Looper.getMainLooper()).postDelayed(() -> {
EventBus.getDefault().post(musicList.get(0));
isPreload2(musicList.get(0).songCode, 1);
musicList.remove(musicList.get(0));
}, 3000); // 3秒延迟
} else {
stopMuisc();
@@ -833,4 +1041,6 @@ public class AgoraManager {
});
}
}

View File

@@ -12,6 +12,8 @@ import java.util.concurrent.CopyOnWriteArrayList;
import io.agora.karaoke_view.v11.downloader.LyricsFileDownloader;
import io.agora.mediaplayer.IMediaPlayerObserver;
import io.agora.mediaplayer.data.CacheStatistics;
import io.agora.mediaplayer.data.PlayerPlaybackStats;
import io.agora.mediaplayer.data.PlayerUpdatedInfo;
import io.agora.mediaplayer.data.SrcInfo;
import io.agora.musiccontentcenter.IAgoraMusicContentCenter;
@@ -246,8 +248,15 @@ private IMusicContentCenterEventHandler getMusicEventHandler() {
private IMediaPlayerObserver getMediaPlayerObserver() {
return new IMediaPlayerObserver() {
// @Override
// public void onPlayerStateChanged(io.agora.mediaplayer.Constants.MediaPlayerState state, io.agora.mediaplayer.Constants.MediaPlayerError error) {
// if (state == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_OPEN_COMPLETED) {
// musicContentCenter.getLyric(mSongCode, 1);
// }
// }
@Override
public void onPlayerStateChanged(io.agora.mediaplayer.Constants.MediaPlayerState state, io.agora.mediaplayer.Constants.MediaPlayerError error) {
public void onPlayerStateChanged(io.agora.mediaplayer.Constants.MediaPlayerState state, io.agora.mediaplayer.Constants.MediaPlayerReason reason) {
if (state == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_OPEN_COMPLETED) {
musicContentCenter.getLyric(mSongCode, 1);
}
@@ -293,6 +302,21 @@ private IMediaPlayerObserver getMediaPlayerObserver() {
}
@Override
public void onPlayerCacheStats(CacheStatistics stats) {
}
@Override
public void onPlayerPlaybackStats(PlayerPlaybackStats stats) {
}
// @Override
// public void onPlayerPlaybackStats(PlayerPlaybackStats stats) {
//
// }
@Override
public void onAudioVolumeIndication(int volume) {

View File

@@ -0,0 +1,378 @@
package com.qxcm.moduleutil.service;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
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;
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;
@Override
public void onCreate() {
super.onCreate();
Logger.e(TAG, "服务创建成功");
NetworkUtils.registerNetworkStatusChangedListener(this);
scheduledExecutorService.scheduleWithFixedDelay(connectTask, 0, 10, TimeUnit.SECONDS);
}
private final Runnable connectTask = this::doClientConnection;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
public static void subscribeRoom(String roomId) {
subscribe("qx_room_topic");
}
public static void cleanSubscribeRoom(String roomId) {
cleanSubscribe("qx_room_topic");
}
public static void subscribeUser(String userId) {
sUserId = userId;
subscribe("user_" + userId);
}
public static void cleanSubscribeUser() {
cleanSubscribe("user_" + sUserId);
sUserId = null;
}
/**
* 订阅主题
*/
public static void subscribe(String topic) {
try {
if (isAlreadyConnected()) {
IMqttToken subToken = mqttAndroidClient.subscribe(topic, qos);
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, "主题订阅失败");
ThreadUtils.runOnUiThreadDelayed(() -> subscribe(topic), 1000);
}
});
}
} 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() {
UserBean user = CommonAppContext.getInstance().getUser();
if (mqttAndroidClient == null) {
clientId = "android-" + user.getUser_id() + "-" + MqttClient.generateClientId();
mqttAndroidClient = new MqttAndroidClient(this, HOST, clientId);
}
mMqttConnectOptions = new MqttConnectOptions();
mMqttConnectOptions.setCleanSession(true);
mMqttConnectOptions.setConnectionTimeout(10);
mMqttConnectOptions.setKeepAliveInterval(60);
mMqttConnectOptions.setUserName("public");
mMqttConnectOptions.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
try {
mqttAndroidClient.connect(mMqttConnectOptions, null, iMqttActionListener);
mqttAndroidClient.setCallback(mqttCallback);
} catch (MqttException e) {
e.printStackTrace();
}
}
private synchronized void doClientConnection() {
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, "链接断开,请检查网络");
doClientConnection();
}
@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 <T> void sendEvent(String message, Class<T> tClass) {
EventBus.getDefault().post(JSON.parseObject(message, tClass));
}
private <T> void sendEventList(String message, Class<T> tClass) {
List<T> list = JSON.parseArray(message, tClass);
EventBus.getDefault().post(list);
}
private <T> void sendKtEvent(String message, Class<T> tClass) {
EventBus.getDefault().post(GsonUtils.GsonToBean(message, tClass));
}
@Override
public void onConnected(NetworkUtils.NetworkType networkType) {
doClientConnection();
}
@Override
public void onDisconnected() {
// 可选:做网络断开后的清理工作
}
public enum EmqttState {
CONNECTED,
DISCONNECTED
}
}

View File

@@ -0,0 +1,26 @@
package com.qxcm.moduleutil.service;
public enum EmqttState {
DISCONNECT(0), //断开连接
CONNECTED(1),//已连接
TOPICS_SUCCESS(2),//订阅成功
TOPICS_FAIL(3),//订阅失败
CANCEL_TOPICS_SUCCESS(4),//取消订阅成功
CANCEL_TOPICS_FAIL(5),//取消订阅失败
CLOSE_SUCCESS(6),//关闭成功
CLOSE_FAIL(7),
;//关闭失败
private int value;
EmqttState(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}

View File

@@ -0,0 +1,23 @@
package com.qxcm.moduleutil.service;
import android.content.Context;
import android.os.Handler;
import java.lang.ref.WeakReference;
public class HandlerUtil extends Handler {
private static HandlerUtil instance = null;
WeakReference<Context> mActivityReference;
public static HandlerUtil getInstance(Context context) {
if (instance == null) {
instance = new HandlerUtil(context.getApplicationContext());
}
return instance;
}
HandlerUtil(Context context) {
mActivityReference = new WeakReference<>(context);
}
}

View File

@@ -0,0 +1,9 @@
package com.qxcm.moduleutil.service;
public interface MyEmqttConnectListener {
void onConnectSuccess();
void onConnectFailure();
}

View File

@@ -0,0 +1,7 @@
package com.qxcm.moduleutil.service;
public interface MyEmqttMesgListener {
void messageArrived(String topic, String mesg);
}

View File

@@ -0,0 +1,8 @@
package com.qxcm.moduleutil.service;
public interface MyEmqttSubscribeListener {
void onSubscribeSuccess(String topic);
void onSubscribeFailure();
}

View File

@@ -0,0 +1,384 @@
package com.qxcm.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.content.pm.ServiceInfo;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;
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 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 org.jetbrains.annotations.Nullable;
public class MyMqttService extends Service {
private final static String TAG = MyMqttService.class.getCanonicalName();
private static int qos = 2;
private static String HOST = "tcp://81.70.45.221";
// private static String USERNAME = BuildConfig.EMQTT_USER;//用户名
// private static String PASSWORD = BuildConfig.EMQTT_PASSWORD;//密码
private static MqttAndroidClient mqttAndroidClient;
private MqttConnectOptions mMqttConnectOptions;
private static boolean b = true;
private static MyEmqttConnectListener mMyEmqttConnectListener;
private static MyEmqttMesgListener mMyEmqttMesgListener;
private static MyEmqttSubscribeListener mMyEmqttSubscribeListener;
private static final String TOPIC_BOSS = "qx_room_topic";
private static final int NOTIFICATION_ID = 1;
@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);
return super.onStartCommand(intent, flags, startId);
}
private void setForegroundServiceBehavior(int foregroundServiceTypeManifest) {
}
@Override
public void onCreate() {
super.onCreate();
init();
}
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();
}
/**
* 开启服务
*/
public static void startService(Context mContext) {
b = true;
boolean serviceRunning = ServiceUtils.isServiceRunning(MyMqttService.class.getCanonicalName());
if (!serviceRunning) {
mContext.startService(new Intent(mContext, MyMqttService.class));
}
}
public static void stopService(Context context) {
b = false;
boolean serviceRunning = ServiceUtils.isServiceRunning(MyMqttService.class.getCanonicalName());
if (serviceRunning) {
context.stopService(new Intent(context, MyMqttService.class));
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* 发布 (模拟其他客户端发布消息)
*
* @param message 消息
*/
public static void publish(String topic, String message) {
if (mqttAndroidClient == null) {
Logger.e(TAG, "mqttAndroidClient is null", "发送失败");
return;
}
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, "发送消息", "发送失败");
}
});
} catch (MqttException e) {
e.printStackTrace();
}
}
public static void subscribe(String topic) {
try {
if (mqttAndroidClient.isConnected()) {
IMqttToken subToken = mqttAndroidClient.subscribe(topic, qos);
subToken.setActionCallback(new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
if (mMyEmqttSubscribeListener != null) {
mMyEmqttSubscribeListener.onSubscribeSuccess(topic);
}
Logger.e(TAG, "订阅成功:" + topic);
}
@Override
public void onFailure(IMqttToken asyncActionToken,
Throwable exception) {
if (!TOPIC_BOSS.equals(topic) && mMyEmqttSubscribeListener != null) {
mMyEmqttSubscribeListener.onSubscribeFailure();
}
Logger.e(TAG, "订阅失败:" + topic);
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void cleanSubscribe(String topic) {
try {
if (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);
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 初始化
*/
private void init() {
String CLIENTID = "android-" + CommonAppContext.getInstance().getUser().getUser_id() + "-" + MqttClient.generateClientId();
mqttAndroidClient = new MqttAndroidClient(this, HOST, CLIENTID);
mqttAndroidClient.setCallback(mqttCallback); //设置监听订阅消息的回调
mMqttConnectOptions = new MqttConnectOptions();
mMqttConnectOptions.setCleanSession(false); //设置是否清除缓存
mMqttConnectOptions.setConnectionTimeout(10); //设置超时时间,单位:秒
mMqttConnectOptions.setKeepAliveInterval(10); //设置心跳包发送间隔,单位:秒
mMqttConnectOptions.setUserName("public"); //设置用户名
// mMqttConnectOptions.setPassword(new char[0]); //设置密码
if (!mqttAndroidClient.isConnected()) {
doClientConnection();
}
}
private void doClientConnection() {
if (mqttAndroidClient != null && !mqttAndroidClient.isConnected() && isConnectIsNomarl() && b) {
try {
mqttAndroidClient.connect(mMqttConnectOptions, null, iMqttActionListener);
} catch (MqttException e) {
e.printStackTrace();
}
}
}
public static void closeConnection() {
if (mqttAndroidClient.isConnected()) {
try {
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 (MqttException e) {
e.printStackTrace();
}
}
}
/**
* 判断网络是否连接
*/
private boolean isConnectIsNomarl() {
ConnectivityManager connectivityManager = (ConnectivityManager) this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = connectivityManager.getActiveNetworkInfo();
if (info != null && info.isAvailable()) {
String name = info.getTypeName();
Log.i(TAG, "当前网络名称:" + name);
return true;
} else {
Log.i(TAG, "没有可用网络");
/*没有可用网络的时候延迟3秒再尝试重连*/
HandlerUtil.getInstance(this).postDelayed(new Runnable() {
@Override
public void run() {
doClientConnection();
}
}, 3000);
return false;
}
}
//MQTT是否连接成功的监听
private IMqttActionListener iMqttActionListener = new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken arg0) {
if (mMyEmqttConnectListener != null) {
mMyEmqttConnectListener.onConnectSuccess();
}
Logger.e(TAG, "链接状态:", "链接成功");
subscribe(TOPIC_BOSS);
}
@Override
public void onFailure(IMqttToken arg0, Throwable arg1) {
if (mMyEmqttConnectListener != null) {
mMyEmqttConnectListener.onConnectFailure();
}
if (arg0 instanceof MqttException) {
Logger.e(TAG, "链接状态:", "链接失败" + ((MqttException) arg1).getMessage());
}
HandlerUtil.getInstance(getApplicationContext()).postDelayed(new Runnable() {
@Override
public void run() {
if (b) {
doClientConnection();
}
}
}, 3000);
}
};
//订阅主题的回调
private MqttCallback mqttCallback = new MqttCallback() {
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
if (mMyEmqttMesgListener != null) {
mMyEmqttMesgListener.messageArrived(topic, message.toString());
}
Logger.e(TAG, "收到的消息", "主题:" + topic + " 收到的消息:" + message.toString());
//收到其他客户端的消息后,响应给对方告知消息已到达或者消息有问题等
if (TOPIC_BOSS.equals(topic)) {
EventBus.getDefault().post(new BossMsgEvent(message.toString()));
}
}
@Override
public void deliveryComplete(IMqttDeliveryToken arg0) {
LogUtils.e("deliveryComplete---------");
}
@Override
public void connectionLost(Throwable arg0) {
if (mMyEmqttConnectListener != null) {
mMyEmqttConnectListener.onConnectFailure();
}
Logger.e(TAG, "链接状态:", "链接断开");
HandlerUtil.getInstance(getApplicationContext()).postDelayed(new Runnable() {
@Override
public void run() {
if (b) {
doClientConnection();
}
}
}, 300);
}
};
@Override
public void onDestroy() {
try {
cleanSubscribe(TOPIC_BOSS);
if (mqttAndroidClient != null) {
mqttAndroidClient.disconnect(); //断开连接
mqttAndroidClient.unregisterResources();
mqttAndroidClient = null;
stopForeground(true); // 停止前台服务
}
Logger.e(TAG, "服务关闭", "资源释放成功");
} catch (Exception e) {
e.printStackTrace();
}
super.onDestroy();
}
public static void addMyEmqttMesgListener(MyEmqttMesgListener myEmqttMesgListener) {
mMyEmqttMesgListener = myEmqttMesgListener;
}
public static void addMyEmqttConnectListener(MyEmqttConnectListener myEmqttConnectListener) {
mMyEmqttConnectListener = myEmqttConnectListener;
}
public static void addMyEmqttSubscribeListener(MyEmqttSubscribeListener myEmqttSubscribeListener) {
mMyEmqttSubscribeListener = myEmqttSubscribeListener;
}
}

View File

@@ -11,8 +11,13 @@ public class ARouteConstants {
public static final String ROOM_DETAILS = "/moduleroom/RoomActivity";
public static final String MY_ROOM = "/modulevocal/MyRoomActivity";
public static final String MY_ROOM_DETAILS = "/modulevocal/RoomDetailsActivity";
public static final String ME = "/modulemain/MainActivity";
public static final String ROOM_ALLOWANCE = "/modulevocal/RoomAllowanceActivity"; //补贴明细
public static final String ROOM_ALLOWANCE_DETAIL = "/modulevocal/RoomAllowanceDetailActivity"; //补贴历史
public static final String CURRENCY = "/modulevocal/CurrencyExchangeActivity"; //补贴历史
public static final String FRAGMENT_CIRCLE = "CirleListFragment";

View File

@@ -30,7 +30,7 @@ public class ChatLauncher {
*/
public void launchC2CChat(Context context, String chatId) {
Intent intent = new Intent(context, TUIC2CChatActivity.class);
intent.putExtra(TUIConstants.TUIChat.CHAT_ID, chatId);
intent.putExtra(TUIConstants.TUIChat.CHAT_ID, "u"+chatId);
intent.putExtra(TUIConstants.TUIChat.CHAT_TYPE, V2TIMConversation.V2TIM_C2C);
context.startActivity(intent);
}

View File

@@ -187,6 +187,11 @@ public class TimeUtils {
SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日");
return sf.format(d);
}
public static String getDateToStringNoZ(long time) {
Date d = new Date(time);
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
return sf.format(d);
}
/*将字符串转为时间戳*/
public static long getStringToDate(String time) {

View File

@@ -0,0 +1,56 @@
package com.qxcm.moduleutil.utils;
import android.os.CountDownTimer;
public class TimerManager {
private static TimerManager instance;
private CountDownTimer countDownTimer;
private boolean isRunning = false;
private TimerManager() {}
public static synchronized TimerManager getInstance() {
if (instance == null) {
instance = new TimerManager();
}
return instance;
}
public void startTimer() {
if (countDownTimer == null && !isRunning) {
countDownTimer = new CountDownTimer(60000, 1000) { // 1分钟倒计时
@Override
public void onTick(long millisUntilFinished) {
// 每秒执行一次
}
@Override
public void onFinish() {
// 倒计时完成,请求接口
requestApi();
startTimer(); // 继续下一轮倒计时
}
};
countDownTimer.start();
isRunning = true;
}
}
public void stopTimer() {
if (countDownTimer != null) {
countDownTimer.cancel();
countDownTimer = null;
isRunning = false;
}
}
private void requestApi() {
// 请求接口逻辑
}
public boolean isRunning() {
return isRunning;
}
}

View File

@@ -8,7 +8,7 @@ public enum EnvironmentEnum {
"DhpCS82gaigZljYqsWsUWUAZ20dREz",
"qx-yusheng",
"https://qx-yusheng.oss-cn-hangzhou.aliyuncs.com/",
"wx9b6db036ca1073a2",
"wxc7681513be9f926b",
1600086675,
"4a521d6f1c6343998b1c8fd425dea02a"),
TEST(
@@ -19,7 +19,7 @@ public enum EnvironmentEnum {
"DhpCS82gaigZljYqsWsUWUAZ20dREz",
"qx-yusheng",
"https://qx-yusheng.oss-cn-hangzhou.aliyuncs.com/",
"wx9b6db036ca1073a2",
"wxc7681513be9f926b",
1600086675,
"4a521d6f1c6343998b1c8fd425dea02a");

View File

@@ -238,32 +238,34 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
});
}
}
}
// @Override
// public void onLocalSoundLevelUpdate(int volume) {
// if (volume==0){
// else {
// mIvRipple.post(() -> {
// mIvRipple.setVisibility(GONE);
// });
// } else {
// if (pitBean.getUser_id().equals(SpUtil.getUserId()) && closePhone) {
// mIvRipple.post(() -> {
// mIvRipple.setVisibility(GONE);
// });
// }else {
// mIvRipple.post(() -> {
// if (!mIvRipple.isAnimating()) {
// mIvRipple.startAnimation();
// }
// mIvRipple.setVisibility(VISIBLE);
// });
// }
// }
// }
}
@Override
public void onLocalSoundLevelUpdate(int volume) {
if (volume == 0) {
mIvRipple.post(() -> {
mIvRipple.setVisibility(GONE);
});
} else {
mIvRipple.setVisibility(VISIBLE);
mIvRipple.post(() -> {
mIvRipple.startAnimation();
// mIvRipple.setSource(getResources().getResourceName(R.raw.ripple3695), 2);
});
}
}
});
}
/**
* 开始倒计时
*
@@ -693,6 +695,10 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
// mIvRipple.setVisibility(GONE);
// });
// }
// } else if (userId.equals("0")) {
// mIvRipple.post(() -> {
// mIvRipple.setVisibility(GONE);
// });
// }
// }
}

View File

@@ -338,6 +338,8 @@ public class Constants {
public static final String MUTE_REMOTE_AUDIO = "muteRemoteAudio";
public static final int PAYSUCESS = 0x0000;
public static final String FILE_PATH = "/YuTang";
@@ -370,7 +372,7 @@ public class Constants {
public static final String EDIT_ALBUM = "/api/User/edit_album";//编辑相册
public static final String GET_REWARD_LIST = "/api/UserZone/reward_list";//动态打赏列表
public static final String GET_GIFT_LABEL = "/api/Gift/get_gift_label";//礼物标签
public static final String GIFT_LIST = "/api/Gift/get_gift_list";//礼物标签
public static final String GIFT_LIST = "/api/Gift/get_gift_list";//礼物列表
public static final String TOPIC_LIST = "/api/UserZone/topic_list";//获取话题列表
public static final String PUBLISH_ZONE = "/api/UserZone/publish_zone";//发布动态
public static final String GET_CATEGORIES = "/api/UserZone/get_zone_topic";//动态引用的四条话题
@@ -472,6 +474,31 @@ public class Constants {
public static final String POST_REFUSE_PK = "/api/RoomPk/refuse_pk";//不再接受 PK is_pk 1-接受2-拒绝
public static final String POST_END_PK = "/api/RoomPk/end_pk";//pk结束、断开链接,type:1:时间到后系统调用2没有开始前点击结束 3开始后中途结束
public static final String POST_START_PK = "/api/RoomPk/start_pk";//开始PK
public static final String POST_CHARM_LIST = "/api/Room/room_turnover_detail";//房间流水明细
public static final String GET_SUBSIDY = "/api/Room/room_ubsidy";//房间补贴
public static final String POST_MY_ROOM_BEAN = "/api/Index/index_banner";//首页轮播图
public static final String GET_RECHARGE = "/api/UserWallet/can_recharge_list";//可选充值金额列表
public static final String POST_APPLY_Pay = "/api/Payment/app_pay";//APP支付
public static final String POST_LOG_LIST = "/api/UserWallet/log_list";//金币(钻石)明细
public static final String GET_REAL_NAME = "/api/UserData/real_name_info";//实名认证后的信息
public static final String SEND_HEADLINE = "/api/Room/send_headline";//发(抢)头条
public static final String CURRENT_HEADLINE = "/api/Room/current_headline";//当前发(抢)头条需要的数据
public static final String POST_BIND_TYPE = "/api/Bind/bindType";//绑定方式及状态
public static final String EARNINGS_NUM = "/api/UserWallet/exchange_coin";//收益(钻石)兑换金币
public static final String GET_WALLET_CONFIG = "/api/UserWallet/get_wallet_config";//钱包相关配置接口
public static final String POST_BIND = "/api/Bind/bind";//绑定(支付宝、银行卡、微信)
public static final String POST_WITHDRAWAL = "/api/UserWithdrawal/withdrawal";//用户提现
public static final String POST_WEALTH_RANKING = "/api/Ranking/wealth_ranking";//财富、魅力榜
public static final String POST_ROOM_RANKING = "/api/Ranking/room_ranking";//房间榜
public static final String GUILD_RANKING = "/api/Ranking/guild_ranking";//公会榜
public static final String POST_LOVE_RANKING = "/api/Ranking/love_ranking";//真爱榜
public static final String GET_TASKS_LIHEN = "/api/Dailytasks/dailyTasksList";//每日任务列表
public static final String GET_DAILY_TASK_BOX = "/api/Dailytasks/dailyTasksBoxRecord";//礼盒记录
public static final String dailyTasksOpenBox = "/api/Dailytasks/dailyTasksOpenBox";//开启礼盒
public static final String GET_MY_BAG_DATA = "/api/UserGiftPack/get_gift_pack_income";//背包收入
public static final String GET_MY_BAG_OUTCOME = "/api/UserGiftPack/get_gift_pack_outcome";//背包礼物支出列表
public static final String GET_GIFT_PACK = "/api/UserGiftPack/get_gift_pack_list";//获取背包礼物列表
public static final String GET_WITHDRAWAL_LIST = "/api/UserWithdrawal/withdrawal_list";//提现记录

View File

@@ -41,7 +41,7 @@ public class DropView extends LinearLayout {
int sh = ScreenUtils.getScreenHeight();
int sw = ScreenUtils.getScreenWidth();
setBackgroundResource(R.drawable.bg_home_drop_view);
int y = (int) (0.8f * sh) - getHeight();
int y = (int) (0.5f * sh) - getHeight();
int x = sw - getWidth();
setTranslationX(x);
setTranslationY(y);

View File

@@ -0,0 +1,43 @@
package com.qxcm.moduleutil.widget;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.widget.Toast;
import java.io.IOException;
import java.io.OutputStream;
public class ImageSaveUtils {
public static void saveImg(Context context, Bitmap bitmap) {
String fileName = "image_" + System.currentTimeMillis() + ".jpg";
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName);
values.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");
values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
ContentResolver resolver = context.getContentResolver();
Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
try (OutputStream os = resolver.openOutputStream(uri)) {
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);
Toast.makeText(context, "图片已保存到相册", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(context, "保存失败", Toast.LENGTH_SHORT).show();
}
// 发送广播通知系统刷新图库
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaScanIntent.setData(uri);
context.sendBroadcast(mediaScanIntent);
}
}

View File

@@ -0,0 +1,54 @@
package com.qxcm.moduleutil.widget;
import android.text.TextUtils;
import java.util.Map;
public class PayResult {
private String resultStatus;
private String result;
private String memo;
public PayResult(Map<String, String> rawResult) {
if (rawResult == null) {
return;
}
for (String key : rawResult.keySet()) {
if (TextUtils.equals(key, "resultStatus")) {
resultStatus = rawResult.get(key);
} else if (TextUtils.equals(key, "result")) {
result = rawResult.get(key);
} else if (TextUtils.equals(key, "memo")) {
memo = rawResult.get(key);
}
}
}
@Override
public String toString() {
return "resultStatus={" + resultStatus + "};memo={" + memo
+ "};result={" + result + "}";
}
/**
* @return the resultStatus
*/
public String getResultStatus() {
return resultStatus;
}
/**
* @return the memo
*/
public String getMemo() {
return memo;
}
/**
* @return the result
*/
public String getResult() {
return result;
}
}

View File

@@ -0,0 +1,120 @@
package com.qxcm.moduleutil.widget;
import static com.qxcm.moduleutil.utils.permission.PermissionUtils.TAG;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import androidx.appcompat.app.AlertDialog;
import com.alipay.sdk.app.PayTask;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.orhanobut.logger.Logger;
import com.qxcm.moduleutil.R;
import com.qxcm.moduleutil.bean.AppPay;
import com.qxcm.moduleutil.event.PayEvent;
import com.tencent.liteav.base.Log;
import com.tencent.mm.opensdk.constants.ConstantsAPI;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.SendReqCallback;
import org.greenrobot.eventbus.EventBus;
import java.util.Map;
public class PaymentUtil {
private static final int SDK_PAY_FLAG = 1;
public static void payAlipay(final Context mContext, String orderNo) {
// 订单信息
final String orderInfo = orderNo;
Runnable payRunnable = new Runnable() {
@Override
public void run() {
PayTask alipay = new PayTask((Activity) mContext);
Map<String, String> result = alipay.payV2(orderInfo, true);
Message msg = new Message();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
mHandler.sendMessage(msg);
}
};
// 必须异步调用
Thread payThread = new Thread(payRunnable);
payThread.start();
}
public static void payWxMiniProgram2(IWXAPI api, AppPay appPay) {
if (!api.isWXAppInstalled()) {
ToastUtils.showShort("请安装微信");
return;
}
PayReq request = new PayReq();
request.appId = appPay.getWx().getAppid();
request.partnerId = appPay.getWx().getPartnerid();
request.prepayId= appPay.getWx().getPrepayid();
request.packageValue = "Sign=WXPay";
request.nonceStr= appPay.getWx().getNoncestr();
request.timeStamp= appPay.getWx().getTimestamp();
request.sign= appPay.getWx().getSign();
api.sendReq(request);
Logger.e("@@@@@","payWxMiniProgram2:"+request);
}
public void onResp(BaseResp resp){
if(resp.getType()== ConstantsAPI.COMMAND_PAY_BY_WX){
Log.d(TAG,"onPayFinish,errCode="+resp.errCode);
// AlertDialog.Builder builder=new AlertDialog.Builder(this);
// builder.setTitle("");
}
}
@SuppressLint("HandlerLeak")
public static Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SDK_PAY_FLAG: {
PayResult payResult = new PayResult((Map<String, String>) msg.obj);
/**
对于支付结果,请商户依赖服务端的异步通知结果。同步通知结果,仅作为支付结束的通知。
*/
// 同步返回需要验证的信息
String resultInfo = payResult.getResult();
String resultStatus = payResult.getResultStatus();
// 判断resultStatus 为9000则代表支付成功
if (TextUtils.equals(resultStatus, "9000")) {
// 该笔订单是否真实支付成功,需要依赖服务端的异步通知。
ToastUtils.showShort("支付成功");
PayEvent messageEvent = new PayEvent(Constants.PAYSUCESS, "支付成功");
EventBus.getDefault().post(messageEvent);
} else if (TextUtils.equals(resultStatus, "6001")) {
// 该笔订单是否真实支付成功,需要依赖服务端的异步通知。
ToastUtils.showShort("支付取消");
PayEvent messageEvent = new PayEvent(-2, "支付取消");
EventBus.getDefault().post(messageEvent);
} else {
// 该笔订单真实的支付结果,需要依赖服务端的异步通知。
ToastUtils.showShort("支付失败");
// StatisticsUtils.addEvent(MyApplication.getInstance(), Constant.OpenInstall.ALIRECHARGEFAIL);
// StatisticsUtils.addEvent(MyApplication.getInstance(), Constant.OpenInstall.RECHARGEFAIL);
}
break;
}
default:
break;
}
}
};
}

View File

@@ -14,6 +14,7 @@ import com.qxcm.moduleutil.R;
import com.qxcm.moduleutil.bean.UserInfo;
import com.qxcm.moduleutil.bean.room.RoomPitBean;
import com.qxcm.moduleutil.utils.ImageUtils;
import com.qxcm.moduleutil.utils.SpUtil;
/**
@@ -68,14 +69,19 @@ public class RoomDefaultWheatView extends BaseWheatView {
mIvFrame.setVisibility(INVISIBLE);
} else {
mIvFrame.setVisibility(VISIBLE);
mIvFrame.setSource(pitBean.getDress(),1);
mIvFrame.setSource(pitBean.getDress(), 1);
// ImageUtils.loadDecorationAvatar(pitBean.getDress_picture(), mIvFrame);
}
if (showBoss && WHEAT_BOSS.equals(pitNumber)) {
mIvTagBoss.setVisibility(GONE);
}
} else {
mTvName.setText(pitNumber.equals("-1")?"":pitNumber+"号麦位");
mTvName.setText(
"-1".equals(pitNumber) ? "" :
"9".equals(pitNumber) ? "主持位" :
"10".equals(pitNumber) ? "嘉宾位" :
pitNumber + "号麦位"
);
//麦位上锁
if (showBoss && WHEAT_BOSS.equals(pitNumber)) {
mIvTagBoss.setVisibility(VISIBLE);
@@ -85,10 +91,10 @@ public class RoomDefaultWheatView extends BaseWheatView {
// @DrawableRes int origin = getOriginImage();
// ImageUtils.loadRes(isLocked() ? R.mipmap.room_ic_wheat_default_suo :
// (origin == 0 ? R.mipmap.room_ic_wheat_default : origin), mRiv);
mRiv.setImageResource(bean.getIs_lock()==1 ? R.mipmap.room_ic_wheat_default_suo : R.mipmap.room_ic_wheat_default);
mRiv.setImageResource(bean.getIs_lock() == 1 ? R.mipmap.room_ic_wheat_default_suo : R.mipmap.room_ic_wheat_default);
// ImageUtils.loadRes(isLocked() ? R.mipmap.room_ic_wheat_default_suo : R.mipmap.room_ic_wheat_default, mRiv);
}
if (isMute()){
if (isMute()) {
ImageUtils.loadRes(R.mipmap.room_microphone_off, mIvSex);
}
mIvFrame.setVisibility(INVISIBLE);
@@ -100,9 +106,9 @@ public class RoomDefaultWheatView extends BaseWheatView {
if (showSexIcon) {
checkSex();
}
if (pitBean.is_pk()){
if (pitBean.is_pk() || pitBean.getNickname() == null || pitBean.getNickname().isEmpty()) {
mCharmView.setVisibility(GONE);
}else {
} else {
mCharmView.setVisibility(VISIBLE);
}
}
@@ -168,8 +174,28 @@ public class RoomDefaultWheatView extends BaseWheatView {
if (maozi != null) maozi.setVisibility(GONE);
}
@Override
public void onRemoteSoundLevelUpdate(String userId, int soundLevel) {
}
@Override
public void onLocalSoundLevelUpdate(int volume) {
if (volume==0){
mIvRipple.stopAnimation();
} else {
if (pitBean.getUser_id().equals(SpUtil.getUserId()) && closePhone) {
mIvRipple.stopAnimation();
}else {
mIvRipple.post(() -> {
if (!mIvRipple.isAnimating()) {
mIvRipple.startAnimation();
}
mIvRipple.setVisibility(VISIBLE);
});
}
}
}
}

View File

@@ -68,7 +68,7 @@ public class RoomMakeWheatView extends BaseWheatView {
mIvRipple.stopAnimation();
mIvRipple.setVisibility(VISIBLE);
mTvName.setText(bean.getNickname());
ImageUtils.loadHeadCC(bean.getAvatar(), mRiv);
ImageUtils.loadCenterCrop(bean.getAvatar(), mRiv);
if (TextUtils.isEmpty(pitBean.getDress_picture())) {
mIvFrame.setVisibility(INVISIBLE);
} else {
@@ -179,4 +179,9 @@ public class RoomMakeWheatView extends BaseWheatView {
public void onRemoteSoundLevelUpdate(String userId, int soundLevel) {
}
@Override
public void onLocalSoundLevelUpdate(int volume) {
}
}

View File

@@ -35,6 +35,7 @@ import com.qxcm.moduleutil.presenter.RewardGiftContacts;
import com.qxcm.moduleutil.presenter.RewardGiftPresenter;
import com.qxcm.moduleutil.utils.DialogUtils;
import com.qxcm.moduleutil.utils.ImageUtils;
import com.qxcm.moduleutil.widget.GifAvatarOvalView;
import java.util.ArrayList;
import java.util.List;
@@ -98,10 +99,13 @@ public class RewardGiftDialogFragment extends BaseMvpDialogFragment<RewardGiftPr
@Override
protected void initView() {
mBinding.recycleView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
adapter = new BaseQuickAdapter<RewardUserBean, BaseViewHolder>(R.layout.item_reward, null) {
adapter = new BaseQuickAdapter<RewardUserBean, BaseViewHolder>(com.qxcm.moduleutil.R.layout.item_reward1, null) {
@Override
protected void convert(BaseViewHolder helper, RewardUserBean item) {
ImageUtils.loadHeadCC(item.getAvatar(), helper.getView(R.id.im_reward));
GifAvatarOvalView gifAvatarOvalView = helper.getView(com.qxcm.moduleutil.R.id.im_reward1);
if (item!=null ) {
ImageUtils.loadHeadCC(item.getAvatar(), helper.getView(com.qxcm.moduleutil.R.id.im_reward1));
}
}
};
mBinding.recycleView.setAdapter(adapter);

View File

@@ -2,10 +2,15 @@ package com.qxcm.moduleutil.widget.dialog;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static androidx.core.content.ContextCompat.getSystemService;
import static com.blankj.utilcode.util.ActivityUtils.startActivity;
import static com.qxcm.moduleutil.utils.wx.WeChatShareUtils.weChatShareUtils;
import android.app.Activity;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
@@ -19,7 +24,9 @@ import androidx.annotation.NonNull;
import com.blankj.utilcode.util.ImageUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.qxcm.moduleutil.R;
import com.qxcm.moduleutil.activity.WebViewActivity;
import com.qxcm.moduleutil.base.CommonAppContext;
import com.qxcm.moduleutil.bean.CircleListBean;
import com.qxcm.moduleutil.databinding.RoomDialogShareBinding;
import com.qxcm.moduleutil.utils.BaseBottomSheetDialog;
import com.qxcm.moduleutil.utils.SpUtil;
@@ -36,8 +43,9 @@ public class ShareDialog extends BaseBottomSheetDialog<RoomDialogShareBinding> {
private String mcontent;
private String murl;
private String ids;
private int types;
private int types;//1用户 2房间3动态
private String mUserId;
private CircleListBean bean;
public interface OnShareDataListener {
void onShareDataLoaded(String id);
@@ -51,7 +59,7 @@ public class ShareDialog extends BaseBottomSheetDialog<RoomDialogShareBinding> {
private static final String TAG = "ShareDialog";
public ShareDialog(Context context, String content, String url, String id, int type,String userId) {
public ShareDialog(Context context, String content, String url, String id, int type,String userId,CircleListBean bean) {
super(context);
this.mcontent = content;
this.murl = url;
@@ -59,6 +67,7 @@ public class ShareDialog extends BaseBottomSheetDialog<RoomDialogShareBinding> {
this.ids = id;
this.types = type;
this.mUserId = userId;
this.bean = bean;
Log.i(TAG, "(Start)启动了===========================ShareDialog");
iniv();
}
@@ -138,9 +147,27 @@ public class ShareDialog extends BaseBottomSheetDialog<RoomDialogShareBinding> {
listener.onShareDataLoaded(ids);
}
} else if (R.id.tv_jub == id) {
if (types == 3) {
Intent intent = new Intent(getContext(), WebViewActivity.class);
intent.putExtra("url", "https://vespa.qxmier.com/web/index.html#/pages/feedback/report?id=" + SpUtil.getToken() + "&fromType=" + types + "&fromId=" + bean.getId());
intent.putExtra("title", "举报");
startActivity(intent);
}else if (types == 1){
Intent intent = new Intent(getContext(), WebViewActivity.class);
intent.putExtra("url", "https://vespa.qxmier.com/web/index.html#/pages/feedback/report?id=" + SpUtil.getToken() + "&fromType=" + types + "&fromId=" + bean.getUser_id());
intent.putExtra("title", "举报");
startActivity(intent);
}
} else if (R.id.tv_copy == id) {
ClipboardManager clipboard = (ClipboardManager)mContext.getSystemService( Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("链接",bean.getShare_url() );
if (clipboard != null) {
clipboard.setPrimaryClip(clip);
com.hjq.toast.ToastUtils.show("复制成功");
} else {
com.hjq.toast.ToastUtils.show("复制失败");
}
}
dismiss();

View File

@@ -16,6 +16,7 @@ import android.widget.TextView;
import androidx.viewpager.widget.ViewPager;
import com.hjq.toast.ToastUtils;
import com.qxcm.moduleutil.R;
import java.util.List;
@@ -67,6 +68,15 @@ public class FullScreenUtil {
}
});
img_vp.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
ToastUtils.show("保存成功");
return false;
}
});
img_vp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
@@ -79,10 +89,9 @@ public class FullScreenUtil {
img_down_iv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/* if(imgList.get(position)!=null){
ImageSaveUtils.saveImg(XQDetailActivity.this, imgList.get(position));
}
*/
// if (imgList.get(position) != null) {
// ImageSaveUtils.saveImg(XQDetailActivity.this, imgList.get(position));
// }
}
});
}
@@ -99,6 +108,7 @@ public class FullScreenUtil {
}
});
dialog.setContentView(view);
dialog.show();
}

View File

@@ -1,15 +1,24 @@
package com.qxcm.moduleutil.widget.img;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.PagerAdapter;
import com.blankj.utilcode.util.ImageUtils;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
import com.qxcm.moduleutil.R;
import com.qxcm.moduleutil.widget.ImageSaveUtils;
import java.util.List;
@@ -47,6 +56,28 @@ public class ImgVPAdapter extends PagerAdapter {
}
}
});
iv_img.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Glide.with(context)
.asBitmap()
.load(paths.get(position))
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
ImageSaveUtils.saveImg(context, resource);
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
Toast.makeText(context, "图片加载失败", Toast.LENGTH_SHORT).show();
}
});
return true;
}
});
container.addView(iv_img);
return iv_img;
}