diff --git a/app/releas/release/output-metadata.json b/app/releas/release/output-metadata.json
index 975d1e36..85dd5618 100644
--- a/app/releas/release/output-metadata.json
+++ b/app/releas/release/output-metadata.json
@@ -11,9 +11,9 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
- "versionCode": 1,
- "versionName": "1.0.0.0",
- "outputFile": "羽声_1.0.0.0_1.apk"
+ "versionCode": 2,
+ "versionName": "1.0.0.1",
+ "outputFile": "羽声_1.0.0.1_2.apk"
}
],
"elementType": "File",
@@ -22,14 +22,14 @@
"minApi": 28,
"maxApi": 30,
"baselineProfiles": [
- "baselineProfiles/1/羽声_1.0.0.0_1.dm"
+ "baselineProfiles/1/羽声_1.0.0.1_2.dm"
]
},
{
"minApi": 31,
"maxApi": 2147483647,
"baselineProfiles": [
- "baselineProfiles/0/羽声_1.0.0.0_1.dm"
+ "baselineProfiles/0/羽声_1.0.0.1_2.dm"
]
}
],
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 854af90d..f9872c1b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -196,7 +196,7 @@
android:name=".wxapi.WXEntryActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:exported="true"
- android:taskAffinity="com.xscm.qxlive"
+ android:taskAffinity="com.qxcm.qxlive"
android:launchMode="singleTask">
diff --git a/app/src/main/java/com/qxcm/qxlive/wxapi/WXEntryActivity.java b/app/src/main/java/com/qxcm/qxlive/wxapi/WXEntryActivity.java
index bad7147b..aef240ad 100644
--- a/app/src/main/java/com/qxcm/qxlive/wxapi/WXEntryActivity.java
+++ b/app/src/main/java/com/qxcm/qxlive/wxapi/WXEntryActivity.java
@@ -1,4 +1,4 @@
-package com.xscm.midi.wxapi;
+package com.qxcm.qxlive.wxapi;
import android.app.Activity;
import android.os.Bundle;
diff --git a/app/src/main/java/com/qxcm/qxlive/wxapi/WXPayEntryActivity.java b/app/src/main/java/com/qxcm/qxlive/wxapi/WXPayEntryActivity.java
index d12a12e2..84f07eb6 100644
--- a/app/src/main/java/com/qxcm/qxlive/wxapi/WXPayEntryActivity.java
+++ b/app/src/main/java/com/qxcm/qxlive/wxapi/WXPayEntryActivity.java
@@ -1,4 +1,4 @@
-package com.xscm.midi.wxapi;
+package com.qxcm.qxlive.wxapi;
import android.app.Activity;
import android.content.Intent;
diff --git a/app/src/main/res/mipmap-xxhdpi/screen.webp b/app/src/main/res/mipmap-xxhdpi/screen.webp
deleted file mode 100644
index 68135279..00000000
Binary files a/app/src/main/res/mipmap-xxhdpi/screen.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/screen.webp b/app/src/main/res/mipmap-xxxhdpi/screen.webp
deleted file mode 100644
index 68135279..00000000
Binary files a/app/src/main/res/mipmap-xxxhdpi/screen.webp and /dev/null differ
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
deleted file mode 100644
index 1c850379..00000000
--- a/app/src/main/res/values-night/themes.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
deleted file mode 100644
index bcb7b148..00000000
--- a/app/src/main/res/values/themes.xml
+++ /dev/null
@@ -1,113 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index 9bc4b211..16ea98c1 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -28,8 +28,8 @@ isBuildModule=false
#org.gradle.deamon=false
android.injected.testOnly=false
-APP_VERSION_NAME=1.0.0.0
-APP_VERSION_CODE=1
+APP_VERSION_NAME=1.0.0.1
+APP_VERSION_CODE=2
org.gradle.jvm.toolchain.useLegacyAdapters=false
#org.gradle.java.home=C\:\\Users\\qx\\.jdks\\ms-17.0.15
diff --git a/moduleLogin/src/main/AndroidManifest.xml b/moduleLogin/src/main/AndroidManifest.xml
index 09c40907..005e324b 100644
--- a/moduleLogin/src/main/AndroidManifest.xml
+++ b/moduleLogin/src/main/AndroidManifest.xml
@@ -4,19 +4,19 @@
+ />
+ />
+ />
diff --git a/moduleLogin/src/main/res/values-night/themes.xml b/moduleLogin/src/main/res/values-night/themes.xml
deleted file mode 100644
index 1c850379..00000000
--- a/moduleLogin/src/main/res/values-night/themes.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/moduleLogin/src/main/res/values/themes.xml b/moduleLogin/src/main/res/values/themes.xml
deleted file mode 100644
index 46ca6c9a..00000000
--- a/moduleLogin/src/main/res/values/themes.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/moduleUtil/src/main/assets/page_show.htm b/moduleUtil/src/main/assets/page_show.htm
new file mode 100644
index 00000000..3587610e
--- /dev/null
+++ b/moduleUtil/src/main/assets/page_show.htm
@@ -0,0 +1,3 @@
+
+
+
羽声语音直播隐私保护政策
本版本更新日期:2025年【9】月【4】日
本版本生效日期:2025年【9】月【4】日
引言:
羽声语音深知个人信息对用户(以下或称“您”)的重要性。我们将按法律法规要求,采取严格的安全保护措施,尽力保护您的个人隐私信息安全可控,故我们特定制本《羽声语音隐私保护政策》(以下简称 “本政策”)。 以便您充分了解,在您使羽声语音直播的产品或服务的过程中,我们如何处理您的个人信息,以及您可以如何管理您的个人信息。
本政策将帮助您了解如下内容:
一、定义及适用范围
二、我们如何收集和使用您的个人信息
三、我们如何使用Cookie和第三方H5页面
四、我们如何共享、转让、公开披露您的个人信息
五、我们如何存储和保护您的个人信息
六、您如何管理您的个人信息
七、未成年人保护
八、本政策的更新
九、联系我们
十、其他
【特别提示】请您在使用我们各项产品或服务前,仔细阅读并透彻理解本政策,特别是以粗体/下划线/粗体下划线等有特殊标识的条款,您应重点阅读,在确认充分理解并同意后使用相关产品或服务。如果您不同意我们收集您的任何个人信息,您应当立即停止使用并退出羽声语音直播。当您使用或继续使用我们的产品或服务时,即表示您同意我们按照本政策来处理您的相关信息。
如对本政策内容有任何疑问,您可以通过本政策中“联系我们”一节提供的联系方式与我们联系。
一、定义及适用范围
(一)定义
1、羽声语音软件及相关服务:指由西安熙晟文化传媒有限公司(注册地址:陕西省西安市高新区天谷八路156号软件新城云汇谷A6西户2层201-2-275 及其关联方通过合法拥有并运营的、标注名称为羽声语音、羽声语音极速版的客户端应用程序、APP、微信小程序、微信公众号、羽声语音官方网站(http://gw.limaoyuyin.cn)、通过APK、SDK、API等方式向您提供的软件和/或服务及随技术发展出现的新形态向您提供的产品与服务。
2、关联方:指在现在、将来控制西安熙晟文化传媒有限公司、受西安熙晟文化传媒有限公司控制或与西安熙晟文化传媒有限公司处于共同控制下的公司、机构。
3、未成年人:指不满十八周岁的自然人。十六周岁以上的未成年人,以自己的劳动收入为主要生活来源的,视为完全民事行为能力人。
4、儿童:指不满十四周岁的未成年人。
(二)适用范围
本政策适用于羽声语音的产品或服务。如我们关联公司的产品或服务中使用了羽声语音直播提供的产品或服务,则本政策同样适用于该部分产品或服务。但请您注意,本政策不适用于以下情况:
1、为我们的产品或服务提供广告服务的第三方的信息收集/处理做法;
2、我们的产品或服务可能会包含或链接至第三方提供的信息与/或第三方服务(包括任何第三方应用、网站、产品、服务等),这些信息与/或服务由第三方负责运营,具体规则请参照该第三方的隐私政策或类似声明;
3、其他非羽声语音向您提供的产品与/或服务内容。
二、我们如何收集和使用您的个人信息
我们收集和使用的您的个人信息类型包括两种:第一种:我们产品与/或服务的基本业务功能所必需的信息:此类信息为产品与/或服务正常运行的必备信息,您须授权我们收集。如您拒绝提供,您将无法正常使用我们的产品与/或服务;第二种:拓展业务功能可能需要收集的信息:此信息为非基本业务功能所需的信息,您可以选择是否授权我们收集。如您拒绝提供,将导致拓展业务功能无法实现或无法达到我们拟达到的效果,但不影响您对基本业务功能的正常使用。
我们在此特别提醒您:我们致力于打造多样的产品和服务以满足您的需求。因我们向您提供的产品和服务种类众多,且不同用户选择使用的具体产品/服务范围存在差异,故基本/拓展功能及对应收集使用的个人信息类型、范围等会有所区别,请以具体的产品/服务功能为准。
我们收集和使用您的个人信息的场景有:
(一)注册成为我们的用户
当您在羽声语音直播上创建羽声语音直播账号时,您需要提供您本人的实名手机号码、验证码并完善相关的网络身份识别信息(包括头像、昵称、登录密码、性别、生日)。您需理解,手机号码、验证码匹配结果、性别、生日均属于您的敏感个人信息,我们收集您的手机号码、验证码是基于法律法规的相关要求。其中:(1)实名手机号码、验证码是为了验证您的身份,满足相关法律规定的网络实名制要求;(2)生日是为了协助判断您是否为年满十八周岁的成年人,若您是未成年人,我们将不对您提供服务,请您谅解,也提请您按真实情况填写相应信息,切勿虚构、假冒;(3)性别是为了向您提供性别匹配服务。上述敏感个人信息,您有权拒绝提供,但将无法使用相关功能或服务,请您谨慎考虑后再选择是否提供。
在您注册账号后,您可以根据自身需求选择填写学校、个性签名、家乡、兴趣爱好等个人主页信息,来帮助您更加形象的展示自我。但如果您不提供这些信息,将不会影响本服务的基本业务功能。您在个人主页发布的上述信息、动态、添加的兴趣标签、游戏名片,以及你的账号等级、ID号、获赞数、粉丝数,将会在账号(包括APP和微信小程序)的个人主页中公开展示,您也可以通过APP设置-隐私进行信息隐藏(不对未关注用户显示可见)或通过第六节所述管理您的个人信息。
(二)进行实名认证
1、为满足相关法律规定及监管要求、确保用户身份真实性、实现反欺诈等风控、保障系统与服务安全(包括依法保护未成年人合法权益、用户权益发放、打击电信网络诈骗等需要),当您使用羽声语音直播中某些特定类型的产品与/或服务,您需要向平台提供您本人的真实姓名及身份证号码信息(敏感个人信息),并可能需要通过您的人脸信息(敏感个人信息)进行身份一致性核验:
(1)在您进行实名认证时,若您选择或产品页面进入火山引擎、腾讯云等第三方的实名认证程序(人脸识别功能),我们及/或第三方会申请、调用终端设备的摄像头权限来采集您的面部识别信息,在您授权后,前述第三方实名认证程序将通过SDK方式获取您的如下敏感个人信息:姓名、身份证件号码、人脸信息(指为验证或识别您的身份而采集的人脸图像、视频,以及基于上述图像、视频提取的面部识别特征),为了准确验证您的身份,第三方需将上述信息与其合法存有的(如基于法律法规或政府部门、有权机关授权或存储)您的个人信息进行比对核验。为了验证实名认证结果的有效性,并及时解决用户就实名认证结果的争议或投诉,您通过以上方式实名认证的,第三方会向我们返回人脸识别验证结果以及为验证或识别您的身份而采集的部分人脸图像、视频(具体以第三方提供为准,此为您的敏感个人信息),除此外,我们会存储您在上述实名认证过程中主动填写的姓名、身份证号码(敏感个人信息)。
当您通过本平台主动选择进行真人头像认证时,经您同意后,我们会收集您上传的头像照片,为了验证您上传的头像照片为您本人,不存在冒用或盗用他人照片、头像的情形,我们将请求您按上述方式通过第三方人脸识别程序完成实名认证,经第三方反馈验证一致的,您上传的头像照片将作为您在羽声语音直播APP内的头像进行公开,具体规则请见《真人头像认证协议》。因此,我们在此提醒您谨慎使用真人头像认证功能,您有权拒绝,且您拒绝不影响您继续使用本平台的基本业务功能。
具体使用的第三方人脸识别程序可通过第四节第(一)条所列《羽声语音直播与第三方共享个人信息清单》查阅。
(2)若您无法通过上述程序完成实名认证,您可以选择通过人工认证方式完成实名认证程序,为了完成实名认证服务,我们将依据相关法律法规获取并存储您的个人身份信息,包括如下:姓名(敏感个人信息)、身份证件类型(包括但不限于相应的身份证、护照、台湾居民来往大陆通行证、港澳居民往来内地通行证等)和相应的证件正反面图片(敏感个人信息)、您手持相应身份证件的照片(敏感个人信息)。
提请您特别注意,您的身份证件信息、您手持身份证件的照片、真人照片、人脸信息均属于敏感个人信息,您可以拒绝提供,如果拒绝提供您将可能无法获得需要实名认证的特定服务,但不影响您正常使用产品的基本业务功能(包括产品的浏览和观看功能);同时,我们将依法记录、保存验证身份信息及验证结果,这些信息仅供完成验证目的,或者其他法律法规所规定的用途,未经您明示授权不会用作其他目的。
2、具体实名场景及对应服务主要包括(具体以您使用的功能为准):
(1)当您申请注册为互联网发布者(主播)、开设个人房时,需要提供您的真实姓名、身份证件信息(敏感个人信息)进行实名身份认证,并通过您的面部识别信息(敏感个人信息)进行身份一致性核验。通过验证后,您方可在平台上从事直播发布活动。如果您拒绝提供上述信息(您有权拒绝),您将可能无法获得相关服务(开播或开设个人房间),但不影响您正常使用产品的浏览和观看功能。
(2)当您通过羽声语音直播进行充值、消费时(特别是当您使用下单功能时),为了保证您的资金安全,避免未成年人使用下单功能,我们可能需要您提供您的真实姓名、身份证件信息(敏感个人信息)进行实名身份认证,并可能需要您通过您的面部识别信息(敏感个人信息)进行身份一致性核验。前述信息您可以拒绝提供,您拒绝提供前述信息的,只会使您无法使用羽声语音直播对应功能,但不影响您使用其他功能。
(3)当您使用提现功能,我们会需要您绑定银行卡账号信息、支付宝账号、身份证号码、姓名(敏感个人信息)进行实名认证。在您授权后,我们可能需要通过您的面部识别信息(敏感个人信息)进行身份一致性核验。您可以拒绝提供前述信息,但您拒绝提供将导致您无法使用对应功能,但不影响您使用羽声语音直播的其他功能。
(4)在账号冻结、封禁申诉时,为了核实争议账号是您本人持有,平台还将使用您注册时使用的实名手机号码、身份证件信息(敏感个人信息)进行身份核实认证。
(5)基于依法保护未成年人权益的需求,我们为未成年人提供了青少年模式,若您拟解除、退出青少年模式,我们会需要您提供真实姓名、身份证件信息(敏感个人信息),并在您授权后,我们可能需要通过您的面部识别信息进行身份一致性核验。如果您拒绝提供前述信息,您将无法退出青少年模式,但不影响您在青少年模式下使用羽声语音直播产品和服务。
(三)为您提供服务内容的浏览/播放/搜索/下载
1、当您进行直播间、聊天室、视频、音频等服务内容的浏览、播放、下载功能时,为与您的移动设备进行必要的适配,向您提供连续性、一致化的使用体验以及最优化的页面展示,我们需要收集您的设备信息、个人上网记录。
设备信息包括:浏览器类型、设备型号、操作系统版本、设备设置、DEVICEID、AndroidID、MAC地址、IMEI、IDFA、OAID、ICCID、UDID、UUID、MEID及其他设备标识符、设备环境。
个人上网记录包括:浏览/点击/播放记录、收藏/关注/预约记录、点赞/分享/发布记录等。
我们收集这些信息是为了向您提供直播间、视频、音频等内容的浏览、播放和展示服务,如您拒绝提供上述权限将可能导致您无法使用我们的相关产品与服务。请您理解,单独的设备信息、日志信息是无法识别特定自然人身份的信息。如果我们将这类非个人信息与其他信息结合用于识别特定自然人身份,或者将其与个人信息结合使用,则在结合使用期间,这类非个人信息将被视为个人信息,除取得您授权或法律法规另有规定外,我们会将该类个人信息做匿名化、去标识化处理。
2、当您使用我们提供的搜索功能时,我们还会收集您搜索的关键字信息、设备信息(包括设备型号、操作系统版本、设备设置、AndroidID、MAC地址、IMEI、IDFA、OAID、ICCID等设备标识符、设备环境)、日志信息(包括您的浏览记录和时间、您搜索的时间以及次数)。我们收集这些信息是为了方便您后续查找时无需再次输入,并向您快速匹配您所需要的内容以及您可能感兴趣的内容,为了提供高效的搜索服务,部分前述信息会暂时存储在您的本地存储设备之中,并可向您展示搜索结果内容、搜索历史记录。您可以自主删除前述搜索记录。搜索的关键词信息通常无法单独识别您的个人身份,不属于您的个人信息,不在本政策的限制范围内。但当您的搜索关键词信息与您的其他信息有联结并可识别您的个人身份时,在结合使用期间,我们会将您的搜索关键词信息作为您的个人信息,与您的搜索历史记录一同按照本政策对其进行处理与保护。
当您分享/接收被分享的信息时,我们会在您进入羽声语音直播时访问您的剪切板,写入或读取其中包含的文字、链接、口令、分享码,以实现分享、跳转功能。我们不会收集、存储剪切板的其他信息。
3、当您使用下载功能时,经您同意后,我们会访问您的存储权限,以便在您设备外置存储空间内写入相关文件。如您拒绝提供,仅会使您无法使用该功能,但并不影响您正常使用产品或服务的其他功能。同时,您也可以随时通过您设备的相关功能设置开启/取消该权限。
(五)帮助您上传或发布图文、音频和视频
1、若您通过羽声语音直播的社区功能或通过羽声语音直播的评论、分享、发帖、发布动态等功能上传/发布/编辑图文、音频、视频时,当您使用到具体功能时,我们将向您分别单独请求访问您设备的相机/摄像头权限、相册权限(IOS端)/存储权限(安卓端)、录音/麦克风权限:(1)经您同意授权相机/摄像头权限后,我们会访问您的相应权限,以便您拍摄照片、视频,并采集、识别上述功能实现过程中所拍摄或录制的图片及视频信息;(2)经您同意授权相册权限(IOS端)/存储权限(安卓端)后,我们会访问您的相应权限,以便您查看、选择相册里的图片/视频发布动态、反馈意见,设置与更换头像、封面,聊天时分享图片/视频,以及保存图片/视频至相册,您还可以在其他场景访问设备里的照片、音频和视频,以及保存内容到设备;(3)经您同意授权录音/麦克风权限后,我们会访问您的相应权限,以便识别您上传的语音信息,并采集、识别上述功能实现过程中所录制、输入的音频信息。如您拒绝提供上述权限的仅会使您无法使用该功能,但并不影响您正常使用产品/服务的其他功能,同时,您也可以随时通过您的设备系统或使用我们的产品/服务的相关功能设置页面开启/取消该权限。
2、如您自愿填写信息或自愿发布内容的,我们会收集您上传的视频、照片、音视频、帖子、评论、点赞、关注、分享信息、浏览及搜索信息。您可随时删除您发布的照片、音视频、帖子及评论内容。为了验证您发布内容的合法合规性,避免您发布的内容涉及违法或侵犯第三方合法权益的情形。您同意我们为了上述目的将您发布的图文、音频、视频内容提供给我们的服务提供商,并由我们的服务提供商对上述内容进行审核、标注后向我们反馈结果。我们不会向上述服务商传输或共享您的个人信息,我们仅会对您发布内容的合法合规性进行审核。
3、当您使用设备相机扫描二维码时,我们将访问您设备的相机/摄像头权限。如您拒绝提供的仅会使您无法使用该功能,但并不影响您正常使用产品与/或服务的其他功能。同时,您也可以随时通过您的设备的设置开启/取消该权限。
4、您在使用动态发布等功能时发布的公开信息可能涉及您或他人的个人信息或个人隐私信息,如您在分享、评论时选择上传的包括个人信息的图片或视频。您应更为谨慎考虑是否公开该等信息,以及获得合法权利人授权后再行发布,同时如该等信息中涉及未成年人个人信息的,您应在发布前征得其监护人同意。
(六)录制音视频及提供直播功能
当您使用录制音视频、使用个人房间服务以及直播服务时,经您分别授权我们将访问您设备的相机/摄像头权限(当您同意开启此项权限后,我们会使用您设备上的相机拍摄功能。此项功能将用于实现照片拍摄、录制视频功能,并采集、识别上述功能实现过程中所拍摄或录制的图片及视频信息)、录音(麦克风)相关权限(当您同意开启此项权限后,我们会使用您设备上的麦克风功能,并会识别您上传的语音信息。此项权限将用于实现语音输入功能,并采集、识别上述功能实现过程中所输入的语音信息),如您拒绝授权的仅会使您无法使用该功能,但并不影响您正常使用产品与/或服务的其他功能。同时,您也可以随时通过您的设备设置开启/取消该权限。此外,为保证您使用直播或聊天室功能时的流畅度、节省您的流量,我们会收集您使用该功能时段内使用流量的大小。
(七)消费与提现
当您通过羽声语音购买商品和/或服务时(如SVIP会员购买、购买虚拟商品、个性装扮、礼物),为帮助您完成交易、保障交易安全、提供订单查询、客服及售后服务,我们需要根据商品的类型收集如下部分或全部的订单信息:下单时间、订单编号、订单状态、交易的商品信息、支付信息(支付金额、支付方式、支付流水号、支付状态、第三方支付渠道的支付账号,敏感个人信息)、虚拟商品消费使用记录、会员开通时间。为此,为保障您的账户和资金安全以及支付服务的安全稳定运行、履行反电信网络诈骗等法定义务,我们还会收集您必要的设备信息(IP地址)并提供给您选择的第三方支付渠道。为向您提供售后与争议解决服务之目的,我们需要及时获悉并确认交付、售后的进度及状态,您同意我们可自相应第三方处收集与交付、售后进度相关的信息。我们向您承诺,我们会以最大努力保障您的个人信息安全,并严格要求第三方对您的个人信息保密,只以交付、售后之目的获悉和使用,不得对外泄露或做其他任何用途。您可以拒绝提供前述信息,但您拒绝提供将导致您无法使用对应功能,但不影响您使用羽声语音直播的基本业务功能。
当您使用提现功能时,为了完成支付结算,我们会收集、使用您主动填写的收款账户信息(银行卡账号信息及开户行信息、支付宝账号及/或微信账号,具体以您填写为准)以及身份证号码、姓名,并会共享给第三方支付结算机构(请见第四节第(一)项)。前述信息为敏感个人信息,您可以拒绝提供,您拒绝提供将导致您无法使用对应提现功能,但不影响您使用羽声语音直播的其他功能。
(八)客户服务
当您主动填写羽声语音APP上的反馈意见(如帮助与反馈-意见反馈页面)、举报投诉页面时,我们会收集您主动填写的手机号、反馈/举报投诉内容(请谨慎考虑后再决定是否填写),我们收集信息仅用于收集您的意见,便于与您联系、尽快帮助您解决问题。
当您向我们发起投诉、申诉或进行咨询时,为了保障您的账户及系统安全,我们需要您提供必要的个人信息(包括账号信息、姓名、手机号、身份证以及其他必要身份信息)以核验您的用户身份。为便于与您联系、尽快帮助您解决问题或记录相关问题的处理方案及结果,我们可能会收集您与我们的沟通信息(包括文字/图片/音视频/通话记录形式)、您为了证明相关事实提供的信息、与客服需求相关联的其他必要信息。如您针对具体的订单发起客服需求的,我们还会使用您的订单信息。
以上信息为您的个人敏感信息,您有权拒绝提供,但我们收集这些信息是为了调查事实与帮助您解决问题,如您拒绝提供上述信息,我们可能无法向您及时反馈投诉、申诉或咨询结果。
(九)为您提供安全保障服务
为了使羽声语音直播产品及服务与您的移动设备进行必要的适配,提高您使用我们及我们合作伙伴提供服务的安全性,保护您或其他用户或公众的人身财产安全免受侵害,更好的预防钓鱼网站、欺诈、网络漏洞、计算机病毒、网络攻击、网络入侵等安全风险,分析当前设备的风险等级,有效识别各种作弊行为、风险设备、恶意刷量、恶意程序、保护您的账号安全,我们会收集为实现安全保障功能的必要信息,我们会获取您的以下信息:
1、网络访问日志信息和用户日志信息。包括:网络信息(如网络类型)、运营商信息(如SIM卡信息)、账号信息(如账号登录地)以及使用“羽声语音直播”产品或服务的频率、崩溃数据、总体安装、使用情况、性能数据、服务故障等信息。
2、您的设备信息。包括:设备型号、操作系统、设备序列号/SN、设备标识符(如IMEI/IMSI/Android ID/IDFA/OpenUDID/GUID/ICCID/ UUID/MEID/DEVICEID)、设备MAC地址、应用列表、登陆IP地址、软件版本号、接入网络的方式、类型和状态、设备当前运行进程/运行中进程信息、设备传感器信息、蓝牙信息屏幕尺寸等参数信息,同时为了保证您的账号安全,我们会检测您设备的root状态。请您注意,为了便于您及时接收、发送聊天消息、接收消息通知,我们会在后台状态下获取您设备的MAC地址。
我们可能会使用或整合您的上述日志信息与设备信息、账户信息、交易信息、支付信息以及其他取得您授权或依据法律共享的信息,综合判断您账户及交易风险、完成身份验证、检测,防范安全事件,并依法采取必要的记录、审计、分析、处置措施,保护各方合法权益稳定不受侵害。
您理解并同意,为了帮助我们进行bug分析、反作弊、反黑产等安全保护工作,保障您正常使用本产品与/或服务、保障您的账号安全,在您的羽声语音App每次切换至后台或处于静默状态下或重新启动时,我们会收集您的Mac地址信息(包括手机Mac地址和蓝牙Mac地址)、IMEI、获取运行中进程信息、设备序列号、Android ID、DEVICEID,我们将把读取频次控制在合理范围内。
请您理解,单独的设备信息、日志信息等是无法识别特定自然人身份的信息。如果我们将这类非个人信息与其他信息结合用于识别特定自然人身份,或者将其与个人信息结合使用,则在结合使用期间,这类非个人信息将被视为个人信息,除取得您授权或法律法规另有规定外,我们会将该类个人信息做匿名化、去标识化处理。
同时,为了维护网络安全、保障良好生态,便于公众为公共利益实施监督,依据《互联网用户账号信息管理规定》等法律规定,您的IP地址所对应的归属地域信息将会展示在您的个人资料页。境内展示到省(区、市),境外展示到国家或地区,信息以网络运营商数据为准,请您理解,该信息不会泄露您的详细地址,相关展示暂不支持手动开启或关闭。
(十)我们获取的设备权限
为确保相关业务功能的正常实现,我们需要根据具体的使用场景调用对应的必要权限。请您注意,您开启任一权限即代表您授权我们可以收集和使用相关个人信息来为您提供对应服务,若您关闭任一权限或取消授权,我们将不再基于对应权限继续收集和使用相关个人信息,也无法为您提供该权限所对应的服务。但是,您关闭权限的决定不会影响此前基于您的授权所进行的信息收集及使用。
(十一)收集和使用个人信息的其他规则
1、若您提供的信息中含有其他用户的个人信息,在向我们提供这些个人信息之前,您需确保您已经取得合法的授权。
2、您理解并知悉,您向外部第三方(羽声语音直播关联公司不在此限)提供的个人信息,或外部第三方收集的您的个人信息,我们无法获取,更不会使用非常规方式(如:恶意干预对方系列APP数据)擅自以软件程序获得您的个人信息。羽声语音直播可能因业务发展的需要而确实需要从第三方间接收集(如共享等)您的个人信息的,且由我们直接或共同为您提供产品或服务的,我们会在收集前明确以书面形式要求该第三方说明其个人信息来源,以及是否已经就其收集、处理以及向我们提供您的个人信息取得了您的合法授权(如果使用方式和范围超出您在第三方原授权范围的,我们会再次征得您的授权同意)。我们的某些产品或服务由第三方业务合作伙伴提供或共同提供时,为了必要且合理的开展业务,我们可能会从部分业务合作伙伴处间接收集的您的部分信息、其他方使用我们的产品/服务时所提供有关您的信息。如果第三方的授权范围无法涵盖我们的处理和使用目的时,我们会自行或者要求该第三方征得您的同意后再行处理您的个人信息。
3、如果某一需要收集您的个人信息的产品/服务未能在本隐私政策中予以说明的,或者我们超出了与收集您的个人信息时所声称的目的及具有直接或合理关联范围的,我们将在收集和使用您的个人信息前,通过更新本隐私政策、页面提示、弹窗、站内信、网站公告或其他便于您获知的方式另行向您说明,并为您提供自主选择同意的方式,且在征得您明示同意后收集和使用。
4、征得授权同意的例外
您理解并同意,在以下情况下,我们无需取得您的授权同意即可收集和使用您的个人信息:
(1)与国家安全、国防安全有关的;
(2)与公共安全、公共卫生、重大公共利益有关的;
(3)与犯罪侦查、起诉、审判和判决执行等有关的;
(4)出于维护个人信息主体或其他个人的生命、财产等重大合法权益但又很难得到您本人同意的;
(5)所收集的个人信息是您自行向社会公众公开的;
(6)从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道,并依照《个人信息保护法》规定在合理的范围内处理您自行公开或者其他已经合法公开的个人信息;
(7)根据您的要求签订合同所必需的;
(8)用于维护所提供的产品或服务的安全稳定运行所必需的,例如发现、处置产品或服务的故障;
(9)为合法的新闻报道所必需的;
(10)学术研究机构基于公共利益开展统计或学术研究所必要,且对外提供学术研究或描述的结果时,对结果中所包含的个人信息进行去标识化处理的;
(11)法律法规规定的其他情形。
我们需要特别提醒您的是:由于我们的产品和服务较多,为您提供的内容也不同,因此收集的您的个人信息也会因产品/服务的内容不同而有所区别,具体以产品/服务实际提供为准。我们可能会不时推出新的或优化后的功能,或者依据最新法律法规要求,可能需要收集、使用您的新的个人信息或变更个人信息使用目的或方式。届时,我们将通过更新本政策、弹窗、页面提示等方式另行向您说明并为您提供自主选择同意的方式,且在征得您同意后再收集、使用。
三、我们如何使用Cookie和第三方H5页面
为使您获得更轻松的访问体验,您使用羽声语音直播产品或服务时,我们可能会通过采用各种技术收集和存储您访问羽声语音直播服务的相关数据,在您访问或再次访问羽声语音直播服务时,我们能识别您的身份,并通过分析数据为您提供更好更多的服务。包括使用小型数据文件识别您的身份,这么做是为了解您的使用习惯,帮您省去重复输入账户信息的步骤,或者帮助判断您的账户安全。这些数据文件可能是Cookie、Flash Cookie,或您的浏览器或关联应用程序提供的其他本地存储(统称“Cookie”)。
网页上常会包含一些电子图像,称为“单像素GIF文件”或“网络beacon”,它可以帮助网站计算浏览网页的用户或访问某些cookie。我们会通过网络beacon收集您浏览网页活动信息,例如您访问的页面地址、您先前访问的援引页面的位址、您停留在页面的时间、您的浏览环境以及显示设定等。
如果您的浏览器或浏览器附加服务允许,您可以修改对Cookie的接受程度或者拒绝羽声语音直播的Cookie(如:在浏览器具备该功能的前提下,可以通过您的浏览器的设置以管理、部分或全部拒绝Cookie与/或同类技术;或删除已经储存在您的计算机、移动设备或其他装置内的Cookie与/或同类技术,从而实现我们无法全部或部分追踪您的个人信息。您如需详细了解如何更改浏览器设置,请具体查看您使用的浏览器的相关设置页面),但拒绝羽声语音直播的Cookie可能无法使用由我们提供的、依赖于Cookie的功能或服务(如有)。
第三方H5页面。为了提升服务便捷性、方便用户快速触达第三方服务,我们可能会接入第三方的H5服务页面入口,如果您进入这些H5页面,该第三方可能会收集你的手机号、身份证件号、付款账号信息,请注意,您在以上第三方H5页面进行的各项操作请遵守该等第三方的隐私保护政策。当您离开我们平台跳转至第三方H5页面时,我们提醒您注意保护个人隐私。本平台不收集、不存储您在该类第三方服务页面填写和提交的任何个人信息。
四、我们如何共享、转让、公开披露您的个人信息
(一)共享
我们不会与西安熙晟文化传媒有限公司及关联方以外的任何公司、组织和个人分享您的个人信息,但以下情况除外:
1、获得您(及监护人)明确同意或授权的共享;
2、基于法定情形提供。根据法律法规的规定、诉讼争议解决需要、您与我们签署的相关协议(包括在线签署的电子协议及平台规则)或法律文件,或行政、司法等有权机关依法提出要求时,我们可能会共享您的个人信息;
3、提供统一管理服务。为便于您统一管理账号,体验更优质的服务,我们可能会向我们的关联公司共享您的个人信息。但我们只会共享必要的个人信息,如果我们共享您的个人敏感信息或者关联方改变个人信息的使用目的,将再次征求您的授权同意;
4、提供必要的合作服务并保证服务安全、优化。我们提供的产品/服务大多是无法单独完成的,故我们的某些服务将由业务合作伙伴提供。为保障为您提供的服务顺利完成,我们可能会将您的个人信息共享给我们的合作伙伴,包括基础技术服务、支付服务、营销活动等的合作商、第三方商家、广告商等;同时,为了向您提供更完善、优质、安全的产品和服务,我们的应用中会嵌入授权合作伙伴的软件工具开发包(本政策中简称“SDK”)或其他类似的应用程序,我们的某些服务将由授权合作伙伴提供或使用第三方SDK相关技术为您提供服务。基于此,我们会与合作伙伴共享您的某些个人信息,或者第三方SDK会通过SDK方式收集您的个人信息,具体包括:
(1)第三方账号登录、内容分享。QQ、微信、新浪微博会通过SDK方式收集您的位置信息、网络信息(包括Wi-Fi信息)、设备标识信息(MAC地址、IMEI、IMSI)、运营商信息、外部存储设备信息,用于实现第三方账号授权登录、共享发布的内容及评论等信息。
(2)安全监测与风险防范。为了保障您的账号安全,避免您遭受欺诈、网络病毒、网络攻击等风险,为我们提供安全保障的合作伙伴会通过SDK方式收集与您有关的必要设备信息、日志信息,以及您的使用习惯和常用软件信息等来综合判断您的账号及交易风险,预防安全事件的发生。
(3)支付与结算功能。支付功能由与我们合作的第三方支付机构向您提供服务,基于此,支付宝、微信、银联会通过SDK方式收集您的手机号、设备信息识别码(包括IMSI)、位置信息、网络信息(包括Wi-Fi信息)、当前运行进程/获取运行中进程信息、屏幕参数、运营商信息,保证充值、消费、支付功能的正常使用,这些信息是支付功能所必需的信息,拒绝提供将导致您无法使用该功能。当您提现收入(如有)时,为了您能及时完成收入的结算与提现、依据法律规定完成税费缴纳,将由与您另行单独确认的第三方服务方向您提供结算、税费扣缴服务,基于此,我们会向该类第三方服务方共享您提现时主动提供的收款账户信息以及身份信息,具体信息详见第二节第(七)款。
(4)人脸识别。阿里云、腾讯云、字节跳动会通过SDK方式收集您的证件信息、设备标识信息、网络信息(包括Wi-Fi信息)、设备传感器信息、屏幕参数、应用列表,该等第三方获取的面部特征信息用于人脸核验,我们只获得核验结果,不保存您的面部特征信息。
(5)直播视频服务。声网、会通过SDK收集您的共享Wi-Fi信息、设备标识信息、地理位置信息、运营商信息、外部存储设备、当前运行进程/获取运行中进程信息、屏幕参数,并共享用户授予的读取/写入外置存储、位置权限、获取设备信息、相机/摄像头权限、读取手机/电话状态,用于聊天室内和IM音视频通话,图片上传、直播推流和直播回放功能等相关功能。
目前,我们接入的第三方服务商主要包括以下几种类型:
用于消息推送功能,包括手机厂商Push推送、特定事件提醒;
用于支付相关服务,包括订单支付、交易行为核验、收入结算、支付信息汇总统计;
用于在您同意的情况下获取设备位置权限、搜集设备信息和日志信息;
用于第三方授权服务,包括第三方账号登陆、将有关内容分享至第三方产品;
用于优化产品性能,包括提高硬件配网能力、降低服务器成本、功能热修复;
用于账号安全、产品加固相关服务,包括网络监测、域名解析、防劫持、防黑产、反作弊、加解密服务。
我们接入的部分第三方SDK可能会收集您的个人信息,如您在我们的服务中使用这类由第三方提供的服务时,您同意将由其直接收集和处理您的信息。我们会评估这类第三方服务收集个人信息的合法性、正当性、必要性,要求该等第三方对您的个人信息采取保护措施,并严格遵守相关法律法规与监管要求。您可以查看下方《语音接入第三方SDK目录》,了解我们主要接入的第三方SDK基本情况。
羽声语音直播接入第三方SDK目录
1) 支付宝服务
类型:唤起支付宝app完成支付收集
所涉信息:设备MAC地址,网络访问,获取WiFi状态,读取电话状态,写入外部存储
隐私政策链接:https://opendocs.alipay.com/open/54/cyz7do
2)QQ开放平台SDK
服务类型:QQ分享
收集所涉信息:设备标识信息、定位信息、地理位置、ANDROID_ID、ICCID、IMEI
隐私政策链接:https://connect.qq.com/index.html
3)微信开放平台SDK
服务类型:微信分享/微信登录/微信支付/微信客服
收集所涉信息:设备标识信息、定位信息、地理位置、ANDROID_ID、ICCID、IMEI
隐私政策链接:https://open.weixin.qq.com/
8)声网SDK
服务类型:提供实时音频
服务收集所涉信息:设备MAC地址,IP地址,网络访问,WIFI状态访问,设备信息,文件存储权限,麦克风权限
隐私政策链接:https://www.agora.io/cn/interactive-live-streaming-premium
9)腾讯云IM SDK
服务类型:提供即时通信(私聊、群聊、房间内公屏聊天)
所涉信息:设备MAC地址,IP地址,网络状态,文件存储权限,麦克风权限,相机权限
隐私政策链接:https://cloud.tencent.com/document/product/269/58094
10)ShareSDK
1、服务类型:社会化分享收集
所涉信息:我们采集设备标识符(IMEI/Mac/android ID/IDFA/OPENUDID/GUID、SIM 卡 IMSI 信息)以及社交账号公开信息,以便向目标设备以及指定社交账号分享消息。采集地理位置甄别分享通道,提供反作弊服务。
2、服务类型:友盟统计需要收集您的设备Mac地址、唯一设备识别码(IMEI/android ID/IDFA/OPENUDID/GUID/IP地址/SIM 卡 IMSI 信息)以提供统计分析服务,并通过地理位置校准报表数据准确性,提供基础反作弊能力。
3、服务类型:友盟推送收集所涉信息:设备信息(如IMEI/Mac/android ID/IDFA/OPENUDID/GUID、SIM卡 IMSI 信息)对用户进行唯一标识,以便进行消息推送。消息推送服务具备基础的反作弊功能,通过获取用户位置信息及IP地址,剔除作弊设备,甄别有效推送通道,提高消息推送的区域覆盖率,提高推送效果及报表数据准确性。
隐私政策链接:https://www.umeng.com/page/policy
11)腾讯Bugly
服务类型:定位反馈客户端异常、崩溃问题,更高效的修复解决异常收集所涉信息:日志信息(包括:第三方开发者自定义 日志、Logcat 日志以及 APP 崩溃堆栈信息)、设备 ID(包括:androidid 以及 idfv)、联网信息、系统名称、系统版本以及国家码
隐私政策链接:https://privacy.qq.com/document/preview/fc748b3d96224fdb825ea79e132c1a56
12)数美服务类型:用于风险控制和反欺诈、以保障账户和交易安全所涉信息:设备基本信息:设备品牌、设备制造商、设备型号、设备名称、设备系统类型及版本信息、设备基本配置、设备基本设置、设备环境、传感器信息(磁场、陀螺仪、加速度传感器)、SD卡信息,设备标识信息:AndroidID、IDFV(应用开发商标识符)、IDFA(广告标示符)、OAID(匿名设备标识符),设备网络信息:网络的接入形式、无线路由器标识(BSSID、SSID)及IP地址、周边WIFI列表、网络运营商信息、网络基站信息、网络连接状态;
隐私政策链接:https://www.ishumei.com/legal/cn/privacy.html;
14)阿里巴巴云计算
服务类型:实名认证
收集所涉信息:个人身份信息(真实姓名,身份证号),面部识别特征,读取短信, 联系,通话记录,位置信息,设备标识信息(IMEI、IMSI、AndroidID)
隐私政策链接:http://terms.aliyun.com/legal-agreement/terms/suit_bu1_ali_cloud/suit_bu1_ali_cloud201902141711_54837.html
15)⾳视频通话 TRTC
服务类型:提供即时通信语音通话(私聊、群聊、房间内公屏聊天)
所涉信息:设备MAC地址,IP地址,网络状态,文件存储权限,麦克风权限,相机权限
隐私政策链接:https://cloud.tencent.com/document/product/269/58094
自启动和关联启动说明:
为确保本应用处于关闭或后台运行状态下可正常接收到客户端推送的广播信息,本应用须使用(自启动)能力,将存在一定频率通过系统发送广播唤醒本应用自启动或关联启动行为,是因实现功能及服务所必要的。
请您知悉:(1)我们仅会出于合法、正当、必要、明确的目的共享您的个人信息,并且授权合作伙伴只能接触到其履行职责所需信息。同时,我们会与合作伙伴签署严格的保密协定,要求他们按照我们的说明、本政策以及其他任何相关的保密和安全措施来处理您的个人信息;(2)前述第三方合作伙伴为数据控制者,以其自己的名义获得您的同意以处理您的个人信息。合作方可能有其独立的隐私政策,我们建议您认真阅读并遵守第三方的隐私政策。如果您拒绝我们的合作方在提供服务时收集为提供服务所必需的个人信息,将可能导致您无法使用相应服务。
(二)转让
我们不会将您的个人隐私信息转让给任何公司组织和个人,但以下情况除外:
1、在获取明确同意的情况下共享:获得您的明确同意后,我们将与其分享您的个人隐私信息;
2、在涉及合并、收购、资产转让、破产清算时,你的个人信息有可能因此而被转移,如涉及个人隐私信息转让,我们将要求受让方继续受此政策约束并告知您受让方身份、联系方式,否则我们将要求受让方向您重新索取授权同意。
(三)公开披露
1、公开披露是指向社会或不特定人群发布信息的行为。我们仅在下列情形下,公开披露您的个人隐私信息:
(1)征得您明确的授权同意;
(2)基于国家法律法规的规定而对外披露;
(3)应国家司法机关及其他有关机关基于法定程序的要求而披露;
(4)为公共利益实施新闻报道、舆论监督等行为在合理的范围内公开的;
(5)为应对突发公共卫生事件,或在紧急情况下,为保护其他用户及第三方生命健康和财产安全而必须披露的,在该情况下我们将在紧急情况消除后及时告知您;
(6)应用户监护人合法要求而提供用户个人身份信息时;
(7)对违规账号、欺诈行为等进行处罚公告、公布中奖/获胜者等名单时脱敏展示相关信息等必要事宜而进行的必要披露。
2、对于公开披露的您的个人信息,我们会在收到公开披露申请后第一时间且审慎审查其正当性、合理性、合法性,并在公开披露时和公开披露后采取最严格个人信息安全保护措施和手段对其进行保护。
(四)共享、转让、公开披露个人信息时事先征得授权同意的例外
下述情形中,共享、转让、公开披露您的个人信息无需事先征得您的授权同意:
1、与国家安全、国防安全直接相关的;
2、与公共安全、公共卫生、重大公共利益直接相关的;
3、与犯罪侦查、起诉、审判和判决执行等直接相关的;或根据法律法规的要求、行政机关或公检法等有权机关的要求的;
4、出于维护您或其他个人的生命、财产等重大合法权益但又很难得到您本人同意的;
5、个人信息是您自行向社会公开的或者是从合法公开的渠道(如合法的新闻报道、政府信息公开等渠道)中收集到的;
6、根据与您签订和履行相关协议或其他书面文件所必需的;
7、法律法规等规定的其他情形。
请知悉,根据适用的法律,若我们对个人信息采取技术措施和其他必要措施进行处理,使得数据接收方无法重新识别特定个人且不能复原,则此类处理后数据的共享、转让、公开披露无需另行向您通知并征得您的同意。
五、我们如何存储和保护您的个人信息
(一)个人信息的存储
1、存储地点:我们会按照法律法规规定,将境内收集的用户个人信息存储于中华人民共和国境内。目前我们不会跨境传输或存储您的个人信息或向境外提供个人信息的场景。将来如需跨境传输或存储的,我们会单独向您明确告知信息出境的目的、接收方、使用方式和范围、安全保证措施等情况并征得您的同意。
2、存储期限:除非依据法律法规或双方约定,我们只会在为实现服务目的所必需的最短时间内留存您的个人信息,此外,我们或对您的相关信息保存至相关法律所规定的必要期限(例如,根据《电子商务法》规定:商品和服务信息、交易信息保存时间自交易完成之日起不少于三年;根据《网络安全法》规定:采取监测、记录网络运行状态、网络安全事件的技术措施,并按照规定留存相关的网络日志不少于六个月;根据《互联网用户公众账号信息服务管理规定》:互联网用户公众账号信息服务提供者应当记录互联网用户公众账号信息服务使用者发布内容和日志信息,并按规定留存不少于六个月)。
我们在判断前述期限的标准主要包括并以其中较长者为准:
A. 完成与您相关的服务目的、维护相应服务及业务记录、应对您可能的查询或投诉;
B. 保证我们为您提供服务的安全和质量;
C. 您是否同意更长的留存期限;
D. 是否存在保留期限的其他特别约定。
在超出保存期限后,我们会根据适用法律的要求删除或者匿名化处理您的个人信息,但法律有特殊要求的除外。
当我们的产品或服务发生停止运营的情况时,我们将以推送通知、公告等形式通知您,并在合理期限内删除您的个人信息或进行匿名化处理,法律法规另有规定的除外。
(二)个人信息的保护措施
数据传输方面,采用传输层安全协议等密码技术,通过Https等方式防止传输链路被嗅探、窃听截取风险,建立安全的隐私数据采集环境,保证数据采集的私密性和完整性。
数据存储方面,我们会通过安全的方式存储您的信息,包括本地存储(例如利用APP进行数据缓存)。我们只会在为实现服务目的所必需的时间内或法律法规规定的条件下存储您的个人信息。您可以自主选择删除观看历史、视频缓存、搜索记录等您在使用羽声语音APP服务时提供和产生的数据记录。
信息安全方面,我们努力为您的信息安全提供保障,以防止信息的泄露、丢失、不当使用、未经授权访问和披露等。我们使用多方位的安全保护措施,以确保您的个人信息保护处于合理的安全水平,包括技术保护手段、管理制度控制、安全体系保障等诸多方面。
数据访问和使用的安全控制方面,实施严格的数据权限控制机制,采取多重身份认证技术,并对能够处理您的信息的行为进行监控,避免数据被违规访问和未授权使用。
建立完整的审计机制,对数据生命周期的全流程进行监控与审计,防止您的个人信息遭遇未经授权的访问、公开披露、使用、修改、人为或意外的损坏或丢失。
其他可行的安全组织和管理措施:
1、在我们从第三方间接收集您的个人信息前,我们会明确以书面形式(如合作协议、承诺书)要求该第三方在已经取得您明示同意后收集以及处理(如共享等)个人信息,在书面协议层面要求第三方对个人信息来源的合法性和合规性作出承诺,如第三方有违反行为的,我们会明确要求对方承担相应法律责任;
2、在我们向业务合作伙伴共享您的个人信息前,我们会严格要求合作伙伴的信息保护义务与责任,并要求业务合作伙伴在合作前需与羽声语音直播签署关于数据安全的保护协议,一旦业务合作伙伴有任何违反协议的行为,将须承担相应法律责任;
3、我们建立了合理有效、科学健全的安全应急响应体系,明确了网络安全事件的分类分级标准、安全应急响应组织及职责,并根据安全事件的不同类型和级别制定了适当的应急响应预案,明确规范了安全事件的报告流程和应急响应处置流程。同时,我们还具备“羽声语音直播”安全应急响应中心,由专业的安全技术和运营团队负责维护,便于及时有效的响应、处置各类安全漏洞和突发事件,联合相关部门进行安全事件溯源和打击;
4、如不幸发生个人信息安全事件的,我们将按照法律法规的要求,及时向您告知安全事件的基本情况和可能的影响、我们已采取或将要采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施等。我们将及时将事件相关情况以邮件、信函、电话、推送通知等方式告知您,难以逐一告知个人信息主体时,我们会采取合理、有效的方式发布公告。
5、请您知悉并理解,互联网并非绝对安全的环境,我们强烈建议通过安全方式、使用复杂密码,协助我们保证您的账号安全。如发现自己的个人信息泄密,尤其是您自己的账户或密码发生泄露,请立即根据本政策文末中提供的联系方式联络我们,以便我们采取相应措施来保护您的个人信息安全。
六、您如何管理您的个人信息
您对您的个人信息享有以下权利:
(一)访问权
1、账号信息:您可以通过相关产品页面随时登陆您的个人账号,随时查询或访问您的账号中个人资料信息,包括:头像、昵称、星座、城市等。例如:“头像/昵称”信息在羽声语音直播APP中的访问路径为:我的—头像栏;在羽声语音直播微信小程序的访问路径为:我的->点击个人头像->点击头像右下角编辑icon可进入资料编辑页面。
2、使用信息:您可以通过相关产品页面随时查阅您的使用信息,包括:订单记录、浏览记录、动态记录等。例如:“浏览记录”信息在羽声语音直播APP和微信小程序中的访问路径为:我的—足迹;
3、财产信息:您可以通过羽声语音直播APP 我的-钱包,以及羽声语音直播微信公众号-钱包查阅;
4、其他信息:您也可以在【我的】-【帮助与反馈】-【个人信息收集清单】中集中查询您的网络身份标识和鉴权信息、身份信息、用户基本资料、个人财产信息、用户使用过程信息、设备信息、内容制作与发布。如您在访问过程中遇到操作问题或如需获取其他前述方法无法获知的个人信息内容,您可通过本政策第九节提供的方式联系我们,我们将在核实您的身份后在合理期限内向您提供,但法律法规另有规定或本政策另有约定的除外。
我们会按照如下规则进行个性化推荐或定向推送,并为您提供相应的退出机制:
我们会根据您的喜欢为您提供个性化的推广内容,
例如在主页推荐房间、派对 - 推荐;您可以通过“我的-设置-个性化推荐”-关闭。关闭后,您看到的相关内容以房间活跃值默认展示。
(二)复制权
若您需要复制我们收集的关于你本人的基本资料、身份信息的,您可通过本政策第九节提供的方式联系我们,我们将在核实您的身份后在合理期限内向您提供,或在技术可行的前提下根据您的请求将您的个人信息转移至指定的个人信息处理者,但法律法规另有规定或本政策另有约定的除外。
(三)更正/修改权
若您发现您提供给我们的个人信息存在登记错误、不完整或有更新的,您可在我们产品和/或服务中更正/修改您的相关个人信息。
1、对于您的部分个人信息,您可以按照相关功能页面的指引和设置在线进行更正/修改。例如“头像/昵称”信息更正/修改路径为:我的—头像栏—编辑资料;
2、对于您在行使上述权利过程中遇到的困难,或者其他可能目前无法向您提供在线自行更正/修改服务的,经过对您身份的验证,且更正/修改不影响信息的客观性和准确性的情况下,您有权对错误或不完整的信息作出更正或修改,或在特定情况下,尤其是数据错误时,通过我们公布的反馈与报错等措施将您的更正/修改申请提交给我们,或联系我们(联系方式:详见下文第九节),要求我们更正或修改您的数据,但法律法规另有规定的除外。但出于安全性和身份识别的考虑,您可能无法修改注册时提交的某些初始注册信息。
(四)删除权
1、对于您提供的部分个人信息,您可以自行通过我们提供的相关产品和服务的功能页面,主动删除您提供信息。例如:“头像/昵称”信息在羽声语音APP中的删除路径为:【我的-个人主页-资料】。您也可以自主删除您发布的视频、动态、图片等。一旦您删除后,我们即会对此类信息进行删除或匿名化处理,法律法规另有规定的除外。
2、在以下情形中,您可以通过本政策第九节提供的联系方式向我们提出删除个人信息的请求,但已做匿名化处理或法律法规另有规定的除外:
(1)如果我们处理个人信息的行为违反法律法规;
(2)如果我们收集、使用您的个人信息,却未征得您的明确同意;
(3)如果我们处理个人信息的行为严重违反了该政策;
(4)如果您主动注销了账号;
(5)当我们终止服务及运营时。
(五)撤回同意权
1、我们提供的产品或服务的部分功能需要获得您使用设备的相关权限(包括:位置、相机、麦克风等,详见本隐私政策第二节第(十二)条“我们获取的设备权限”,具体以产品实际获取的功能为准)。您可以在授权后随时撤回(或停止)对该权限的继续授权,包括通过您设备中的设置页面或羽声语音APP的相关路径(“我的-设置-隐私-隐私权限设置”)撤回相关授权。示例路径如下:
(1)位置的权限:您可通过【我的-设置-隐私-隐私权限设置-允许羽声语音直播访问位置信息】撤回同意;
(2)相机的权限:您可通过【我的-设置-隐私-隐私权限设置-允许羽声语音直播访问相机】撤回同意;
(3)麦克风的权限:您可通过【我的-设置-隐私-隐私权限设置-允许羽声语音直播访问相机】撤回同意;
(4)日历的权限:您可通过【我的-系统设置-系统权限管理】撤回同意。
2、就我们通过短信的方式向您发送的商业性服务信息,如果您不想收到此类信息,您可以通过联系我们(联系方式:详见下文第九节),或者通过编辑“T”或“TD”并回复短信进行退订,提请注意:我们不会就您申请退订额外收取任何费用,但可能会发生一定的通信或者网络费用,具体以通信运营商与您约定为准,退订成功后我们将不再向您发送此类型的短信。就我们通过您设备的系统通知向你推送的内容,如果您不想收到此类信息,你可选择在设备中关闭羽声语音直播的通知功能。
3、对于合作方使用或我们转让、公开披露您的个人信息,您可以通过我们的相关功能页面或联系我们、合作方,撤回您的授权,但法律法规另有规定或本隐私政策另有约定的除外。
4、您可以通过卸载羽声语音App的方式撤回我们通过当前设备对您的个人信息的收集能力。
5、当您收回同意后,我们将不再处理相应的个人信息。但您收回同意的决定,不会影响此前基于您的授权而开展的个人信息处理。当您更新APP版本后,未经您的明确同意,我们不会更改您之前设置的权限状态。
6、对于您无法直接通过上述路径改变授权同意或撤回同意的,您均可通过本政策第九节提供的方式联系我们进行处理,但法律法规另有规定或本政策另有约定的除外。
(六)注销权
我们向您提供账户注销的途径。在您符合国家相关法律法规规定及约定注销条件的情况下,可以通过本隐私政策预留的联系方式(详见下文第九节)或在线申请注销您的账户。
提请注意:当您注销账号后,您将无法再以该账号登录和使用我们的产品与服务;且该账号在羽声语音及旗下的其他产品与服务使用期间已产生的但未消耗完毕的权益及未来的预期利益等全部权益将被清除;该账号下的内容、信息、数据、记录等将会被删除或匿名化处理(但法律法规另有规定或监管部门另有要求的除外,如依据《中华人民共和国网络安全法》规定,您的网络操作日志将至少保留六个月的时间);羽声语音账号注销完成后,将无法恢复。更多关于羽声语音账号注销的流程、条件等事项请详见《帐号注销须知》。
如您在谨慎考虑后仍执意决定注销您的羽声语音直播账号的,您可以在您使用的我们的产品/服务的相关功能设置页面或根据操作指引向我们提交注销申请,羽声语音APP的在线申请注销路径为:【我的】-【设置】-【账号与安全】-【安全中心】-【注销账号】;羽声语音直播微信小程序可以选择通过上述羽声语音APP注销路径、联系客服或者通过本隐私政策第九节预留的联系方式申请注销。
在您主动注销账户之后,我们将停止为您提供产品或服务,根据适用法律的要求删除您的个人信息,或使其匿名化处理。
(七)约束信息系统自动决策
在某些业务功能中,我们可能仅依据信息系统、算法等在内的非人工自动决策机制做出决定。如果这些决定显著影响您的合法权益,您有权通过本政策第九节提供的联系方式要求我们做出解释并拒绝我们仅通过自动化决策的方式作出决定,我们也将在不侵害羽声语音直播商业秘密或其他用户权益、社会公共利益、国家利益的前提下做出合理解释、处理。
(八)我们对去世用户的个人信息保护
1. 羽声语音直播将根据《个人信息保护法》的相关规定保护死者个人信息。羽声语音用户(仅限自然人)去世后,其近亲属为了自身的合法、正当利益,可以通过本隐私政策第九节“联系我们”中公示的联系方式,对去世用户的相关个人信息行使查阅、复制、更正、删除等权利,但是去世用户生前另有安排的除外。
2. 您理解并确认,为了充分保护去世用户的个人信息权益,申请行使本条权利的去世用户近亲属需要根据羽声语音直播的指定流程或客服提示,提交去世用户的身份证明文件、死亡证明文件、申请人的身份证明文件、申请人与去世用户的亲属关系证明文件,并提供申请行使的权利种类、目的。更多关于去世用户的个人信息保护流程、条件等事项请联系在线客服。
(九)响应您的上述请求
如果您在行使上述权利、处置您的个人信息时有任何疑问,您均可以通过本隐私政策第九节中公示的联系方式与我们沟通解决。
为保障安全,当您提出前述请求时,您需要提供上述要求材料,或以其他方式证明您的身份,再处理您的请求,若您拒绝提供相应证明材料,我们将无法响应您的请求。我们将在15日内做出答复。在以下情形中,按照法律法规要求,我们将无法响应您的请求:
1、与国家安全、国防安全、国家利益有关的;
2、与公共安全、公共卫生、重大公共利益有关的;
3、与犯罪刑事侦查、起诉、立案、审判和执行判决等有关的;
4、有充分证据表明个人信息主体存在主观恶意串通妨碍第三人行使合法权益或滥用权利使其他个人、组织的合法权益受到严重损害的;
5、响应您的请求将导致您或其他个人、组织的合法权益受到严重损害的;
6、涉及商业秘密的。
七、未成年人保护
我们的产品、网站和服务主要面向成年人。您知悉,羽声语音直播将依赖用户提供的个人信息判断用户是否为未成年人。若您是未成年人,建议您及您的监护人仔细阅读本政策,并在征得您的监护人同意的前提下使用我们的产品或服务或向我们提供信息。对于经父母或监护人同意使用我们的产品或服务而收集未成年人个人信息的情况,我们只会在法律法规允许、父母或监护人明确同意或者保护未成年人所必要的情况下使用、共享、转让或披露此信息。
特别地,若您是14周岁以下的儿童,将适用《羽声语音儿童个人信息保护规则》,建议您及您的监护人仔细阅读《羽声语音儿童个人信息保护规则》,并在征得您的监护同意的前提下使用我们的产品或服务。
若您是未成年人的监护人,一旦发现未成年人虚报年龄注册账号的,可通过本政策第九节所述方式向我们提出中止/终止该未成年人的账号或者要求向该未成年人提供青少年保护服务模式下的产品与/或服务。为了验证请求方为未成年人的监护人,特别是当您作为监护人提出资金类申请时,我们可能需要您向我们提供被监护人以及监护人的身份证(正面及反面)复印件/扫描件一份、可证明法定监护关系的有效法律文件(如出生证明、户口本)以及监护人手机号码、收款账号信息(如需),以保障用户的账号与资金安全。我们在收到您的上述文件后,会及时审核其真实性和有效性,并请确保监护人的手机畅通,以便我们的专业客服联系您进一步核实身份(如需)。同时,我们将依法记录、保存验证身份信息及验证结果,这些信息仅供完成验证、争议解决服务之目的,或者其他法律法规所规定的用途,我们向您承诺,我们会以最大努力保障您的个人信息安全,未经您明示授权不会用作其他目的。以上信息包含您及您所监护的未成年人的个人敏感信息,您有权拒绝提供,但我们收集这些信息是为了调查事实与帮助您解决问题,如您拒绝提供上述信息,我们可能无法向您及时反馈投诉、申诉或咨询结果。
若您是未成年人的监护人,当您对您所监护的未成年人的个人信息保护有任何相关疑问时,请通过第九节“联系我们”中公示的联系方式与我们联系。
八、本政策的更新
为保证您能够获得更好的服务并应平台业务调整以及未来发展,本政策也会与时俱进随之更新。但在更新的同时,我们会以单独、明显的方式获取您的授权。
我们在应用程序、官方网站更新版本后或官方发出公告后以合理、适当、明显的方式提醒您相关内容的更新,以便您能更快了解您权利的更迭。
对于重大变更,我们还会提供更为显著的通知方式(我们会通过包括但不限于邮件、短信、公告、首页或在浏览页面做特别提示等方式,来向您表达政策的更新内容)。
本政策所指的重大变更包括但不限于:
(一)我们的服务模式发生重大变化。如处理个人信息的目的、处理的个人信息类型、个人信息的使用方式等;
(二)我们在所有权结构、组织架构等方面发生重大变化。如业务调整、破产并购等引起的所有者变更等;
(三)个人信息共享、转让或公开披露的主要对象发生变化;
(四)您参与个人信息处理方面的权利及其行使方式发生重大变化。
九、联系我们
如您对本政策(或您个人信息的相关事宜)有投诉、举报、意见或建议的,可以通过如下方式与我们(西安熙晟文化传媒有限公司)联系,我们将在15天内予以您答复:
1、羽声语音站内客服:【我的】-【在线客服】-输入“人工客服”进行咨询;
2、人工客服电话:17531991222
3、个人信息保护负责人电话:17531991222
4、我们还设立了个人信息保护专职部门,您可以写信至:陕西省西安市高新区天谷八路156号软件新城云汇谷A6西户2层201-2-275 法务合规部(收);邮编710000
十、其他
本政策的解释、执行及争议解决均适用中华人民共和国法律(不包括冲突法)。因本政策产生争议的,双方应首先友好协商,协商不成的,您同意通过被告所在地有管辖权的法院提起诉讼来寻求解决方案。
\ No newline at end of file
diff --git a/moduleUtil/src/main/assets/page_yongh.htm b/moduleUtil/src/main/assets/page_yongh.htm
new file mode 100644
index 00000000..b507e16e
--- /dev/null
+++ b/moduleUtil/src/main/assets/page_yongh.htm
@@ -0,0 +1,3 @@
+
+
+注册与服务协议
“用户注册与服务协议”用户协议是您(下称“用户”)与本平台之间签订的协议。本平台是一款语音网络社交工具。
1、重要须知
1.1、用户欲访问和使用本平台,必须事先认真阅读、充分理解本协议中各条款,包括免除或者限制本平台责任的免责条款及对用户的权利限制条款。如用户不同意本协议,则应拒绝使用或主动取消本平台提供的服务。若您使用第三方账号登录,也请您务必认真阅读本协议,您的使用行为将被视为对本协议的无条件完全接受。
1.2、特别提醒:请确认您具有完全民事行为能力,如您已年满18周岁,或您已年满16周岁且依靠自己的劳动收入作为主要生活来源,否则请您停止注册或使用本协议项下的服务。
1.3在用户接受本协议之后,此文本可能因国家政策、产品以及履行本协议的环境发生变化而进行修改,修改后的协议将发布在“本平台”所有产品(包含但不限于APP、网站、PC客户端)上。修改后的协议公布七日后即视为“本平台”已将协议修改内容通知用户。若用户对修改后的协议有异议的,请立即停止访问、使用“本平台”软件,若用户继续访问或使用,则视为对修改后的协议予以认可。
1.4、“本平台”目前向用户提供丰富的互联网服务,包括但不限于视频、语音通讯、在线游戏、聊天室等,如果某一特定服务有单独的协议、规则、指引,用户须遵守该单独的协议、规则和指引,用户接受其他的所有服务均应遵守本协议。
2、本平台账号注册规则
2.1本平台帐号注册资料包括但不限于用户的本平台帐号名称、头像、密码、注册或更新本平台帐号时输入的所有信息以及用户使用本平台各单项服务时输入的名称、头像等所有信息。
2.2 用户不得在注册资料中出现以下违法和不良信息:
(1)违反宪法或法律法规规定的;
(2)危害国家安全,泄露国家秘密,颠覆国家政权,破坏国家统一的;
(3)损害国家荣誉和利益的,损害公共利益的;
(4)煽动民族仇恨、民族歧视,破坏民族团结的;
(5)破坏国家宗教政策,宣扬邪教和封建迷信的;
(6)散布谣言,扰乱社会秩序,破坏社会稳定的;
(7)散布淫秽、色情、赌博、暴力、凶杀、恐怖或者教唆犯罪的;
(8)侮辱或者诽谤他人,侵害他人合法权益的;
(9)含有法律、行政法规禁止的其他内容的。
若用户提供给“本平台”的帐号注册资料不准确,不真实,含有违法或不良信息的,“本平台”有权不予注册,并保留终止用户使用“本平台”各项服务的权利。若用户以虚假信息骗取帐号注册或帐号头像、个人简介等注册资料存在违法和不良信息的,“本平台”有权采取通知限期改正、暂停使用、注销登记等措施。对于冒用关联机构或社会名人注册帐号名称的,“本平台”有权注销该帐号,并向政府主管部门进行报告。
根据相关法律、法规规定以及考虑到“本平台”服务的重要性,用户同意:
(1)主动提交个人有效身份信息进行实名认证;
(2)提供及时、详尽及准确的账户注册资料(姓名、手机号等);
(3)不断更新注册资料,符合及时、详尽准确的要求,对注册“本平台”帐号时填写的身份证件信息不能更新。
用户同意,其提供的真实、准确、合法的“本平台”帐号注册资料是作为认定用户与其“本平台”帐号的关联性以及用户身份的唯一证据。用户在享用“本平台”各项服务的同时,同意接受“本平台”提供的各类信息服务。“本平台”提醒用户,用户注册“本平台”帐号或更新注册信息时填写的证件号码,在注册“本平台”帐号成功或补充填写后将无法进行修改,请用户慎重填写各类注册信息。
为使用户及时、全面了解“本平台”公司提供的各项服务,用户同意,“本平台”可以多次、长期向用户发送各类商业性短信息而无需另行获得用户的同意。
用户同意与注册、使用“本平台”帐号相关的一切资料、数据和记录,包括但不限于“本平台”帐号、注册资料、所有登录、消费记录和相关的使用统计数字等归“本平台”所有。发生争议时,用户同意以“本平台”的系统数据为准,“本平台”保证该数据的真实性。
2.3对于用户使用“本平台”帐号而产生的一切数据,包括但不限于登录记录、消费记录、客户服务记录以及用户在使用“本平台”中创造的社会网络内容等,归“本平台”运营公司所有。发生争议时,用户同意以“本平台”的系统数据为准。
2.4 用户不得将其账号、密码转让或出借给他人使用。如因黑客行为或用户的保管疏忽导致账号、密码遭他人非法盗取、使用或遭受损失,“本平台”不承担任何责任;如给“本平台”造成损害,则用户应予赔偿。
2.5 如用户的“本平台”账户从最后一次登录次日起连续180天未登录,“本平台”有权采取包括但不限于注销、回收、替换或采取删除该用户账户在“本平台”平台数据库中的任何记录(包括但不限于注册信息、虚拟礼物信息等)等清理措施,“本平台”提供的相应服务同时终止。“本平台”在对此类账户进行清理前30天(“通知期限”),将采取包括但不限于弹窗、网站公告、站内消息、客户端推送信息等方式通知该用户。若用户在收到通知且在通知期限内不采取“本平台”认可的方式重新激活账号,则视为自动放弃对该账户及账户所包含的信息和虚拟资产包括但不限于数据、虚拟礼物信息、虚拟资产等的主张、追索和赔偿的权利。
2.6 特别提示:用户只可使用中华人民共和国法定货币(即人民币/¥)向“本平台”平台进行充值,并兑换为平台虚拟货币“金币”使用;“金币”仅可在“本平台”平台购买虚拟道具或参与平台活动使用,不可兑换为人民币或实物奖励。
3、平台服务规则与用户行为守则
3.1 用户在使用本软件时,不得出现以下《网络表演经营活动管理办法》中规定的禁止行为:
3.1.1含有《互联网文化管理暂行规定》第十六条规定的禁止内容的;
3.1.2表演方式恐怖、残忍、暴力、低俗,摧残表演者身心健康的;
3.1.3利用人体缺陷或者以展示人体变异等方式招徕用户的;
3.1.4以偷拍偷录等方式,侵害他人合法权益的;
3.1.5以虐待动物等方式进行表演的;
3.1.6使用未取得文化行政部门内容审查批准文号或备案编号的网络游戏产品,进行网络游戏技法展示或解说的。
如“本平台”发现用户出现以上情形,用户同意并接受“本平台”根据对其采取包括但不限于暂停直播服务、封停账户、扣除虚拟道具、扣除金币、封禁设备等处罚措施。
3.2 用户不得利用本软件的服务制作、复制、发布、传播、存储含有下列淫秽色情类信息,包括但不限于:
3.2.1散布淫秽、色情内容,包括但不限于招嫖、寻找一夜情、性伴侣、磕音、连麦陪睡等内容;
3.2.2色情擦边、性暗示类信息内容,以此来达到吸引用户的目的;
3.2.3 以色情为目的的青色语音、情色文字、情色视频、情色漫画等内容,但不限于上述形式。
如果用户违反了本条约定,“本平台”将根据用户的违法违规的具体情况,有权对违法违规用户做出包括但不限于冻结账号、永久封禁账号、封禁设备、扣除虚拟道具、扣除金币等处罚。3.3 用户不得利用本软件的服务制作、复制、发布、传播、存储含有下列暴力赌博类信息,包括但不限于:
3.3.1散播人或动物被杀、致残以及枪击、刺伤、拷打等受伤情形的真实内容;
3.3.2出现描绘暴力、自残等内容;
3.3.3涉及令人不安的血腥场景描绘的;
3.3.4出现以鼓励非法或鲁莽使用方式等为目的而描述真实武器的内容;
3.3.5发送组织聚众赌博、出售赌博器具、传授赌博(千术)技巧、方式、方法等内容;
3.3.6宣传违背人性道德的血腥暴力内容。
如果用户违反了本条约定,“本平台”将根据用户的违法违规的具体情况,有权对违法违规用户做出包括但不限于如下处罚:若用户第一次违反上述规定,则“本平台”将对该用户做出冻结账号24小时的处罚;若该用户第二次违反上述规定,则“本平台”将对该用户做出冻结账号3天的处罚;若该用户第三次违反上述规定,则“本平台”将对该用户做出冻结账号15天的处罚;若该用户第四次违反上述规定,则“本平台”将对该用户做出永久冻结账号的处罚。若经“本平台”判定该用户违法违规情节严重,则“本平台”有权在该用户第一次违反上述规定时,直接对该用户做出永久冻结账号或封禁设备的处罚。
3.4未经“本平台”授权,用户不得利用本软件的服务制作、复制、发布、传播、存储含有下列广告宣传类信息,包括但不限于:
3.4.1宣传其他平台、商品、店铺言论和图片的;
3.4.2留微信号、QQ号、手机号等引导到其他平台,涉嫌诈骗、非法获利广告行为的;
3.4.3宣传主播在“本平台”或其他直播平台的账号/频道号/房间号、求土豪包养、求送花等,引导到产品内其他版块广告行为等;
3.4.4发送宣传国家明令禁止或未取得国家行政许可销售的产品内容;
3.4.5发送宣传虚假人气以及其他不符合平台刷房/刷虚拟道具规则,出售代刷房间,个人关注软件等不正当牟利内容;
3.4.6发送组织、宣传网络兼职内容;
3.4.7恶意诋毁“本平台”平台,恶意扰乱平台规则等行为。
如果用户违反了本条约定,“本平台”将根据用户的违法违规的具体情况,有权对违法违规用户做出包括但不限于如下处罚:若用户第一次违反上述规定,则“本平台”将对该用户做出冻结账号24小时的处罚;若该用户第二次违反上述规定,则“本平台”将对该用户做出冻结账号3天的处罚;若该用户第三次违反上述规定,则“本平台”将对该用户做出冻结账号15天的处罚;若该用户第四次违反上述规定,则“本平台”将对该用户做出永久冻结账号的处罚。若经“本平台”判定该用户违法违规情节严重,则“本平台”有权在该用户第一次违反上述规定时,直接对该用户做出永久冻结账号或封禁设备的处罚。
3.5 用户不得利用本软件的服务制作、复制、发布、传播、存储含有下列违反网络道德行为的内容,包括但不限于:
3.5.1恶意骚扰用户的,尤其是女性用户;
3.5.2污言秽语、侮辱他人、诽谤他人、人身攻击的;
3.5.3恶意灌水、刷屏,恶意重复评论、发表与社区氛围明显不符的内容或言论的;
3.5.4涉及泄露他人隐私信息、侵害他人合法权益的;
3.5.5发布明显不符合聊天室主题、规范内容的;
3.5.6其他侵害他人合法权益行为的。
如果用户违反了本条约定,“本平台”将根据用户的违法违规的具体情况,有权对违法违规用户做出包括但不限于如下处罚:若用户第一次违反上述规定,则“本平台”将对该用户做出冻结账号24小时的处罚;若该用户第二次违反上述规定,则“本平台”将对该用户做出冻结账号3天的处罚;若该用户第三次违反上述规定,则“本平台”将对该用户做出冻结账号15天的处罚;若该用户第四次违反上述规定,则“本平台”将对该用户做出永久冻结账号的处罚。若用户违法违规情节严重,则“本平台”有权在该用户第一次违反上述规定时,直接对该用户做出永久冻结账号或封禁设备的处罚。
3.6用户理解并同意,“本平台”向用户提供相关服务,是为了让用户体验丰富多彩的网络服务内容,而非利用该服务赚取现实世界的金钱或牟取经济利益。因此,用户承诺不以营利为目的从事网络表演服务,任何以营利为目的从事表演服务的行为将被视为牟取不正当利益,包括但不限于用户:
3.6.1同一用户(指同一手机、同一身份证号、同一设备号、同一IP)利用多个用户帐号,以营利为目的刷主播人气、刷虚拟道具等;
3.6.2事先允诺“好处费”或“返利”,要求其他用户为自己账号刷人气、刷虚拟道具等;
3.6.3在非“本平台”提供或认可的交易平台上交易用户帐号或虚拟物品获利;
3.6.4通过盗号、骗取账号密码等手段,出售他人用户账号或虚拟物品获利;
3.6.5其他任何不以正常的娱乐互动需要为目的的牟利行为。
“本平台”有权对牟取不正当利益的用户同时采取包括但不限于暂停直播服务、封停账户、扣除虚拟道具、扣除金币、封禁设备等处罚措施,如给“本平台”造成损失的,“本平台”有权要求赔偿。
3.7 除上述3.1-3.6条外,“本平台”将不定期在“本平台”官方平台及客户端发布具体运营规则(如《本平台社区规范》等),用户同意将一并遵守以上运营规则。如用户违反相关运营规则,用户同意并接受“本平台”以具体运营规则为依据,对其采取包括但不限于暂停直播服务、封停账户、扣除虚拟道具、扣除金币等处罚措施。
3.8如用户在使用聊天室等服务过程中出现侵犯第三方合法权益的行为,均由用户自行承担相应责任,“本平台”无需要承担任何责任。若因用户侵权行为导致“本平台”遭受第三方的侵权指控时,用户应承担“本平台”在应对该等指控所支付的所有费用(包括但不限于律师费、诉讼费、差旅费等费用),“本平台”因此承担侵权赔偿责任的,有权向用户追偿。
3.9用户不得对本软件进行反向工程、反向汇编、反向编译;不得使用第三方插件干扰、修改、破坏本软件;不得利用软件可能存在的bug或规则漏洞谋取不正当利益。
4、告知声明
4.1用户已知悉:用户在使用“本平台”服务时可能遭受来自“施害人”恶意发布、实施的包括但不限于带有威胁性的、诽谤性的、令人反感的或非法的内容的侵扰,或用户的合法权利(包括但不限于知识产权、虚拟资产等)遭受“施害人”无论采用匿名的或冒名的方式的侵犯,用户承诺由其无条件承担以上风险,并且豁免对 “本平台”的任何索赔主张。“本平台”对所提供的服务不作担保,不论是明确的或隐含的,包括所有有关信息真实性、适商性、适于某一特定用途、所有权和非侵权性的默示担保和条件,对因此导致任何因用户不正当或非法使用服务产生的直接、间接、偶然、特殊及后续的损害,不承担任何责任。
4.2用户使用“本平台”服务必须遵守国家有关法律和政策等,维护国家利益,保护国家安全,并遵守本条款,对于用户违法或违反本协议的使用(包括但不限于言论发表、传播等)而引起的一切责任,由用户负全部责任。
4.3 “本平台”的服务同大多数因特网(INTERNET)产品一样,易受到各种安全问题的困扰,包括但不限于:
4.3.1 用户的详细个人资料被不法分子非法取得并利用,造成现实生活中的骚扰;
4.3.2 哄骗、破译密码;
4.3.3 下载安装的其它软件中含有“特洛伊木马”等病毒,威胁到个人计算计上信息和数据的安全,继而威胁对本服务的使用。对于发生上述情况的,用户应当自行承担责任。
4.4用户理解,因互联网技术的不稳定性、政府政策管制、病毒入侵、黑客攻击、服务器系统崩溃或者其他现今技术无法解决的风险的发生可能导致“本平台”服务中断或帐号道具损失,若因上述原因导致用户的任何损失,用户承诺该等损失由用户自行承担,且用户无条件放弃因上述原因发生而对 “本平台”的任何索赔的主张。
4.5 “本平台”不对发布在本网站上的广告或信息的效果、宣传、信息准确性做出保证,用户在接触这些广告或信息时应谨慎自行判断,且用户承诺:用户因使用本网站上发布的广告或信息而遭受的任何损失由用户与发布者协商解决,用户无条件放弃对“本平台”采取上述主张的权利。
4.6用户同意“本平台”向其接收信息的装置或软件包括但不限于固定电话、移动电话、电子邮箱、QQ、微博、微信等发送服务信息和商业性广告。
4.7 用户在使用“本平台”服务过程中,因其他用户行为遭遇的任何纠纷和/或损失,原则上由用户自行解决并承担相应的责任,与“本平台”无关。
5、知识产权
5.1本平台对下述内容拥有完整和全部的知识产权:“本平台”的文字、图片、视频、音频、软件等元素,“本平台”服务标志、标识以及专利权。
5.2用户只能在本协议以及相应的授权许可协议授权的范围(“知识产权的使用范围”)使用“本平台”的知识产权,未经授权超越“知识产权的使用范围”的使用即构成对“本平台”知识产权的侵权,“本平台”对此等侵权行为有权采取包括但不限于警告、诉讼、仲裁等措施来维护自身合法权益。
5.3用户在使用“本平台”服务时上传、发布的文字、图片、视频、软件以及表演等用户原创的信息,上述信息的知识产权归用户所有,但用户同意其在“本平台”平台上发表、上传的行为是对“本平台”服务平台的授权,用户确认其发表、上传的信息的非独占性,同时是对“本平台”的永久性的授权,该授权可转授权。“本平台”可将前述信息在“厦门本平台”旗下的服务平台上免费使用,也可再次编辑后免费使用,也可以由“本平台”授权给合作方使用。
5.4若“本平台”软件内的信息以及其他用户上传、存储、传播的信息存在侵犯第三人知识产权的情形,被侵权人可以向“本平台”提供的投诉通道进行投诉举报,“本平台”将有权采取合理措施对上述侵权行为做出处置。
6、收费服务
6.1 “本平台”部分功能或应用涉及付费,用户点击同意/确认本协议的行为视为对收费服务的接受并订阅,用户一旦接受订阅收费服务,则需要按本平台公示的收费标准支付相应费用。
6.2 用户在进行消费时,请事先了解消费价格及事项;如您是未成年人,请在监护人的认可后进行消费。
6.3 用户付费后获得的权益不得转让给第三人。
7.隐私保护
7.1请用户注意勿在使用“本平台”服务中透露自己的各类财产帐户、银行卡、信用卡、第三方支付账户及对应密码等重要信息、资料,否则由此带来的任何损失由用户自行承担。
\ No newline at end of file
diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/activity/BaseAppCompatActivity.java b/moduleUtil/src/main/java/com/xscm/moduleutil/activity/BaseAppCompatActivity.java
index ac94e260..ce6fe4a2 100644
--- a/moduleUtil/src/main/java/com/xscm/moduleutil/activity/BaseAppCompatActivity.java
+++ b/moduleUtil/src/main/java/com/xscm/moduleutil/activity/BaseAppCompatActivity.java
@@ -114,12 +114,13 @@ public abstract class BaseAppCompatActivity extends
}
QXGiftDriftView qxGiftDriftView;
-
+ protected void doDone(){}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().getDecorView().setBackgroundResource(R.mipmap.log_bj);
setContentView(getLayoutId());
+ doDone();
// 隐藏标题栏
if (getSupportActionBar() != null) {
getSupportActionBar().hide();
diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/activity/BaseMvpActivity.java b/moduleUtil/src/main/java/com/xscm/moduleutil/activity/BaseMvpActivity.java
index 8e9699d2..d9e5f455 100644
--- a/moduleUtil/src/main/java/com/xscm/moduleutil/activity/BaseMvpActivity.java
+++ b/moduleUtil/src/main/java/com/xscm/moduleutil/activity/BaseMvpActivity.java
@@ -50,7 +50,10 @@ public abstract class BaseMvpActivity() {
-// RetrofitClient.getInstance().roomGetIn(roomId, password, new BaseObserver() {
-//
-// @Override
-// public void onSubscribe(Disposable d) {
-// }
-//
-// @Override
-// public void onNext(RoomInfoResp resp) {
-// String appId = CommonAppContext.getInstance().getCurrentEnvironment().getSwSdkAppId();
-// String token = resp.getUser_info().getAgora_token(); // 如果启用了鉴权才需要
-// String roomId = resp.getRoom_info().getRoom_id(); // 房间 ID
-// String rtm_token=resp.getUser_info().getAgora_rtm_token();
-// SpUtil.setRtmToken(rtm_token);
-// int uid = SpUtil.getUserId(); // 0 表示由 Agora 自动生成 UID
-// boolean enableMic = false; // 是否开启麦克风
-// boolean enableJs=false; // 是否开启角色
-// if (resp.getUser_info().getPit_number()!=0){
-// enableJs=true;
-// }
-// LogUtils.e("token",token);
-// LogUtils.e("roomId:",roomId);
-//// 初始化 Agora 并加入房间
-// AgoraManager.getInstance(context)
-// .joinRoom(token, roomId, uid, enableMic,enableJs);
-// cacheRoomData(roomId, resp);
-// navigateToRoom(context, roomId, password, resp);
-// }
-// });
+ @Override
+ public void onSubscribe(Disposable d) {
+ }
+
+ @Override
+ public void onNext(RoomInfoResp resp) {
+ String appId = CommonAppContext.getInstance().getCurrentEnvironment().getSwSdkAppId();
+ String token = resp.getUser_info().getAgora_token(); // 如果启用了鉴权才需要
+ String roomId = resp.getRoom_info().getRoom_id(); // 房间 ID
+ String rtm_token = resp.getUser_info().getAgora_rtm_token();
+ SpUtil.setRtmToken(rtm_token);
+ int uid = SpUtil.getUserId(); // 0 表示由 Agora 自动生成 UID
+ boolean enableMic = false; // 是否开启麦克风
+ boolean enableJs = false; // 是否开启角色
+ if (resp.getUser_info().getPit_number() != 0) {
+ enableJs = true;
+ }
+ LogUtils.e("token", token);
+ LogUtils.e("roomId:", roomId);
+// 初始化 Agora 并加入房间
+ AgoraManager.getInstance(context)
+ .joinRoom(token, roomId, uid, enableMic, enableJs);
+ cacheRoomData(roomId, resp);
+ navigateToRoom(context, roomId, password, resp, false);
+ }
+ });
}
/**
@@ -323,18 +329,21 @@ public class RoomManager {
* @param roomInfo 房间信息
*/
private void navigateToRoom(Context context, String roomId, String password, RoomInfoResp roomInfo, boolean isOnline) {
+ LogUtils.dTag("RoomActivity", "navigateToRoom"+roomInfo.toString());
+
try {
// 构建跳转参数
Bundle bundle = new Bundle();
bundle.putString("roomId", roomId);
bundle.putBoolean("isOnline", isOnline);
-
+ bundle.putSerializable("roomInfo", roomInfo);
if (!TextUtils.isEmpty(password)) {
bundle.putString("password", password);
}
- if (roomInfo != null) {
-// bundle.putSerializable("roomInfo", roomInfo);
+ if (roomInfo == null){
+ LogUtils.dTag("RoomActivity", "navigateToRoom:房间信息获取存在问题");
+ return;
}
// 使用ARouter跳转到房间页面
diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/RoomMessageEvent.java b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/RoomMessageEvent.java
index f7fab608..19238090 100644
--- a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/RoomMessageEvent.java
+++ b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/RoomMessageEvent.java
@@ -90,7 +90,7 @@ public class RoomMessageEvent {
private String from_pit_number;
private String to_pit_number;
- private String gift_num;
+ private int gift_num;
private RedPacketInfo redpacketInfo;
private String redpacket_id;
diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/dialog/PolicyDialog.java b/moduleUtil/src/main/java/com/xscm/moduleutil/dialog/PolicyDialog.java
index 1b25b798..7c313c70 100644
--- a/moduleUtil/src/main/java/com/xscm/moduleutil/dialog/PolicyDialog.java
+++ b/moduleUtil/src/main/java/com/xscm/moduleutil/dialog/PolicyDialog.java
@@ -1,6 +1,7 @@
package com.xscm.moduleutil.dialog;
import static com.blankj.utilcode.util.ActivityUtils.startActivity;
+import static com.tencent.qcloud.network.sonar.utils.Utils.isNetworkAvailable;
import android.app.Dialog;
import android.content.Context;
@@ -46,10 +47,26 @@ public class PolicyDialog extends Dialog {
ClickableSpan clickSpan = new ClickableSpan() {
@Override
public void onClick(@NonNull View widget) {
- Intent intent = new Intent(getContext(), WebViewActivity.class);
- intent.putExtra("url", CommonAppContext.getInstance().getCurrentEnvironment().getServerUrl()+"/api/Page/page_show?id=6");
- intent.putExtra("title", "用户协议");
- startActivity(intent);
+// Intent intent = new Intent(getContext(), WebViewActivity.class);
+// intent.putExtra("url", CommonAppContext.getInstance().getCurrentEnvironment().getServerUrl()+"/api/Page/page_show?id=6");
+// intent.putExtra("title", "用户协议");
+// startActivity(intent);
+// ARouter.getInstance().build(ARouteConstants.H5).withString("url", "file:///android_asset/page_yongh.html").withString("title", "用户协议").navigation();
+
+ // 检查网络连接状态
+ if (isNetworkAvailable(getContext())) {
+ // 有网络时加载网络资源
+ Intent intent = new Intent(getContext(), WebViewActivity.class);
+ intent.putExtra("url", CommonAppContext.getInstance().getCurrentEnvironment().getServerUrl()+"/api/Page/page_show?id=6");
+ intent.putExtra("title", "用户协议");
+ startActivity(intent);
+ } else {
+ // 无网络时加载本地资源
+ ARouter.getInstance().build(ARouteConstants.H5)
+ .withString("url", "file:///android_asset/page_yongh.html")
+ .withString("title", "用户协议")
+ .navigation();
+ }
// ARouter.getInstance().build(ARouteConstants.H5).withString("url", CommonAppContext.getInstance().getCurrentEnvironment().getServerUrl()+"/api/Page/page_show?id=6" ).withString("title", "用户协议").navigation();
}
@@ -63,11 +80,20 @@ public class PolicyDialog extends Dialog {
ClickableSpan ysClickSpan = new ClickableSpan() {
@Override
public void onClick(@NonNull View widget) {
- Intent intent = new Intent(getContext(), WebViewActivity.class);
- intent.putExtra("url", CommonAppContext.getInstance().getCurrentEnvironment().getServerUrl()+"/api/Page/page_show?id=4");
- intent.putExtra("title", "隐私协议");
- startActivity(intent);
+// Intent intent = new Intent(getContext(), WebViewActivity.class);
+// intent.putExtra("url", CommonAppContext.getInstance().getCurrentEnvironment().getServerUrl()+"/api/Page/page_show?id=4");
+// intent.putExtra("title", "隐私协议");
+// startActivity(intent);
+// ARouter.getInstance().build(ARouteConstants.H5).withString("url", "file:///android_asset/page_show.html").withString("title", "隐私协议").navigation();
+ if (isNetworkAvailable(getContext())) {
+ Intent intent = new Intent(getContext(), WebViewActivity.class);
+ intent.putExtra("url", CommonAppContext.getInstance().getCurrentEnvironment().getServerUrl()+"/api/Page/page_show?id=4");
+ intent.putExtra("title", "隐私协议");
+ startActivity(intent);
+ }else {
+ ARouter.getInstance().build(ARouteConstants.H5).withString("url", "file:///android_asset/page_show.html").withString("title", "隐私协议").navigation();
+ }
// ARouter.getInstance().build(ARouteConstants.H5).withString("url", CommonAppContext.getInstance().getCurrentEnvironment().getServerUrl()+"/api/Page/page_show?id=4").withString("title", "隐私协议").navigation();
}
diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/dialog/giftLottery/TourClubDialogFragment.java b/moduleUtil/src/main/java/com/xscm/moduleutil/dialog/giftLottery/TourClubDialogFragment.java
index 0872f8bf..6567a74b 100644
--- a/moduleUtil/src/main/java/com/xscm/moduleutil/dialog/giftLottery/TourClubDialogFragment.java
+++ b/moduleUtil/src/main/java/com/xscm/moduleutil/dialog/giftLottery/TourClubDialogFragment.java
@@ -421,7 +421,7 @@ public class TourClubDialogFragment extends BaseMvpDialogFragment()).subscribe(observer);
} else if (ranking_type.equals("1") || ranking_type.equals("2")) {
sApiServer.wealthRanking(ranking_type, type).compose(new DefaultTransformer<>()).subscribe(observer);
- } else if (ranking_type.equals("3")) {
- sApiServer.guildRanking().compose(new DefaultTransformer<>()).subscribe(observer);
- } else if (ranking_type.equals("4")) {
+ }else if (ranking_type.equals("3")) {
sApiServer.loveRanking(type).compose(new DefaultTransformer<>()).subscribe(observer);
}
+ else if (ranking_type.equals("4")) {
+ sApiServer.guildRanking().compose(new DefaultTransformer<>()).subscribe(observer);
+ }
}
public void dailyTasksBoxRecord(BaseObserver> observer) {
diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/utils/config/EnvironmentEnum.java b/moduleUtil/src/main/java/com/xscm/moduleutil/utils/config/EnvironmentEnum.java
index d252176c..e0884499 100644
--- a/moduleUtil/src/main/java/com/xscm/moduleutil/utils/config/EnvironmentEnum.java
+++ b/moduleUtil/src/main/java/com/xscm/moduleutil/utils/config/EnvironmentEnum.java
@@ -1,6 +1,7 @@
package com.xscm.moduleutil.utils.config;
public enum EnvironmentEnum {
+// "https://vespa.qxyushen.top/",
PRODUCTION(//生产环境
"https://vespa.qxyushen.top/",
"KvNmqZc+VMzO4CfGMd5zmG6w6OFwpFO/19TwXUWfHDOBgmnl9DgIuE+kbrjNNnxqhtP3pH7bBrnSaSeFtunr72q6sgpLsfuswcUroMvz2slaTBcNzCaLi+GSnM3gB/GdO47mwLdk+iYBTvPUOCIuT608Z29z09w+vPeUDoMCHJBGXu6uh7Nj6PtV1dfGoUvByk1ZF0WYVjIqKDcb3tXY4jonFh3XAWhzMy8xKwN6F2nuK2IcdIwaSPsvuMZmhatP6f9kOE+vnfweyCHS3RxiG474WIoZGJM8omrl3/pOVqE=",
diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/utils/roomview/GiftDisplayManager.java b/moduleUtil/src/main/java/com/xscm/moduleutil/utils/roomview/GiftDisplayManager.java
index 996cbba6..cd992fdf 100644
--- a/moduleUtil/src/main/java/com/xscm/moduleutil/utils/roomview/GiftDisplayManager.java
+++ b/moduleUtil/src/main/java/com/xscm/moduleutil/utils/roomview/GiftDisplayManager.java
@@ -118,6 +118,8 @@ public class GiftDisplayManager {
// 处理队列
processGiftQueue();
+ // 确保每次接收礼物后都处理队列
+ mainHandler.postDelayed(this::processGiftQueue, 50);
}
private GiftDisplayView findDisplayingViewForGift(GiftBean gift) {
@@ -141,11 +143,12 @@ public class GiftDisplayManager {
private void processGiftQueue() {
if (isProcessingQueue) {
+ Log.d("GiftDisplayManager", "Already processing queue, skip");
return;
}
isProcessingQueue = true;
-
+ Log.d("GiftDisplayManager", "Start processing queue, size: " + giftQueue.size());
// 循环处理队列直到队列为空或没有可用视图
while (!giftQueue.isEmpty()) {
GiftDisplayView availableView = findAvailableDisplayView();
@@ -195,7 +198,8 @@ public class GiftDisplayManager {
}
// 延迟一下再处理队列,确保视图状态完全重置
- mainHandler.postDelayed(this::processGiftQueue, 100);
+ // 立即处理队列,而不是延迟
+ mainHandler.post(this::processGiftQueue);
}
public void clearAll() {
diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/AdaptiveImageView.java b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/AdaptiveImageView.java
new file mode 100644
index 00000000..a93b63bd
--- /dev/null
+++ b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/AdaptiveImageView.java
@@ -0,0 +1,63 @@
+package com.xscm.moduleutil.widget;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.Log;
+import androidx.appcompat.widget.AppCompatImageView;
+import com.xscm.moduleutil.R;
+
+/**
+ * com.xscm.moduleutil.widget
+ * qx
+ * 2025/10/24
+ * 自适应图片展示
+ */
+public class AdaptiveImageView extends AppCompatImageView {
+ public AdaptiveImageView(Context context) {
+ super(context);
+ }
+
+ public AdaptiveImageView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public AdaptiveImageView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ Log.d("DebugImageView", "=== onMeasure START ===");
+ Log.d("DebugImageView", "widthMeasureSpec: " + MeasureSpec.toString(widthMeasureSpec));
+ Log.d("DebugImageView", "heightMeasureSpec: " + MeasureSpec.toString(heightMeasureSpec));
+
+ // 先调用父类测量
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+ Log.d("DebugImageView", "After super - Width: " + getMeasuredWidth() + ", Height: " + getMeasuredHeight());
+
+ Drawable drawable = getDrawable();
+ if (drawable != null) {
+ Log.d("DebugImageView", "Drawable - Width: " + drawable.getIntrinsicWidth() + ", Height: " + drawable.getIntrinsicHeight());
+ }
+
+ // 强制设置为最小尺寸,确保不会太小
+ int measuredWidth = getMeasuredWidth();
+ int measuredHeight = getMeasuredHeight();
+
+ int minSize = (int) getContext().getResources().getDimension(R.dimen.dp_40);
+
+ if (measuredWidth < minSize) {
+ measuredWidth = minSize;
+ }
+ if (measuredHeight < minSize) {
+ measuredHeight = minSize;
+ }
+
+ Log.d("DebugImageView", "Final - Width: " + measuredWidth + ", Height: " + measuredHeight);
+ Log.d("DebugImageView", "=== onMeasure END ===");
+
+ setMeasuredDimension(measuredWidth, measuredHeight);
+ }
+ }
\ No newline at end of file
diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/AvatarFrameView.java b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/AvatarFrameView.java
index d783d630..ea46383e 100644
--- a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/AvatarFrameView.java
+++ b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/AvatarFrameView.java
@@ -1080,11 +1080,12 @@ public class AvatarFrameView extends FrameLayout {
// 隐藏所有视图
// if (playerView != null) playerView.setVisibility(View.GONE);
if (svgaSurface != null) svgaSurface.setVisibility(View.GONE);
- mBinding.playView.setVisibility(View.GONE);
+
// 停止播放器
if (mBinding != null && mBinding.playView != null) {
mBinding.playView.stopPlay();
+ mBinding.playView.setVisibility(View.GONE);
}
} catch (Exception e) {
LogUtils.e(TAG, "Error in clearPrevious: " + e.getMessage());
diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/BaseWheatView.java b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/BaseWheatView.java
index 327d497b..1bdab39e 100644
--- a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/BaseWheatView.java
+++ b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/BaseWheatView.java
@@ -214,8 +214,10 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
//自动调节麦位波纹
// if (!TextUtils.isEmpty(bean.getDress_picture())) {
- mIvRipple.setScaleX(1.1f);
- mIvRipple.setScaleY(1.1f);
+ if (mIvRipple != null) {
+ mIvRipple.setScaleX(1.1f);
+ mIvRipple.setScaleY(1.1f);
+ }
// } else {
// mIvRipple.setScaleX(0.9f);
// mIvRipple.setScaleY(0.9f);
@@ -256,6 +258,8 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
AgoraManager.getInstance(getContext()).addSoundLevelListener(new SoundLevelUpdateListener() {
@Override
public void onRemoteSoundLevelUpdate(String userId, int soundLevel) {
+ if (mIvRipple == null)
+ return;
if (userId.equals(pitBean.getUser_id())) {
if (soundLevel == 0) {
mIvRipple.post(() -> {
@@ -281,6 +285,8 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
@Override
public void onLocalSoundLevelUpdate(int volume) {
+ if (mIvRipple == null)
+ return;
if (volume == 0) {
mIvRipple.post(() -> {
mIvRipple.setVisibility(GONE);
diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/RoomSingSongWheat2View.java b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/RoomSingSongWheat2View.java
new file mode 100644
index 00000000..81c1a153
--- /dev/null
+++ b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/RoomSingSongWheat2View.java
@@ -0,0 +1,297 @@
+package com.xscm.moduleutil.widget;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.xscm.moduleutil.R;
+import com.xscm.moduleutil.bean.UserInfo;
+import com.xscm.moduleutil.bean.room.RoomPitBean;
+import com.xscm.moduleutil.utils.ImageUtils;
+import com.xscm.moduleutil.utils.SpUtil;
+
+/**
+ * @Author lxj$
+ * @Time 2025-8-6 17:27:29$ $
+ * @Description 二卡八视图控件$
+ */
+public class RoomSingSongWheat2View extends BaseWheatView {
+ public ImageView mIvTagBoss;
+ public TextView mTvTime;
+ public TextView tv_time_pk;
+ public boolean isClickListenerSet = false;
+ private boolean showBoss;//显示老板标识
+
+ public RoomSingSongWheat2View(Context context) {
+ this(context, null, 0);
+ }
+
+ public RoomSingSongWheat2View(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public RoomSingSongWheat2View(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ @Override
+ protected void initPit(Context context, AttributeSet attrs) {
+ TypedArray typedArray = null;
+ try {
+ typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoomDefaultWheatView);
+ pitNumber = typedArray.getString(R.styleable.RoomDefaultWheatView_room_wheat_number);
+ } finally {
+ if (typedArray != null) {
+ typedArray.recycle();
+ }
+ }
+ mIvTagBoss = findViewById(R.id.iv_tag_boos);
+ mTvTime = findViewById(R.id.tv_time);
+ tv_time_pk = findViewById(R.id.tv_time_pk);
+ }
+
+ @Override
+ protected int getLayoutId() {
+ return R.layout.room_view_sing_wheat_2;
+ }
+
+ @Override
+ protected void setPitData(RoomPitBean bean) {
+ if (bean == null) return;
+
+ sex = bean.getSex();
+ pitBean = bean; // 统一使用参数 bean
+ if (isOn()) {
+ handleOnState(bean);
+ } else {
+ handleOffState(bean);
+ }
+
+ updateSexIcon();
+// updateCharmViewVisibility(bean);
+ updatePkState(bean);
+ iv_on_line.setVisibility(GONE);
+ }
+
+ private void handleOnState(RoomPitBean bean) {
+
+ mTvName.setText(bean.getNickname());
+ ImageUtils.loadHeadCC(bean.getAvatar(), mRiv);
+ mCharmView.setVisibility(VISIBLE);
+ if (mIvFrame != null) {
+ if (TextUtils.isEmpty(bean.getDress())) {
+ mIvFrame.stopAll();
+ mIvFrame.setVisibility(INVISIBLE);
+ } else {
+ mIvFrame.setVisibility(VISIBLE);
+ mIvFrame.setSource(bean.getDress(), 3);
+ }
+ }
+
+ if (showBoss && TextUtils.equals(WHEAT_BOSS, pitNumber)) {
+ mIvTagBoss.setVisibility(GONE);
+ }
+ }
+
+ private void handleOffState(RoomPitBean bean) {
+ mTvName.setText(getPitNumberText());
+ mCharmView.setVisibility(GONE);
+ if (showBoss && TextUtils.equals(WHEAT_BOSS, pitNumber)) {
+ mIvTagBoss.setVisibility(VISIBLE);
+ int resId = bean.getIs_lock() == 1 ? R.mipmap.index_img_room_mask : R.drawable.room_ic_wheat_default;
+ mRiv.setImageResource(resId);
+ } else {
+ mRiv.setImageResource(bean.getIs_lock() == 1 ? R.mipmap.index_img_room_mask : R.drawable.room_ic_wheat_default);
+ }
+
+ if (isMute()) {
+ ImageUtils.loadRes(R.mipmap.room_microphone_off, mIvSex);
+ }
+ if (mIvFrame != null) {
+ mIvFrame.stopAll();
+ mIvFrame.setVisibility(INVISIBLE);
+ }
+ mIvFace.remove();
+ }
+
+ private String getPitNumberText() {
+ if ("-1".equals(pitNumber)) return "";
+ if ("9".equals(pitNumber)) return "主持位";
+ if ("10".equals(pitNumber)) return "嘉宾位";
+ return pitNumber + "号麦位";
+ }
+
+ private void updateSexIcon() {
+ if (showSexIcon) {
+ checkSex();
+ }
+ }
+
+ private void updateCharmViewVisibility(RoomPitBean bean) {
+ boolean isEmptyNickname = bean.getNickname() == null || bean.getNickname().isEmpty();
+ mCharmView.setVisibility(isEmptyNickname ? GONE : VISIBLE);
+ }
+
+ private void updatePkState(RoomPitBean bean) {
+ if (bean.is_pk()) {
+ String userId = bean.getUser_id();
+ if (userId != null && !userId.equals("0") && !userId.isEmpty()) {
+ tv_time_pk.setVisibility(VISIBLE);
+ setSex(bean.getCharm(), false);
+ mCharmView.setVisibility(GONE);
+ } else {
+ tv_time_pk.setVisibility(GONE);
+ }
+ } else {
+ tv_time_pk.setVisibility(GONE);
+ if (isOn()) {
+ mCharmView.setVisibility(VISIBLE);
+ } else {
+ mCharmView.setVisibility(GONE);
+ }
+ }
+ }
+
+ public void setSex(String value, boolean format) {
+ if (format) {
+ tv_time_pk.setText(value);
+ } else {
+ try {
+ long xd = Long.parseLong(value);
+ if (xd > 9999 || xd < -9999) {
+ tv_time_pk.setText(String.format("%.2fw", xd / 10000.0f));
+ } else {
+ tv_time_pk.setText(value);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ tv_time_pk.setText("0"); // 设置默认值防止UI异常
+ }
+ }
+ }
+
+ private boolean showSexIcon = false;
+ private String sex;
+
+ public boolean isMale() {
+ return "1".equals(sex);
+ }
+
+ public boolean isFemale() {
+ return "2".equals(sex);
+ }
+
+ public void setShowSexIcon(boolean show) {
+ showSexIcon = show;
+ }
+
+ public void checkSex() {
+ if (isOn()) {
+ mIvSex.setVisibility(VISIBLE);
+ if (!TextUtils.isEmpty(sex)) {
+ if (UserInfo.MALE.equals(sex)) {
+ mIvSex.setBackgroundResource(R.drawable.room_xq_wheat_male_mask);
+ if (mTvNo != null) mTvNo.setBackgroundResource(R.mipmap.ic_room_xq_wno_male);
+ } else {
+ mIvSex.setBackgroundResource(R.drawable.room_xq_wheat_female_mask);
+ if (mTvNo != null) mTvNo.setBackgroundResource(R.mipmap.ic_room_xq_wno_female);
+ }
+ } else {
+ mIvSex.setVisibility(GONE);
+ if (mTvNo != null) mTvNo.setBackgroundResource(getOriginNoImage());
+ }
+ } else {
+ mIvSex.setVisibility(GONE);
+ if (mTvNo != null) mTvNo.setBackgroundResource(getOriginNoImage());
+ }
+ }
+
+ /**
+ * 是否显示老板标识
+ */
+ public void setIsBossShow(String is_boss_pit) {
+ showBoss = "1".equals(is_boss_pit);
+ }
+
+ /**
+ * 开启计时
+ */
+ public void setTime(int time) {
+ if (time == 0) {
+ mTvTime.setText("");
+ mTvTime.setVisibility(INVISIBLE);
+ } else {
+ mTvTime.setText(String.format("%s'%s", time / 60, time % 60));
+ mTvTime.setVisibility(VISIBLE);
+ }
+ }
+
+ public void hideMaoziIcon() {
+ View maozi = findViewById(R.id.iv_maozi);
+ if (maozi != null) maozi.setVisibility(GONE);
+ }
+
+ // 添加内存释放方法
+ public void releaseResources() {
+ // 清理头像加载
+ if (mRiv != null) {
+ mRiv.setImageBitmap(null);
+ }
+
+ // 清理框架视图
+ if (mIvFrame != null) {
+ mIvFrame.release(); // 清理SVGA资源
+ }
+
+ // 清理表情视图
+ if (mIvFace != null) {
+ mIvFace.remove();
+ }
+
+ // 清理其他图片资源
+ if (mIvSex != null) {
+ mIvSex.setImageBitmap(null);
+ }
+
+ if (mIvTagBoss != null) {
+ mIvTagBoss.setImageBitmap(null);
+ }
+ }
+
+
+ @Override
+ protected void onDetachedFromWindow() {
+ // 视图从窗口分离时释放资源
+ releaseResources();
+ super.onDetachedFromWindow();
+ }
+
+ @Override
+ public void onRemoteSoundLevelUpdate(String userId, int soundLevel) {
+ // 暂无实现
+ }
+
+ @Override
+ public void onLocalSoundLevelUpdate(int volume) {
+
+ }
+
+ @Override
+ public void userJoined(int userId, int elapsd) {
+ // 暂无实现
+ }
+
+ @Override
+ public void userOffline(int userId, int reason) {
+ // 暂无实现
+ }
+
+ @Override
+ public void unRegister(Object obj) {
+
+ }
+}
diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutSingManager.java b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutSingManager.java
index 68482528..64bd69d0 100644
--- a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutSingManager.java
+++ b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutSingManager.java
@@ -1,5 +1,6 @@
package com.xscm.moduleutil.widget;
+import android.app.Activity;
import android.content.Context;
import android.util.DisplayMetrics;
import android.view.View;
@@ -17,6 +18,8 @@ import com.xscm.moduleutil.utils.SpUtil;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
/**
* @Author lxj$
@@ -50,97 +53,30 @@ public class WheatLayoutSingManager {
this.container = container;
}
- public void setWheatData(List pitList) {
+ public void setWheatData(List pitList, boolean isFirst) {
// 检查容器状态
- if (container == null || !isContainerValid()) {
+ if (container == null) {
return;
}
this.pitList = pitList;
- restoreMultiWheat();
- }
-
- public void setWheatDataPk(List pitList, int layoutType) {
- // 检查容器状态
- if (container == null || !isContainerValid()) {
- return;
- }
-
- this.pitList = pitList;
- restoreMultiWheatPk(layoutType);
+ restoreMultiWheat(isFirst);
}
public void setOnWheatClickListener(@Nullable OnWheatClickListener listener) {
this.wheatClickListener = listener;
}
- public void showSingleWheat(int pitNumber) {
+ public void restoreMultiWheat(boolean isFirst) {
// 检查容器状态
- if (container == null || !isContainerValid()) {
- return;
- }
-
- if (isSingleMode && this.currentSinglePit == pitNumber) return;
-
- try {
- container.removeAllViews();
- } catch (Exception e) {
- // 忽略异常,继续执行
- return;
- }
-
- if (pitNumber < 1 || pitNumber > 10 || pitList == null || pitList.size() < 10)
- return;
-
- RoomPitBean bean = pitList.get(pitNumber - 1);
-
- singleWheatView = new RoomSingSongWheatView(context);
- singleWheatView.pitNumber = String.valueOf(pitNumber);
- singleWheatView.setData(bean);
-
- // 默认设置为 MATCH_PARENT,也可以自定义
- LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.MATCH_PARENT,
- LinearLayout.LayoutParams.WRAP_CONTENT
- );
- params.setMargins(20, 20, 20, 20);
- singleWheatView.setLayoutParams(params);
-
- GifAvatarOvalView avatarView = (GifAvatarOvalView) singleWheatView.mRiv;
- avatarView.setOnClickListener(v -> {
- if (wheatClickListener != null) {
- wheatClickListener.onWheatClick(singleWheatView, pitNumber);
- }
- restoreMultiWheat();
- });
-
- WheatCharmView charmView = singleWheatView.mCharmView;
- charmView.setOnClickListener(v -> {
- if (wheatClickListener != null) {
- wheatClickListener.onMeilingClick(singleWheatView, Integer.parseInt(singleWheatView.pitNumber));
- }
- });
-// // 添加点击事件
- singleWheatView.setOnClickListener(v -> {
- if (wheatClickListener != null) {
- wheatClickListener.onMakeWheatClick(singleWheatView, pitNumber);
- }
- restoreMultiWheat();
- });
-
- container.addView(singleWheatView);
- isSingleMode = true;
- currentSinglePit = pitNumber;
- }
-
- public void restoreMultiWheat() {
- // 检查容器状态
- if (container == null || !isContainerValid()) {
+ if (container == null) {
return;
}
try {
- container.removeAllViews();
+ if (multiWheatViews != null && multiWheatViews.size() != 10) {
+ container.removeAllViews();
+ }
} catch (Exception e) {
// 忽略异常,继续执行
return;
@@ -150,86 +86,131 @@ public class WheatLayoutSingManager {
return;
}
- multiWheatViews.clear();
+// multiWheatViews.clear();
int screenWidth = getScreenWidth();
int itemWidth = screenWidth / 4; // 每个控件宽度为屏幕宽度的 1/4
LinearLayout row = new LinearLayout(context);
row.setOrientation(LinearLayout.HORIZONTAL);
+ if (multiWheatViews.size() == 10){
+ for (int i = 0; i < multiWheatViews.size(); i++){
+ multiWheatViews.get(i).setData(pitList.get(pitIndexMap[i] - 1));
+ }
+ }else {
+ for (int i = 0; i < 10; i++) {
+ int pitNumber = pitIndexMap[i];
+ if (isFirst){
+ RoomSingSongWheat2View wheatView = new RoomSingSongWheat2View( context);
+ wheatView.pitNumber = String.valueOf(pitNumber);
+ wheatView.setData(pitList.get(pitNumber - 1));
- for (int i = 0; i < 10; i++) {
- int pitNumber = pitIndexMap[i];
- RoomSingSongWheatView wheatView = new RoomSingSongWheatView(context);
- wheatView.pitNumber = String.valueOf(pitNumber);
- wheatView.setData(pitList.get(pitNumber - 1));
- multiWheatViews.add(wheatView);
- LinearLayout.LayoutParams params;
+ LinearLayout.LayoutParams params;
+ if (i == 0) {
+ int fixedHeightInDp = 110; // 固定高度为 100dp
+ int fixedHeightInPx = dpToPx(fixedHeightInDp); // 调用已有的 dpToPx 方法
+ // 第一个控件:左边距 86dp,右边距 100dp
+ params = new LinearLayout.LayoutParams(itemWidth, fixedHeightInPx);
+ params.rightMargin = dpToPx(50);
+ } else if (i == 1) {
+ int fixedHeightInDp = 110; // 固定高度为 100dp
+ int fixedHeightInPx = dpToPx(fixedHeightInDp); // 调用已有的 dpToPx 方法
+ // 第二个控件:右边距 86dp
+ params = new LinearLayout.LayoutParams(itemWidth, fixedHeightInPx);
+ } else {
+ int fixedHeightInDp = 90; // 固定高度为 100dp
+ int fixedHeightInPx = dpToPx(fixedHeightInDp); // 调用已有的 dpToPx 方法
+ params = new LinearLayout.LayoutParams(itemWidth - 30, fixedHeightInPx + 30);
+ // 其他控件保持原有逻辑
- if (i == 0) {
- int fixedHeightInDp = 110; // 固定高度为 100dp
- int fixedHeightInPx = dpToPx(fixedHeightInDp); // 调用已有的 dpToPx 方法
- // 第一个控件:左边距 86dp,右边距 100dp
- params = new LinearLayout.LayoutParams(itemWidth, fixedHeightInPx);
- params.rightMargin = dpToPx(50);
- } else if (i == 1) {
- int fixedHeightInDp = 110; // 固定高度为 100dp
- int fixedHeightInPx = dpToPx(fixedHeightInDp); // 调用已有的 dpToPx 方法
- // 第二个控件:右边距 86dp
- params = new LinearLayout.LayoutParams(itemWidth, fixedHeightInPx);
- } else {
- int fixedHeightInDp = 90; // 固定高度为 100dp
- int fixedHeightInPx = dpToPx(fixedHeightInDp); // 调用已有的 dpToPx 方法
- params = new LinearLayout.LayoutParams(itemWidth - 30, fixedHeightInPx + 30);
- // 其他控件保持原有逻辑
+ params.setMargins(0, 0, 0, 0); // 不设右边距,由 row padding 控制
+ }
+ wheatView.setLayoutParams(params);
+ row.addView(wheatView);
+ // 第一行添加两个后换行
+ if (i == 1) {
+ container.addView(row);
+ row = new LinearLayout(context);
+ row.setOrientation(LinearLayout.HORIZONTAL);
+ } else if (i > 1 && (i - 2) % 4 == 3) {
+ container.addView(row);
+ row = new LinearLayout(context);
+ row.setOrientation(LinearLayout.HORIZONTAL);
+ }
+
+ }else {
+ RoomSingSongWheatView wheatView = new RoomSingSongWheatView(context);
+ wheatView.pitNumber = String.valueOf(pitNumber);
+ wheatView.setData(pitList.get(pitNumber - 1));
+ multiWheatViews.add(wheatView);
+
+ LinearLayout.LayoutParams params;
+ if (i == 0) {
+ int fixedHeightInDp = 110; // 固定高度为 100dp
+ int fixedHeightInPx = dpToPx(fixedHeightInDp); // 调用已有的 dpToPx 方法
+ // 第一个控件:左边距 86dp,右边距 100dp
+ params = new LinearLayout.LayoutParams(itemWidth, fixedHeightInPx);
+ params.rightMargin = dpToPx(50);
+ } else if (i == 1) {
+ int fixedHeightInDp = 110; // 固定高度为 100dp
+ int fixedHeightInPx = dpToPx(fixedHeightInDp); // 调用已有的 dpToPx 方法
+ // 第二个控件:右边距 86dp
+ params = new LinearLayout.LayoutParams(itemWidth, fixedHeightInPx);
+ } else {
+ int fixedHeightInDp = 90; // 固定高度为 100dp
+ int fixedHeightInPx = dpToPx(fixedHeightInDp); // 调用已有的 dpToPx 方法
+ params = new LinearLayout.LayoutParams(itemWidth - 30, fixedHeightInPx + 30);
+ // 其他控件保持原有逻辑
+
+ params.setMargins(0, 0, 0, 0); // 不设右边距,由 row padding 控制
+ }
+ wheatView.setLayoutParams(params);
+
+
+ GifAvatarOvalView avatarView = (GifAvatarOvalView) wheatView.mRiv;
+ avatarView.setOnClickListener(v -> {
+ if (wheatClickListener != null) {
+ wheatClickListener.onWheatClick(wheatView, pitNumber);
+ }
+ });
+
+ WheatCharmView charmView = wheatView.mCharmView;
+ charmView.setOnClickListener(v -> {
+ if (wheatClickListener != null) {
+ ToastUtils.show("点击了麦位");
+ wheatClickListener.onMeilingClick(wheatView, pitNumber);
+ }
+ });
+
+ wheatView.setOnClickListener(v -> {
+ if (wheatClickListener != null) {
+ wheatClickListener.onMeilingClick(wheatView, Integer.parseInt(wheatView.pitNumber));
+ }
+ });
+
+ row.addView(wheatView);
+
+ // 第一行添加两个后换行
+ if (i == 1) {
+ container.addView(row);
+ row = new LinearLayout(context);
+ row.setOrientation(LinearLayout.HORIZONTAL);
+ } else if (i > 1 && (i - 2) % 4 == 3) {
+ container.addView(row);
+ row = new LinearLayout(context);
+ row.setOrientation(LinearLayout.HORIZONTAL);
+ }
+ }
- params.setMargins(0, 0, 0, 0); // 不设右边距,由 row padding 控制
}
- wheatView.setLayoutParams(params);
-
-
- GifAvatarOvalView avatarView = (GifAvatarOvalView) wheatView.mRiv;
- avatarView.setOnClickListener(v -> {
- if (wheatClickListener != null) {
- wheatClickListener.onWheatClick(wheatView, pitNumber);
- }
- });
-
- WheatCharmView charmView = wheatView.mCharmView;
- charmView.setOnClickListener(v -> {
- if (wheatClickListener != null) {
- ToastUtils.show("点击了麦位");
- wheatClickListener.onMeilingClick(wheatView, pitNumber);
- }
- });
-
- wheatView.setOnClickListener(v -> {
- if (wheatClickListener != null) {
- wheatClickListener.onMeilingClick(wheatView, Integer.parseInt(wheatView.pitNumber));
- }
- });
-
- row.addView(wheatView);
-
- // 第一行添加两个后换行
- if (i == 1) {
+ // 添加最后一行可能存在的剩余 view
+ if (row.getChildCount() > 0) {
container.addView(row);
- row = new LinearLayout(context);
- row.setOrientation(LinearLayout.HORIZONTAL);
- } else if (i > 1 && (i - 2) % 4 == 3) {
- container.addView(row);
- row = new LinearLayout(context);
- row.setOrientation(LinearLayout.HORIZONTAL);
}
+ isSingleMode = false;
+ currentSinglePit = -1;
}
-
- // 添加最后一行可能存在的剩余 view
- if (row.getChildCount() > 0) {
- container.addView(row);
- }
- isSingleMode = false;
- currentSinglePit = -1;
}
public void restoreMultiWheatPk(int layoutType) {
diff --git a/moduleUtil/src/main/res/anim/a_slide_left_in.xml b/moduleUtil/src/main/res/anim/a_slide_left_in.xml
new file mode 100644
index 00000000..ef8340a9
--- /dev/null
+++ b/moduleUtil/src/main/res/anim/a_slide_left_in.xml
@@ -0,0 +1,5 @@
+
+
+
+
\ No newline at end of file
diff --git a/moduleUtil/src/main/res/anim/a_slide_left_out.xml b/moduleUtil/src/main/res/anim/a_slide_left_out.xml
new file mode 100644
index 00000000..9a36b6cf
--- /dev/null
+++ b/moduleUtil/src/main/res/anim/a_slide_left_out.xml
@@ -0,0 +1,5 @@
+
+
+
+
\ No newline at end of file
diff --git a/moduleUtil/src/main/res/anim/a_slide_right_in.xml b/moduleUtil/src/main/res/anim/a_slide_right_in.xml
new file mode 100644
index 00000000..d9603c2e
--- /dev/null
+++ b/moduleUtil/src/main/res/anim/a_slide_right_in.xml
@@ -0,0 +1,5 @@
+
+
+
+
\ No newline at end of file
diff --git a/moduleUtil/src/main/res/anim/a_slide_right_out.xml b/moduleUtil/src/main/res/anim/a_slide_right_out.xml
new file mode 100644
index 00000000..acbd7de0
--- /dev/null
+++ b/moduleUtil/src/main/res/anim/a_slide_right_out.xml
@@ -0,0 +1,5 @@
+
+
+
+
\ No newline at end of file
diff --git a/moduleUtil/src/main/res/layout/ease_row_received_message_giftr_send.xml b/moduleUtil/src/main/res/layout/ease_row_received_message_giftr_send.xml
new file mode 100644
index 00000000..204cd23f
--- /dev/null
+++ b/moduleUtil/src/main/res/layout/ease_row_received_message_giftr_send.xml
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/moduleUtil/src/main/res/layout/ease_row_received_message_system.xml b/moduleUtil/src/main/res/layout/ease_row_received_message_system.xml
index 27a55f30..31765018 100644
--- a/moduleUtil/src/main/res/layout/ease_row_received_message_system.xml
+++ b/moduleUtil/src/main/res/layout/ease_row_received_message_system.xml
@@ -5,6 +5,9 @@
android:id="@+id/bubble"
android:layout_marginTop="@dimen/dp_3"
android:layout_marginBottom="@dimen/dp_3"
+ android:padding="@dimen/dp_8"
+ android:layout_marginStart="@dimen/dp_8"
+ android:background="@drawable/ease_row_pubilc_sys_bg"
>
diff --git a/moduleUtil/src/main/res/layout/ease_row_received_message_user_send.xml b/moduleUtil/src/main/res/layout/ease_row_received_message_user_send.xml
index 4a1a8fec..494ae777 100644
--- a/moduleUtil/src/main/res/layout/ease_row_received_message_user_send.xml
+++ b/moduleUtil/src/main/res/layout/ease_row_received_message_user_send.xml
@@ -13,15 +13,15 @@
>
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/moduleUtil/src/main/res/layout/room_view_sing_wheat_2.xml b/moduleUtil/src/main/res/layout/room_view_sing_wheat_2.xml
new file mode 100644
index 00000000..e8e6dd1b
--- /dev/null
+++ b/moduleUtil/src/main/res/layout/room_view_sing_wheat_2.xml
@@ -0,0 +1,491 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/moduleUtil/src/main/res/mipmap-hdpi/bandan.webp b/moduleUtil/src/main/res/mipmap-hdpi/bandan.webp
new file mode 100644
index 00000000..e4c8e9f4
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/bandan.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-hdpi/cp_tx_k.png b/moduleUtil/src/main/res/mipmap-hdpi/cp_tx_k.png
new file mode 100644
index 00000000..85e5f003
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/cp_tx_k.png differ
diff --git a/moduleUtil/src/main/res/mipmap-hdpi/guanb1.webp b/moduleUtil/src/main/res/mipmap-hdpi/guanb1.webp
new file mode 100644
index 00000000..5e67d52e
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/guanb1.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-hdpi/guanb2.webp b/moduleUtil/src/main/res/mipmap-hdpi/guanb2.webp
new file mode 100644
index 00000000..41950002
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/guanb2.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-hdpi/guanb3.webp b/moduleUtil/src/main/res/mipmap-hdpi/guanb3.webp
new file mode 100644
index 00000000..f72e935a
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/guanb3.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-hdpi/item_ranking_bj.webp b/moduleUtil/src/main/res/mipmap-hdpi/item_ranking_bj.webp
new file mode 100644
index 00000000..10fdf975
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/item_ranking_bj.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-hdpi/ranking_bj.webp b/moduleUtil/src/main/res/mipmap-hdpi/ranking_bj.webp
new file mode 100644
index 00000000..ab91e437
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/ranking_bj.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-hdpi/ranking_hr.webp b/moduleUtil/src/main/res/mipmap-hdpi/ranking_hr.webp
new file mode 100644
index 00000000..9e9602db
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/ranking_hr.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-hdpi/ranking_top_bj.webp b/moduleUtil/src/main/res/mipmap-hdpi/ranking_top_bj.webp
new file mode 100644
index 00000000..455e69fb
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/ranking_top_bj.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-hdpi/ranking_user_cp_k.png b/moduleUtil/src/main/res/mipmap-hdpi/ranking_user_cp_k.png
new file mode 100644
index 00000000..03abeb87
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/ranking_user_cp_k.png differ
diff --git a/moduleUtil/src/main/res/mipmap-hdpi/ranking_user_k.webp b/moduleUtil/src/main/res/mipmap-hdpi/ranking_user_k.webp
new file mode 100644
index 00000000..3b3d90d8
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/ranking_user_k.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-hdpi/ranking_za_hr.webp b/moduleUtil/src/main/res/mipmap-hdpi/ranking_za_hr.webp
new file mode 100644
index 00000000..8f9da3df
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/ranking_za_hr.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-hdpi/text_ranking_sele.webp b/moduleUtil/src/main/res/mipmap-hdpi/text_ranking_sele.webp
new file mode 100644
index 00000000..cace7f9f
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/text_ranking_sele.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-hdpi/text_ranking_ud.webp b/moduleUtil/src/main/res/mipmap-hdpi/text_ranking_ud.webp
new file mode 100644
index 00000000..ac4553df
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/text_ranking_ud.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/bandan.webp b/moduleUtil/src/main/res/mipmap-xhdpi/bandan.webp
new file mode 100644
index 00000000..b6506489
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/bandan.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/cp_tx_k.png b/moduleUtil/src/main/res/mipmap-xhdpi/cp_tx_k.png
new file mode 100644
index 00000000..a13d19d4
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/cp_tx_k.png differ
diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/guanb1.webp b/moduleUtil/src/main/res/mipmap-xhdpi/guanb1.webp
new file mode 100644
index 00000000..0498c722
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/guanb1.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/guanb2.webp b/moduleUtil/src/main/res/mipmap-xhdpi/guanb2.webp
new file mode 100644
index 00000000..56b8d2d1
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/guanb2.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/guanb3.webp b/moduleUtil/src/main/res/mipmap-xhdpi/guanb3.webp
new file mode 100644
index 00000000..d88621cb
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/guanb3.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/item_ranking_bj.webp b/moduleUtil/src/main/res/mipmap-xhdpi/item_ranking_bj.webp
new file mode 100644
index 00000000..e83d2c5c
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/item_ranking_bj.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/ranking_bj.webp b/moduleUtil/src/main/res/mipmap-xhdpi/ranking_bj.webp
new file mode 100644
index 00000000..b3f41efc
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/ranking_bj.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/ranking_hr.webp b/moduleUtil/src/main/res/mipmap-xhdpi/ranking_hr.webp
new file mode 100644
index 00000000..dd6942aa
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/ranking_hr.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/ranking_top_bj.webp b/moduleUtil/src/main/res/mipmap-xhdpi/ranking_top_bj.webp
new file mode 100644
index 00000000..0b18d0ae
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/ranking_top_bj.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/ranking_user_cp_k.png b/moduleUtil/src/main/res/mipmap-xhdpi/ranking_user_cp_k.png
new file mode 100644
index 00000000..83de7d45
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/ranking_user_cp_k.png differ
diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/ranking_user_k.webp b/moduleUtil/src/main/res/mipmap-xhdpi/ranking_user_k.webp
new file mode 100644
index 00000000..8a3a9d39
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/ranking_user_k.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/ranking_za_hr.webp b/moduleUtil/src/main/res/mipmap-xhdpi/ranking_za_hr.webp
new file mode 100644
index 00000000..a3e54212
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/ranking_za_hr.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/text_ranking_sele.webp b/moduleUtil/src/main/res/mipmap-xhdpi/text_ranking_sele.webp
new file mode 100644
index 00000000..db357761
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/text_ranking_sele.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/text_ranking_ud.webp b/moduleUtil/src/main/res/mipmap-xhdpi/text_ranking_ud.webp
new file mode 100644
index 00000000..ce157625
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/text_ranking_ud.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/bandan.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/bandan.webp
new file mode 100644
index 00000000..8221a5cb
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/bandan.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/cp_tx_k.png b/moduleUtil/src/main/res/mipmap-xxhdpi/cp_tx_k.png
new file mode 100644
index 00000000..36b86ae2
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/cp_tx_k.png differ
diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/guanb1.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/guanb1.webp
new file mode 100644
index 00000000..212b8c51
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/guanb1.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/guanb2.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/guanb2.webp
new file mode 100644
index 00000000..64aef656
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/guanb2.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/guanb3.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/guanb3.webp
new file mode 100644
index 00000000..a7dd9409
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/guanb3.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/item_ranking_bj.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/item_ranking_bj.webp
new file mode 100644
index 00000000..5e889aa5
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/item_ranking_bj.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_bj.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_bj.webp
new file mode 100644
index 00000000..a762ac3d
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_bj.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_hr.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_hr.webp
new file mode 100644
index 00000000..d97f2431
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_hr.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_top_bj.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_top_bj.webp
new file mode 100644
index 00000000..ee3dc190
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_top_bj.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_user_cp_k.png b/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_user_cp_k.png
new file mode 100644
index 00000000..d2344065
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_user_cp_k.png differ
diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_user_k.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_user_k.webp
new file mode 100644
index 00000000..15b77b62
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_user_k.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_za_hr.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_za_hr.webp
new file mode 100644
index 00000000..d5527dc0
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_za_hr.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/text_ranking_sele.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/text_ranking_sele.webp
new file mode 100644
index 00000000..cb8ffe68
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/text_ranking_sele.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/text_ranking_ud.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/text_ranking_ud.webp
new file mode 100644
index 00000000..9b72bfef
Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/text_ranking_ud.webp differ
diff --git a/moduleUtil/src/main/res/mipmap-xxxhdpi/bangdan.webp b/moduleUtil/src/main/res/mipmap-xxxhdpi/bangdan.webp
deleted file mode 100644
index 818630c1..00000000
Binary files a/moduleUtil/src/main/res/mipmap-xxxhdpi/bangdan.webp and /dev/null differ
diff --git a/moduleUtil/src/main/res/mipmap-xxxhdpi/guanb1.webp b/moduleUtil/src/main/res/mipmap-xxxhdpi/guanb1.webp
deleted file mode 100644
index 90e6cd02..00000000
Binary files a/moduleUtil/src/main/res/mipmap-xxxhdpi/guanb1.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-xhdpi/screen.webp b/moduleUtil/src/main/res/mipmap-xxxhdpi/screen.webp
similarity index 100%
rename from app/src/main/res/mipmap-xhdpi/screen.webp
rename to moduleUtil/src/main/res/mipmap-xxxhdpi/screen.webp
diff --git a/moduleUtil/src/main/res/values-night/themes.xml b/moduleUtil/src/main/res/values-night/themes.xml
deleted file mode 100644
index edf75cd6..00000000
--- a/moduleUtil/src/main/res/values-night/themes.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/moduleUtil/src/main/res/values/colors.xml b/moduleUtil/src/main/res/values/colors.xml
index 59481c64..7d3df463 100644
--- a/moduleUtil/src/main/res/values/colors.xml
+++ b/moduleUtil/src/main/res/values/colors.xml
@@ -327,4 +327,25 @@
#DAD1F8
+
+ #ff5878
+ @color/gray2
+ #282828
+ #969696
+ #f5f5f5
+ #c8c8c8
+ #B4B4B4
+ #dcdcdc
+ #fffa37
+ #f0cd08
+ #FFF34D
+ #ffdd00
+ #646464
+ #ff0000
+ #FF205E
+ #169AFF
+ #e6323232
+ #1FC8F8
+ #4998F7
+ #32A0FF
\ No newline at end of file
diff --git a/moduleUtil/src/main/res/values/styles.xml b/moduleUtil/src/main/res/values/styles.xml
index 5dc48157..c1a41126 100644
--- a/moduleUtil/src/main/res/values/styles.xml
+++ b/moduleUtil/src/main/res/values/styles.xml
@@ -67,12 +67,12 @@
-
+
+
+
+
+
+
-
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modulecircle/src/main/AndroidManifest.xml b/modulecircle/src/main/AndroidManifest.xml
index 84b97dc4..faa4b3a0 100644
--- a/modulecircle/src/main/AndroidManifest.xml
+++ b/modulecircle/src/main/AndroidManifest.xml
@@ -10,18 +10,18 @@
+ />
\ No newline at end of file
diff --git a/modulecircle/src/main/java/com/example/modulecircle/adapter/ExpandColumnAdapter.java b/modulecircle/src/main/java/com/example/modulecircle/adapter/ExpandColumnAdapter.java
index 74e93e71..5c2d95a3 100644
--- a/modulecircle/src/main/java/com/example/modulecircle/adapter/ExpandColumnAdapter.java
+++ b/modulecircle/src/main/java/com/example/modulecircle/adapter/ExpandColumnAdapter.java
@@ -114,8 +114,8 @@ public class ExpandColumnAdapter extends BaseQuickAdapter
-
-
-
\ No newline at end of file
diff --git a/modulecircle/src/main/res/values/themes.xml b/modulecircle/src/main/res/values/themes.xml
deleted file mode 100644
index 46ca6c9a..00000000
--- a/modulecircle/src/main/res/values/themes.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/modulemain/src/main/res/values-night/themes.xml b/modulemain/src/main/res/values-night/themes.xml
deleted file mode 100644
index 1c850379..00000000
--- a/modulemain/src/main/res/values-night/themes.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/modulemain/src/main/res/values/themes.xml b/modulemain/src/main/res/values/themes.xml
deleted file mode 100644
index 28121856..00000000
--- a/modulemain/src/main/res/values/themes.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/modulenews/src/main/res/values-night/themes.xml b/modulenews/src/main/res/values-night/themes.xml
deleted file mode 100644
index 1c850379..00000000
--- a/modulenews/src/main/res/values-night/themes.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/modulenews/src/main/res/values/themes.xml b/modulenews/src/main/res/values/themes.xml
deleted file mode 100644
index 46ca6c9a..00000000
--- a/modulenews/src/main/res/values/themes.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/moduleroom/src/main/java/com/example/moduleroom/activity/RoomActivity.kt b/moduleroom/src/main/java/com/example/moduleroom/activity/RoomActivity.kt
index df7a3a0c..6f3ec25f 100644
--- a/moduleroom/src/main/java/com/example/moduleroom/activity/RoomActivity.kt
+++ b/moduleroom/src/main/java/com/example/moduleroom/activity/RoomActivity.kt
@@ -46,6 +46,7 @@ import com.example.moduleroom.fragment.*
import com.example.moduleroom.presenter.RoomPresenter
import com.example.moduleroom.service.ForegroundService
import com.example.moduleroom.service.RoomPlayService
+import com.google.common.collect.Sets.SetView
import com.hjq.toast.ToastUtils
import com.liulishuo.okdownload.OkDownloadProvider
import com.orhanobut.logger.Logger
@@ -90,7 +91,10 @@ import com.xscm.moduleutil.widget.*
import com.xscm.moduleutil.widget.ViewUtils.OnViewCreatedListener
import com.xscm.moduleutil.widget.floatingView.Floa
import io.agora.musiccontentcenter.Music
+import io.reactivex.Observable
+import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
+import io.reactivex.schedulers.Schedulers
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
@@ -116,20 +120,12 @@ class RoomActivity : BaseMvpActivity(),
private var mRoomUserBean: RoomUserBean? = null
private var mPitList: List = ArrayList()
- @JvmField
- @Autowired
var password: String? = null
- @JvmField
- @Autowired
var roomId: String? = null
- @JvmField
- @Autowired
var mRoomInfoResp: RoomInfoResp? = null
- @JvmField
- @Autowired
var taskId: String? = null
var likeUserAdapter: LikeUserAdapter? = null
@@ -176,7 +172,13 @@ class RoomActivity : BaseMvpActivity(),
fun addActiveDialogFragment(dialogFragment: Fragment) {
activeDialogFragments.add(dialogFragment)
}
-
+ override fun doDone() {
+ isOnline = intent.getBooleanExtra("isOnline", false)
+ password = intent.getStringExtra("password")
+ roomId = intent.getStringExtra("roomId")
+ mRoomInfoResp = intent.getSerializableExtra("roomInfo") as RoomInfoResp?
+ LogUtils.dTag("RoomActivity", "doDone"+mRoomInfoResp.toString())
+ }
private fun resumeRoomFromMinimize() {
@@ -354,7 +356,7 @@ class RoomActivity : BaseMvpActivity(),
/** 最小化 */
private fun showExitRoomDialog() {
- if (mRoomInfoResp!!.room_info.type_id.equals("6")) {
+ if (mRoomInfoResp?.room_info?.type_id.equals("6")) {
val bottomSheet = ExitRoomBottomSheet.newInstance(false, true, true);
bottomSheet.setOnOptionSelectedListener(object : OnOptionSelectedListener {
override fun onMinimize() {
@@ -368,8 +370,7 @@ class RoomActivity : BaseMvpActivity(),
// 调用退出房间方法
MessageListenerSingleton.quitGroup(roomId);
quit();
- if (mRoomInfoResp!!.getRoom_info()
- .getLabel_id() != null && mRoomInfoResp!!.getRoom_info().getLabel_id()
+ if (mRoomInfoResp?.getRoom_info()?.getLabel_id() != null && mRoomInfoResp?.getRoom_info()?.getLabel_id()
.equals("5")
) {
jiaR();
@@ -489,7 +490,7 @@ class RoomActivity : BaseMvpActivity(),
isSave = false
sDestroied = false
isMinimized = false
- overridePendingTransition(0, 0) // 关闭转场动画
+// overridePendingTransition(0, 0) // 关闭转场动画
startKeepLiveService() //保活
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN)
@@ -500,12 +501,13 @@ class RoomActivity : BaseMvpActivity(),
checkAndRestoreMinimizeState()
// 获取传递的房间数据
// 在子线程中执行网络请求
- performNetworkRequestsAsync()
- roomFragment = RoomFragment.newInstance()
- supportFragmentManager
- .beginTransaction()
- .replace(R.id.vp_room_pager, roomFragment!!)
- .commitAllowingStateLoss()
+// performNetworkRequestsAsync()
+
+// roomFragment = RoomFragment.newInstance()
+// supportFragmentManager
+// .beginTransaction()
+// .replace(R.id.vp_room_pager, roomFragment!!)
+// .commitAllowingStateLoss()
// 使用新的 OnBackPressedDispatcher API 来处理返回事件
if (onBackPressedDispatcher != null) {
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
@@ -516,6 +518,7 @@ class RoomActivity : BaseMvpActivity(),
})
}
+
// 获取Application实例并设置监听器
val app = application as CommonAppContext
appStateListener = AppStateManager.getInstance()
@@ -526,7 +529,7 @@ class RoomActivity : BaseMvpActivity(),
appStateListener?.onRoomActivityCreated(this)
}
-
+ MessageListenerSingleton.getInstance().joinGroup(roomId)
// 处理房间数据
// handleRoomData();
SpUtil.saveMyRoomId(roomId)
@@ -583,6 +586,113 @@ class RoomActivity : BaseMvpActivity(),
override fun onSelfInfoUpdated(info: V2TIMUserFullInfo?) {}
}
+ private fun setview(resp: RoomInfoResp?) {
+ if (resp == null)
+ return
+ this.mRoomInfoResp = resp
+ val roomBean = resp.room_info
+ this.mRoomBean = roomBean
+ this.mRoomUserBean = resp.user_info
+ this.mRoomOwnerBean = resp.room_owner
+ this.mPitList = mRoomBean!!.pit_list
+
+ CommonAppContext.getInstance().isPlaying = true
+ CommonAppContext.getInstance().playId = roomId
+ CommonAppContext.getInstance().playName = mRoomBean!!.room_name
+
+ CommonAppContext.getInstance().playCover = resp.room_info.room_cover
+ CommonAppContext.getInstance().showSelf = resp.is_show_self == 1
+
+ ImageUtils.loadHeadCC(resp.room_info.room_cover, mBinding!!.roomTop.avatar)
+
+ mBinding!!.roomTop.name.text = roomBean.room_name
+ mBinding!!.roomTop.idVal.text = "ID:" + roomBean.room_number
+ if (mRoomUserBean?.getIs_room_owner() == 1) {
+ mBinding!!.roomTop.btnFollow.visibility = View.GONE
+ } else {
+ mBinding!!.roomTop.btnFollow.visibility = View.VISIBLE
+ if (resp.isCollect) {
+ mBinding!!.roomTop.btnFollow.background =
+ resources.getDrawable(com.xscm.moduleutil.R.mipmap.collected)
+ mBinding!!.roomTop.btnFollow.text = ""
+ }
+ }
+ number = roomBean.online_number
+ mBinding!!.roomTop.tvNum.text = number.toString() + ""
+ val userIds = StringBuilder()
+ for (i in mRoomInfoResp!!.room_info.pit_list.indices) {
+ val userId = mRoomInfoResp!!.room_info.pit_list[i].user_id
+ if (userId != null && userId != "0" && !userId.isEmpty()) {
+ if (userIds.length > 0) {
+ userIds.append(",")
+ }
+ userIds.append(userId)
+ }
+ }
+ initPublicScreenFragment()
+ // 确保Fragment已完全初始化后再调用getUpRoomInfo
+ if (publicScreenFragment != null && publicScreenFragment!!.isAdded && publicScreenFragment!!.view != null) {
+ publicScreenFragment!!.getUpRoomInfo(resp)
+ }
+ if (!isFinishing && !isDestroyed) {
+ resetFragment()
+ upHeight()
+ } else {
+ Log.e("Fragment", "Fragment transaction skipped due to state loss.")
+ }
+
+ if (mRoomUserBean?.getIs_collect() == 1) {
+ mBinding!!.roomTop.btnFollow.background =
+ resources.getDrawable(com.xscm.moduleutil.R.mipmap.yishouc)
+ mBinding!!.roomTop.btnFollow.text = ""
+ } else {
+ ThemeableDrawableUtils.setThemeableRoundedBackground(
+ mBinding!!.roomTop.btnFollow,
+ ColorManager.getInstance().primaryColorInt,
+ 53
+ )
+ mBinding!!.roomTop.btnFollow.setTextColor(ColorManager.getInstance().buttonColorInt)
+ mBinding!!.roomTop.btnFollow.text = "收藏"
+ }
+ if ((roomBean.type_id == "3" || roomBean.type_id == "1" || roomBean.type_id == "4") && roomBean.label_id == "2") {
+ AgoraManager.getInstance(this).isBjMusic = false
+ } else {
+ AgoraManager.getInstance(this).isBjMusic = true
+ }
+
+ AgoraManager.stopMuisc()
+ initializeAudio()
+
+ toutiao()
+ upRoomInfo(resp)
+
+ instView()
+
+ if (mRoomInfoResp!!.user_info.pit_number == 9 && mRoomInfoResp!!.user_info.user_id == SpUtil.getUserId()
+ .toString() + ""
+ ) {
+ mBinding!!.roomTop.rl.visibility = View.VISIBLE
+ ivSoundEffects(true)
+ } else {
+ mBinding!!.roomTop.rl.visibility = View.GONE
+ ivSoundEffects(false)
+ }
+
+ if (mRoomInfoResp!!.room_info.type_id == "7" || mRoomInfoResp!!.room_info.type_id == "2") {
+ mBinding!!.rlMore.visibility = View.GONE
+ mBinding!!.rlMisc.visibility = View.GONE
+ }
+ setupEffectView()
+
+ // 使用Handler延迟执行,确保Fragment视图已完全创建
+ Handler(Looper.getMainLooper()).post {
+ if (publicScreenFragment != null && publicScreenFragment!!.isAdded && publicScreenFragment!!.view != null) {
+ publicScreenFragment!!.getUpRoomInfo(resp)
+ }
+ }
+ }
+
+
private fun checkAndRestoreMinimizeState() {
val prefs = getSharedPreferences("room_minimize_state", Context.MODE_PRIVATE)
var isMinimized = prefs.getBoolean("is_minimized", false)
@@ -1185,17 +1295,7 @@ class RoomActivity : BaseMvpActivity(),
})
mBinding!!.roomTop.root.isClickable = false
- mBinding!!.roomTop.root.setOnClickListener {
- // ToastUtils.showShort("点击了房间,事件穿透");
- }
-
-// mBinding!!.clXsb.setOnClickListener {
-// val fragment = HourlyChartDialog.newInstance()
-// fragment.show(supportFragmentManager,"HourlyChartDialog")
-// if (fragment != null) {
-// addActiveDialogFragment(fragment) // 添加到管理列表
-// }
-// }
+ setview(mRoomInfoResp)
}
@@ -1222,7 +1322,7 @@ class RoomActivity : BaseMvpActivity(),
fun roomInfoEvent(messageEvent: RoomMessageEvent?) {
if (messageEvent == null) return
if (roomFragment == null) {
- roomFragment = RoomFragment.newInstance()
+ roomFragment = RoomFragment.newInstance(mRoomInfoResp)
supportFragmentManager
.beginTransaction()
.replace(R.id.vp_room_pager, roomFragment!!)
@@ -1239,15 +1339,29 @@ class RoomActivity : BaseMvpActivity(),
.dropLastWhile { it.isEmpty() }.toTypedArray()
)
QXGiftPlayerManager.getInstance(this).displayFullEffectView1(playQueue)
- if (messageEvent!!.text.giftInfo!=null) {
- var giftBean = messageEvent.text.giftInfo
- giftBean.nickname= messageEvent.text.fromUserInfo.nickname
- giftBean.userAvatar=messageEvent.text.fromUserInfo.avatar
- giftBean.senderName=messageEvent.text.toUserInfo.nickname
- giftBean.senderAvatarUrl=messageEvent.text.toUserInfo.avatar
- giftBean.number=messageEvent.text.gift_num.toInt()
- giftManager.receiveGift(giftBean)
- }
+// if(messageEvent?.text?.toUserInfos!=null){
+// for (i in messageEvent.text.toUserInfos.indices){
+// var giftBean = messageEvent.text.giftInfo
+// giftBean.nickname= messageEvent.text.fromUserInfo.nickname
+// giftBean.userAvatar=messageEvent.text.fromUserInfo.avatar
+// giftBean.senderName=messageEvent.text.toUserInfos.get(i).nickname
+// giftBean.senderAvatarUrl=messageEvent.text.toUserInfos.get(i).avatar
+//
+// giftBean.number=messageEvent.text.gift_num.toInt()
+// giftManager.receiveGift(giftBean)
+// }
+// }else {
+ if (messageEvent!!.text.giftInfo != null) {
+ var giftBean = messageEvent.text.giftInfo
+ giftBean.nickname = messageEvent.text.fromUserInfo.nickname
+ giftBean.userAvatar = messageEvent.text.fromUserInfo.avatar
+ LogUtils.e("1005", messageEvent.text.toUserInfo?.nickname)
+ giftBean.senderName = messageEvent.text.toUserInfo?.nickname
+ giftBean.senderAvatarUrl = messageEvent.text.toUserInfo?.avatar
+ giftBean.number = messageEvent.text.gift_num.toInt()
+ giftManager.receiveGift(giftBean)
+ }
+// }
hand1005(messageEvent, text)
} else if (msgType == 123) {
EventBus.getDefault().post(RoomSettingEvent())
@@ -1787,7 +1901,7 @@ class RoomActivity : BaseMvpActivity(),
private fun handleMsgType1003(messageEvent: RoomMessageEvent, text: T?) {
if (text == null || mRoomInfoResp == null || mRoomInfoResp!!.room_info == null) return
if (roomFragment == null) {
- roomFragment = RoomFragment.newInstance()
+ roomFragment = RoomFragment.newInstance(mRoomInfoResp)
supportFragmentManager
.beginTransaction()
.replace(R.id.vp_room_pager, roomFragment!!)
@@ -2648,13 +2762,13 @@ class RoomActivity : BaseMvpActivity(),
RoomManager.getInstance().exitRoom(roomId)
// 清理资源
cleanupResources()
- if (type == 1) {
- // 导航到首页
- navigateToMainPage()
- } else if (type == 2) {
- // 返回上一个页面
- finish()
- }
+// if (type == 1) {
+// // 导航到首页
+// navigateToMainPage()
+// } else if (type == 2) {
+// // 返回上一个页面
+// finish()
+// }
finish()
}
@@ -2685,14 +2799,6 @@ class RoomActivity : BaseMvpActivity(),
return false
}
- private fun navigateToMainPage() {
- ARouter.getInstance()
- .build(ARouteConstants.ME)
- .navigation()
-
- // 添加转场动画
- overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
- }
private fun quitUpRoom() {
// 清理最小化状态
@@ -3582,7 +3688,8 @@ class RoomActivity : BaseMvpActivity(),
override fun onResume() {
super.onResume()
-
+ if (true)
+ return
LogUtils.e("RoomActivity", "onResume")
CommonAppContext.getInstance().isShow = true
CommonAppContext.getInstance().isPlaying = true
@@ -3892,7 +3999,7 @@ class RoomActivity : BaseMvpActivity(),
val labelId = mRoomInfoResp!!.room_info.label_id
CommonAppContext.getInstance().lable_id = typeId
if (roomFragment == null) {
- roomFragment = RoomFragment.newInstance()
+ roomFragment = RoomFragment.newInstance(mRoomInfoResp)
supportFragmentManager
.beginTransaction()
.replace(R.id.vp_room_pager, roomFragment!!)
@@ -4081,8 +4188,8 @@ class RoomActivity : BaseMvpActivity(),
).show()
}
- override fun onDestroy() {
- LogUtils.e("RoomActivity", "onDestroy")
+ override fun finish() {
+ LogUtils.e("RoomActivity", "finish")
// 只有在真正退出房间时才清理最小化状态
if (!isMinimized) {
clearMinimizeState()
@@ -4094,63 +4201,64 @@ class RoomActivity : BaseMvpActivity(),
giftManager.clearAll()
mBinding!!.giftContainer.removeAllViews()
// 确保父类的 onDestroy 被调用
- super.onDestroy()
+ super.finish()
}
fun cleanupResources() {
sDestroied = true
- overridePendingTransition(0, 0)
- try {
- // 1. 清理 EventBus 注册
- if (EventBus.getDefault().isRegistered(this)) {
- EventBus.getDefault().unregister(this)
- }
+ Observable.create {
+ try {
+ // 1. 清理 EventBus 注册
+ if (EventBus.getDefault().isRegistered(this)) {
+ EventBus.getDefault().unregister(this)
+ }
- // 2. 清理 Handler 回调
- if (roomSwitchHandler != null) {
- roomSwitchHandler.removeCallbacksAndMessages(null)
- }
+ // 2. 清理 Handler 回调
+ if (roomSwitchHandler != null) {
+ roomSwitchHandler.removeCallbacksAndMessages(null)
+ }
- // 3. 清理 CountDownTimer
- releaseCountDownTimer()
- releaseCountDownTimer1()
- if (giftCountTimer != null) {
- giftCountTimer!!.cancel()
- giftCountTimer = null
- }
+ // 3. 清理 CountDownTimer
+ releaseCountDownTimer()
+ releaseCountDownTimer1()
+ if (giftCountTimer != null) {
+ giftCountTimer!!.cancel()
+ giftCountTimer = null
+ }
- // 4. 清理 SVGA 资源
- clearSVGAResources()
+ // 4. 清理 SVGA 资源
+ clearSVGAResources()
- // 5. 清理自定义悬浮窗
- if (customMusicFloatingView != null) {
- customMusicFloatingView!!.destroy()
- customMusicFloatingView = null
- }
+ // 5. 清理自定义悬浮窗
+ if (customMusicFloatingView != null) {
+ customMusicFloatingView!!.destroy()
+ customMusicFloatingView = null
+ }
- // 6. 清理 Agora 资源
+ // 6. 清理 Agora 资源
// if (AgoraManager.getInstance(this) != null) {
// AgoraManager.getInstance(this).cleanup();
// }
// 清理所有弹框
- dismissAllDialogs()
- // 7. 清理 Fragment
- cleanupFragments()
+ dismissAllDialogs()
+ // 7. 清理 Fragment
+ cleanupFragments()
- // 8. 清理监听器
- if (mBinding != null) {
- // 移除所有 OnClickListener 防止内存泄漏
- clearClickListeners()
- }
- ThreadUtils.cancel()
- QXGiftPlayerManager.getInstance(applicationContext).destroyEffectSvga()
- stopkeepLiveService() //停止service
- CommonAppContext.getInstance().onlineMap.clear()
+ // 8. 清理监听器
+ if (mBinding != null) {
+ // 移除所有 OnClickListener 防止内存泄漏
+ clearClickListeners()
+ }
+ ThreadUtils.cancel()
+ QXGiftPlayerManager.getInstance(applicationContext).destroyEffectSvga()
+ stopkeepLiveService() //停止service
+ CommonAppContext.getInstance().onlineMap.clear()
// ImageUtils.clearDiskCache(this)
- } catch (e: Exception) {
- LogUtils.e("cleanupResources error: " + e.message)
- }
+ } catch (e: Exception) {
+ LogUtils.e("cleanupResources error: " + e.message)
+ }
+ }.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe()
}
/**
diff --git a/moduleroom/src/main/java/com/example/moduleroom/adapter/EaseChatAdapter.java b/moduleroom/src/main/java/com/example/moduleroom/adapter/EaseChatAdapter.java
index b94bb3ae..5ed426df 100644
--- a/moduleroom/src/main/java/com/example/moduleroom/adapter/EaseChatAdapter.java
+++ b/moduleroom/src/main/java/com/example/moduleroom/adapter/EaseChatAdapter.java
@@ -43,6 +43,7 @@ import com.xscm.moduleutil.bean.room.EMMessageInfo;
import com.xscm.moduleutil.utils.ColorManager;
import com.xscm.moduleutil.utils.ImageUtils;
import com.xscm.moduleutil.utils.logger.Logger;
+import com.xscm.moduleutil.widget.AdaptiveImageView;
import com.xscm.moduleutil.widget.GifAvatarOvalView;
import com.xscm.moduleutil.widget.img.BubbleBackgroundHelper;
@@ -74,7 +75,7 @@ public class EaseChatAdapter extends BaseMultiItemQuickAdapter() {
@@ -271,83 +270,115 @@ public class EaseChatAdapter extends BaseMultiItemQuickAdapter() {
@Override
- public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
- // 加载完成后执行
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- // 清除 Glide 缓存
-// Glide.get(mContext).clearDiskCache();
-
- // 更换图片
- Glide.with(mContext)
- .load(emMessage.getText().getEmoji().getImage())
- .into((ImageView) helper.getView(com.xscm.moduleutil.R.id.im_emj));
- }
- }, 1500);
+ public boolean onResourceReady(Drawable resource, Object model, Target target,
+ DataSource dataSource, boolean isFirstResource) {
+ // 检查视图是否仍属于当前数据项
+ if (uniqueId.equals(emojiImageView.getTag())) {
+ // 加载完成后执行
+ new Handler().postDelayed(() -> {
+ // 再次检查视图状态
+ if (uniqueId.equals(emojiImageView.getTag())) {
+ Glide.with(mContext)
+ .load(emMessage.getText().getEmoji().getImage())
+ .into(emojiImageView);
+ }
+ }, 1500);
+ }
return false;
}
@Override
- public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
+ public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target,
+ boolean isFirstResource) {
return false;
}
})
- .into((ImageView) helper.getView(com.xscm.moduleutil.R.id.im_emj));
- // 设置标签,避免重复加载
- helper.getView(com.xscm.moduleutil.R.id.im_emj).setTag(emMessage.getText().getEmoji().getAnimate_image());
+ .into(emojiImageView);
} else {
helper.getView(com.xscm.moduleutil.R.id.tv_content).setVisibility(View.VISIBLE);
- helper.getView(com.xscm.moduleutil.R.id.im_emj).setVisibility(View.GONE);
+ emojiImageView.setVisibility(View.GONE);
}
break;
case 3:
- if (emMessage.getText().getFromUserInfo() != null && emMessage.getText().getFromUserInfo().getChat_bubble() != null && !emMessage.getText().getFromUserInfo().getChat_bubble().isEmpty()) {
- helper.getView(com.xscm.moduleutil.R.id.bubble).setBackgroundResource(com.xscm.moduleutil.R.mipmap.qipaokang);
- } else {
- helper.getView(com.xscm.moduleutil.R.id.bubble).setBackgroundResource(com.xscm.moduleutil.R.drawable.ease_row_pubilc_user_bg);
- }
- if (emMessage.getText().getFromUserInfo() != null && emMessage.getText().getFromUserInfo().getAvatar() != null) {
- ImageUtils.loadHeadCC(emMessage.getText().getFromUserInfo().getAvatar(), helper.getView(com.xscm.moduleutil.R.id.avatar));
- }
- helper.setText(com.xscm.moduleutil.R.id.tv_name, emMessage.getText().getFromUserInfo().getNickname());
+// if (emMessage.getText().getFromUserInfo().getChat_bubble() != null && !emMessage.getText().getFromUserInfo().getChat_bubble().isEmpty()) {
+//// helper.getView(com.xscm.moduleutil.R.id.bubble).setBackgroundResource(com.xscm.moduleutil.R.mipmap.qipaokang);
+//// ImageUtils.loadHeadCC(emMessage.getText().getFromUserInfo().getChat_bubble(), helper.getView(com.xscm.moduleutil.R.id.network_background));
+//
+// // 使用 Glide 加载图片并设置名称
+// String imageUrl = emMessage.getText().getFromUserInfo().getChat_bubble();
+//
+// Glide.with(mContext)
+// .load(imageUrl)
+// .into(new SimpleTarget() {
+// @Override
+// public void onResourceReady(@NonNull Drawable resource, @Nullable Transition super Drawable> transition) {
+// // 将资源转换为 Bitmap
+// if (resource instanceof BitmapDrawable) {
+// Bitmap bitmap = ((BitmapDrawable) resource).getBitmap();
+// // 创建新的文件名
+// Drawable fakeNinePatch = new FakeNinePatchDrawable(bitmap, 0.4f, 0.4f, 0.6f, 0.5f);
+//
+// // 保存图片到本地
+// helper.getView(com.xscm.moduleutil.R.id.bubble).setBackground(fakeNinePatch);
+// }
+// }
+//
+// @Override
+// public void onLoadFailed(@Nullable Drawable errorDrawable) {
+// // 加载失败处理
+// }
+// });
+// } else {
+ helper.getView(com.xscm.moduleutil.R.id.bubble1).setBackgroundResource(com.xscm.moduleutil.R.drawable.ease_row_pubilc_user_bg);
+// }
+// if (emMessage.getText().getFromUserInfo() != null && emMessage.getText().getFromUserInfo().getAvatar() != null) {
+// ImageUtils.loadHeadCC(emMessage.getText().getFromUserInfo().getAvatar(), helper.getView(com.xscm.moduleutil.R.id.avatar));
+// }
+// helper.setText(com.xscm.moduleutil.R.id.tv_name, emMessage.getText().getFromUserInfo().getNickname());
// helper.setText(com.xscm.moduleutil.R.id.tv_content, emMessage.getText().getText());
helper.setText(com.xscm.moduleutil.R.id.tv_content, getSpannable(emMessage));
- List images1 = emMessage.getText().getFromUserInfo().getIcon();
- LinearLayout ll_images1 = helper.getView(com.xscm.moduleutil.R.id.line);
- ll_images1.removeAllViews();
-// tv_content.setTextColor(ColorManager.getInstance().getPrimaryColorInt());
- if (images1 == null) {
- return;
- }
- for (String url : images1) {
- if (url.contains("http")) {
- ImageView imageView = new ImageView(helper.itemView.getContext());
- LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
- helper.itemView.getContext().getResources().getDimensionPixelSize(com.xscm.moduleutil.R.dimen.dp_74),
- helper.itemView.getContext().getResources().getDimensionPixelSize(com.xscm.moduleutil.R.dimen.dp_17)
- );
- params.setMargins(0, 0, helper.itemView.getContext().getResources().getDimensionPixelSize(com.xscm.moduleutil.R.dimen.dp_5), 0); // 右边距
- imageView.setLayoutParams(params);
- imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
- // 使用 Glide 加载图片
- ImageUtils.loadHeadCC(url, imageView);
- ll_images1.addView(imageView);
- }
- }
+// List images1 = emMessage.getText().getFromUserInfo().getIcon();
+// LinearLayout ll_images1 = helper.getView(com.xscm.moduleutil.R.id.line);
+// ll_images1.removeAllViews();
+// if (images1 == null) {
+// return;
+// }
+// for (String url : images1) {
+// if (url.contains("http")) {
+// ImageView imageView = new ImageView(helper.itemView.getContext());
+// LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
+// helper.itemView.getContext().getResources().getDimensionPixelSize(com.xscm.moduleutil.R.dimen.dp_57),
+// helper.itemView.getContext().getResources().getDimensionPixelSize(com.xscm.moduleutil.R.dimen.dp_15)
+// );
+// params.setMargins(0, 0, helper.itemView.getContext().getResources().getDimensionPixelSize(com.xscm.moduleutil.R.dimen.dp_5), 0); // 右边距
+// imageView.setLayoutParams(params);
+// imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
+// // 使用 Glide 加载图片
+// ImageUtils.loadHeadCC(url, imageView);
+// ll_images1.addView(imageView);
+// }
+// }
break;
// case 4:
@@ -546,28 +577,29 @@ public class EaseChatAdapter extends BaseMultiItemQuickAdapter 10) {
+ continue;
+ }
+ RoomFriendshipWheatView object = mWheatViews.get(Integer.parseInt(roomPitBean.getPit_number()) - 1);
+ if (object != null) {
+ object.setData(roomPitBean);
+ } else {
+ continue;
+ }
+ }
+
+ if (roomInfoResp.getUser_info().getPit_number() > 0) {
+ myPitNumber = roomInfoResp.getUser_info().getPit_number();
+ } else {
+ myPitNumber = -1;
+ }
+ tzblChanged();
+ updateFriendshipState(FriendshipPartType.fromValue(roomInfoResp.getFriend_info().getStep()));
+ configGameOptionBtn();
+ configTime();
+ configHeart();
+ configPowerBtn();
+ initUserViewMap();
}
protected void tzblChanged() {
diff --git a/moduleroom/src/main/java/com/example/moduleroom/fragment/RankingChildFragment.java b/moduleroom/src/main/java/com/example/moduleroom/fragment/RankingChildFragment.java
index 62a4c871..4d18422e 100644
--- a/moduleroom/src/main/java/com/example/moduleroom/fragment/RankingChildFragment.java
+++ b/moduleroom/src/main/java/com/example/moduleroom/fragment/RankingChildFragment.java
@@ -223,8 +223,8 @@ public class RankingChildFragment extends BaseMvpFragment implements RoomContacts.View {
- public static RoomFragment newInstance() {
+ public static RoomFragment newInstance(RoomInfoResp resp) {
Bundle args = new Bundle();
- RoomFragment fragment = new RoomFragment();
+ RoomFragment fragment = new RoomFragment(resp);
fragment.setArguments(args);
return fragment;
}
+ public RoomFragment(){
+
+ }
+ public RoomFragment(RoomInfoResp roomInfoResp){
+ this.mRoomInfoResp = roomInfoResp;
+ }
+
private RoomInfoResp mRoomInfoResp;
private String password;
private String roomId;
@@ -92,17 +99,31 @@ public class RoomFragment extends BaseMvpFragment {
-// if (data != null) {
-// // 处理接收到的数据
-// refreshData(data, qxRoomSeatViewType);
-// // 可选:清除数据以避免重复处理
-// // sharedViewModel.clearData();
-// }
-// });
-// sharedViewModel.getSeatViewType().observe(getViewLifecycleOwner(), type -> {
-// if (type != null) {
-// // 处理数据
-// setqxRoomSeatViewType(type);
-// }
-// });
+ setRoomSeatViewType();
+ upRoomInfo(mRoomInfoResp);
return super.onCreateView(inflater, container, savedInstanceState);
}
@@ -210,7 +212,7 @@ public class RoomFragment extends BaseMvpFragment {
- if (mRoomInfoResp != null && mRoomInfoResp.getRoom_info() != null) {
- String typeId = mRoomInfoResp.getRoom_info().getType_id();
- String labelId = mRoomInfoResp.getRoom_info().getLabel_id();
+// getView().post(() -> {
+ if (mRoomInfoResp != null && mRoomInfoResp.getRoom_info() != null) {
+ String typeId = mRoomInfoResp.getRoom_info().getType_id();
+ String labelId = mRoomInfoResp.getRoom_info().getLabel_id();
- if ("7".equals(typeId)) {
- FriendshipRoomFragment friendshipRoomFragment = findFragmentByTag(FriendshipRoomFragment.class);
- if (friendshipRoomFragment != null && friendshipRoomFragment.isAdded()) {
- friendshipRoomFragment.roomInfoUpdate(mRoomInfoResp);
+ if ("7".equals(typeId)) {
+ if (friendshipRoomFragment != null && friendshipRoomFragment.isAdded()) {
+ friendshipRoomFragment.roomInfoUpdate(mRoomInfoResp);
// sharedViewModel.setChildFragmentData(mRoomInfoResp);
- }
- } else if ("2".equals(typeId)) {
- RoomAuctionFragment auctionRoomFragment = findFragmentByTag(RoomAuctionFragment.class);
- if (auctionRoomFragment != null && auctionRoomFragment.isAdded()) {
- auctionRoomFragment.roomInfoUpdate(mRoomInfoResp);
+ }
+ } else if ("2".equals(typeId)) {
+ if (roomAuctionFragment != null && roomAuctionFragment.isAdded()) {
+ roomAuctionFragment.roomInfoUpdate(mRoomInfoResp);
// sharedViewModel.setChildFragmentData(mRoomInfoResp);
- }
- } else if ("1".equals(typeId) || "3".equals(typeId) || "4".equals(typeId) || "8".equals(typeId)) {
- if ("2".equals(labelId)) {
- RoomKtvFragment roomKtvFragment = findFragmentByTag(RoomKtvFragment.class);
- if (roomKtvFragment != null && roomKtvFragment.isAdded()) {
- roomKtvFragment.roomInfoUpdate(mRoomInfoResp);
+ }
+ } else if ("1".equals(typeId) || "3".equals(typeId) || "4".equals(typeId) || "8".equals(typeId)) {
+ if ("2".equals(labelId)) {
+ if (ktvFragment != null && ktvFragment.isAdded()) {
+ ktvFragment.roomInfoUpdate(mRoomInfoResp);
// sharedViewModel.setChildFragmentData(mRoomInfoResp);
- }
- } else if ("1".equals(labelId)) {
- SingSongFragment singSongFragment = findFragmentByTag(SingSongFragment.class);
- if (singSongFragment != null && singSongFragment.isAdded()) {
- singSongFragment.roomInfoUpdate(mRoomInfoResp);
+ }
+ } else if ("1".equals(labelId)) {
+ if (singSongFragment != null && singSongFragment.isAdded()) {
+ singSongFragment.roomInfoUpdate(mRoomInfoResp);
// sharedViewModel.setDataForFragment(mRoomInfoResp);
// sharedViewModel.setChildFragmentData(mRoomInfoResp);
- }
- }
- } else if ("6".equals(typeId)) {
- RoomCabinFragment roomCabinFragment = findFragmentByTag(RoomCabinFragment.class);
- if (roomCabinFragment != null && roomCabinFragment.isAdded()) {
- roomCabinFragment.roomInfoUpdate(mRoomInfoResp);
-// sharedViewModel.setChildFragmentData(mRoomInfoResp);
}
}
-
+ } else if ("6".equals(typeId)) {
+ if (roomCabinFragment != null && roomCabinFragment.isAdded()) {
+ roomCabinFragment.roomInfoUpdate(mRoomInfoResp);
+// sharedViewModel.setChildFragmentData(mRoomInfoResp);
+ }
}
- });
+
+ }
+// });
}
@@ -653,91 +650,6 @@ public class RoomFragment extends BaseMvpFragment updateChildFragmentViews());
-//// }
-//
-//// if (getActivity() instanceof RoomActivity) {
-//// if (mRoomInfoResp.getRoom_info().getType_id().equals("6")) {
-//// ((RoomActivity) getActivity()).changeBackground(com.xscm.moduleutil.R.mipmap.cabin_bj);
-//// ((RoomActivity) getActivity()).setvisibTop(false);
-//// } else if (mRoomInfoResp.getRoom_info().getType_id().equals("7")) {
-//// if (mRoomInfoResp.getRoom_info().getRoom_background() == null || mRoomInfoResp.getRoom_info().getRoom_background().equals("")) {
-//// ((RoomActivity) getActivity()).changeBackground(com.xscm.moduleutil.R.mipmap.jiaoy_bj);
-//// } else {
-//// ((RoomActivity) getActivity()).changeBackgroundColor(mRoomInfoResp.getRoom_info().getRoom_background());
-//// }
-//// ((RoomActivity) getActivity()).setvisibTop(true);
-//// } else {
-//// ((RoomActivity) getActivity()).changeBackgroundColor(mRoomInfoResp.getRoom_info().getRoom_background());
-//// ((RoomActivity) getActivity()).setvisibTop(true);
-//// }
-//// }
-//
-// updateChildFragmentViews();
}
private void performLoadSubFragment(QXRoomSeatViewType qxRoomSeatViewType) {
this.qxRoomSeatViewType = qxRoomSeatViewType;
@@ -749,44 +661,44 @@ public class RoomFragment extends BaseMvpFragment {
- if (mRoomInfoResp != null && mRoomInfoResp.getRoom_info() != null) {
- String typeId = mRoomInfoResp.getRoom_info().getType_id();
- String labelId = mRoomInfoResp.getRoom_info().getLabel_id();
-
- if ("7".equals(typeId)) {
- FriendshipRoomFragment friendshipRoomFragment = findFragmentByTag(FriendshipRoomFragment.class);
- if (friendshipRoomFragment != null && friendshipRoomFragment.isAdded()) {
- friendshipRoomFragment.upRoomInfo(mRoomInfoResp);
- }
- } else if ("2".equals(typeId)) {
- RoomAuctionFragment auctionRoomFragment = findFragmentByTag(RoomAuctionFragment.class);
- if (auctionRoomFragment != null && auctionRoomFragment.isAdded()) {
- auctionRoomFragment.upRoomInfo(mRoomInfoResp);
- }
- } else if ("1".equals(typeId) || "3".equals(typeId) || "4".equals(typeId) || "8".equals(typeId)) {
- if ("2".equals(labelId)) {
- RoomKtvFragment roomKtvFragment = findFragmentByTag(RoomKtvFragment.class);
- if (roomKtvFragment != null && roomKtvFragment.isAdded()) {
- roomKtvFragment.upRoomInfo(mRoomInfoResp);
- }
- } else if ("1".equals(labelId)) {
- SingSongFragment singSongFragment = findFragmentByTag(SingSongFragment.class);
- if (singSongFragment != null && singSongFragment.isAdded()) {
- singSongFragment.upRoomInfo(mRoomInfoResp);
- }
- }
- } else if ("6".equals(typeId)) {
- RoomCabinFragment roomCabinFragment = findFragmentByTag(RoomCabinFragment.class);
- if (roomCabinFragment != null && roomCabinFragment.isAdded()) {
- roomCabinFragment.upRoomInfo(mRoomInfoResp);
- }
- }
- }
- });
- }
public void setview() {//这里是当进入电影放房的时候,如果是排麦模式,并且不是电影放的时候,就隐藏排麦视图
- if (mRoomInfoResp.getRoom_info().getRoom_up_pit_type().equals("1") && !mRoomInfoResp.getRoom_info().getType_id().equals("6")) {
-// mBinding.clFirstCharge.setVisibility(View.VISIBLE);
- if (getActivity() instanceof RoomActivity) {
+ if (getActivity() instanceof RoomActivity){
+ if (mRoomInfoResp.getRoom_info().getRoom_up_pit_type().equals("1") && !mRoomInfoResp.getRoom_info().getType_id().equals("6")) {
((RoomActivity) getActivity()).clFirstCharge(true);
+ } else {
+ ((RoomActivity) getActivity()).clFirstCharge(false);
}
- } else {
-// mBinding.clFirstCharge.setVisibility(View.GONE);
- ((RoomActivity) getActivity()).clFirstCharge(false);
}
-
}
@Subscribe(threadMode = ThreadMode.MAIN)
diff --git a/moduleroom/src/main/java/com/example/moduleroom/fragment/RoomKtvFragment.java b/moduleroom/src/main/java/com/example/moduleroom/fragment/RoomKtvFragment.java
index 3102e2d5..67bb2364 100644
--- a/moduleroom/src/main/java/com/example/moduleroom/fragment/RoomKtvFragment.java
+++ b/moduleroom/src/main/java/com/example/moduleroom/fragment/RoomKtvFragment.java
@@ -68,11 +68,14 @@ public class RoomKtvFragment extends BaseMvpFragment adapter;
private RoomOnline online;
+ public RoomKtvFragment() {}
+ public RoomKtvFragment(RoomInfoResp roomInfoResp) {
+ this.roomInfoResp = roomInfoResp;
+ }
- public static RoomKtvFragment newInstance() {
- RoomKtvFragment fragment = new RoomKtvFragment();
+ public static RoomKtvFragment newInstance(RoomInfoResp roomInfoResp) {
+ RoomKtvFragment fragment = new RoomKtvFragment(roomInfoResp);
Bundle args = new Bundle();
-// args.putSerializable("roomInfo", roomInfoResp);
fragment.setArguments(args);
return fragment;
}
diff --git a/moduleroom/src/main/java/com/example/moduleroom/fragment/SingSongFragment.java b/moduleroom/src/main/java/com/example/moduleroom/fragment/SingSongFragment.java
index 323f12b9..8e10a6a4 100644
--- a/moduleroom/src/main/java/com/example/moduleroom/fragment/SingSongFragment.java
+++ b/moduleroom/src/main/java/com/example/moduleroom/fragment/SingSongFragment.java
@@ -74,6 +74,8 @@ import com.xscm.moduleutil.widget.WheatLayoutManager;
import com.xscm.moduleutil.widget.WheatLayoutSingManager;
import com.xscm.moduleutil.widget.dialog.CommonDialog;
+import io.reactivex.Observable;
+import io.reactivex.android.schedulers.AndroidSchedulers;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
@@ -82,6 +84,7 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
+import java.util.concurrent.TimeUnit;
/**
* @author qx
@@ -109,13 +112,20 @@ public class SingSongFragment extends BaseRoomFragment pitList;
private SharedViewModel sharedViewModel;
- public static SingSongFragment newInstance() {
+ public static SingSongFragment newInstance(RoomInfoResp roomInfoResp) {
Bundle args = new Bundle();
- SingSongFragment fragment = new SingSongFragment();
+ SingSongFragment fragment = new SingSongFragment(roomInfoResp);
fragment.setArguments(args);
return fragment;
}
+
+ public SingSongFragment() {
+ }
+
+ public SingSongFragment(RoomInfoResp roomInfoResp) {
+ this.roomInfoResp = roomInfoResp;
+ }
@Override
public void initArgs(Bundle arguments) {
super.initArgs(arguments);
@@ -131,21 +141,30 @@ public class SingSongFragment extends BaseRoomFragment {
+ upDtaView(true);
+ });
+ Observable.timer(500, TimeUnit.MILLISECONDS)
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(aLong -> {
+ upDtaView(false);
+ });
}
public void upRoomInfo(RoomInfoResp roomInfoResp) {
this.roomInfoResp = roomInfoResp;
}
- private void upDtaView() {
+ private void upDtaView(boolean isFirst) {
pitList = new ArrayList<>();
if (getActivity() instanceof RoomActivity) {
((RoomActivity) getActivity()).setvisibTop(true);
}
// 初始化 PopupWindow
initPopupWindow();
- isWhether();
+ isWhether2(isFirst);
parentFragment = (RoomFragment) getParentFragment();
}
@@ -162,6 +181,7 @@ public class SingSongFragment extends BaseRoomFragment
diff --git a/modulevocal/src/main/AndroidManifest.xml b/modulevocal/src/main/AndroidManifest.xml
index 3d07d092..723426a3 100644
--- a/modulevocal/src/main/AndroidManifest.xml
+++ b/modulevocal/src/main/AndroidManifest.xml
@@ -13,133 +13,133 @@
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
+ />
diff --git a/modulevocal/src/main/java/com/example/modulevocal/adapter/BlackAdapter.java b/modulevocal/src/main/java/com/example/modulevocal/adapter/BlackAdapter.java
index 874cb95b..a7d7a0f3 100644
--- a/modulevocal/src/main/java/com/example/modulevocal/adapter/BlackAdapter.java
+++ b/modulevocal/src/main/java/com/example/modulevocal/adapter/BlackAdapter.java
@@ -100,8 +100,8 @@ public class BlackAdapter extends BaseQuickAdapter
-
-
-
\ No newline at end of file
diff --git a/modulevocal/src/main/res/values/themes.xml b/modulevocal/src/main/res/values/themes.xml
deleted file mode 100644
index 46ca6c9a..00000000
--- a/modulevocal/src/main/res/values/themes.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/modulevoice/src/main/AndroidManifest.xml b/modulevoice/src/main/AndroidManifest.xml
index 52d29332..ac98997e 100644
--- a/modulevoice/src/main/AndroidManifest.xml
+++ b/modulevoice/src/main/AndroidManifest.xml
@@ -8,12 +8,12 @@
android:theme="@style/BaseAppTheme">
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/dp_48"
+ android:layout_marginTop="@dimen/dp_10"
+ android:gravity="center_vertical"
+ android:background="@mipmap/item_ranking_bj"
+ android:orientation="horizontal">
+ android:id="@+id/tv_no"
+ android:layout_width="@dimen/dp_38"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:textColor="@color/white"
+ android:textSize="@dimen/sp_12"
+ tools:text="1"/>
+ android:id="@+id/riv_avatar"
+ android:layout_width="@dimen/dp_36"
+ android:layout_height="@dimen/dp_36"
+ android:src="@color/color_FF88CF"
+ app:riv_border_color="#FFFA447D"
+ app:gav_border_color="#FFFA447D"
+ app:riv_oval="true"
+ tools:visibility="gone"
+ />
-
+
+ android:id="@+id/iv_three_cp1_head"
+ android:layout_width="@dimen/dp_30"
+ android:layout_height="@dimen/dp_30"
+ android:src="@color/white"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"/>
+ android:id="@+id/iv_three_cp2_head"
+ android:layout_width="@dimen/dp_30"
+ android:layout_height="@dimen/dp_30"
+ android:layout_toRightOf="@+id/iv_three_cp1_head"
+ android:src="@color/white"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
-
-
+ android:layout_width="@dimen/dp_60"
+ android:layout_height="@dimen/dp_30"
+ android:src="@mipmap/cp_pt"
+ android:visibility="visible"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"/>
+
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+ android:id="@+id/tv_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxLength="6"
+ android:paddingStart="@dimen/dp_10"
+ android:paddingEnd="@dimen/dp_5"
+ android:textColor="@color/white"
+ android:textSize="@dimen/sp_14"
+ tools:text="利力星"/>
+ android:id="@+id/bnv_rank_list"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/dp_10"
+ android:visibility="gone"/>
+
+
+ android:id="@+id/iv_vip"
+ android:layout_width="@dimen/dp_24"
+ android:layout_height="@dimen/dp_24"
+ android:scaleType="fitCenter"
+ android:visibility="gone"/>
+ android:id="@+id/iv_level"
+ android:layout_width="@dimen/dp_30"
+ android:layout_height="@dimen/dp_24"
+ android:scaleType="fitCenter"
+ android:visibility="gone"/>
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"/>
+ android:id="@+id/tv_charm"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/dp_7"
+ android:layout_marginRight="@dimen/dp_14"
+ android:drawableStart="@mipmap/f_h"
+ android:gravity="center"
+ android:paddingLeft="@dimen/dp_25"
+ android:paddingRight="@dimen/dp_5"
+ android:paddingBottom="@dimen/dp_2"
+ android:textColor="@color/white"
+ android:textSize="@dimen/sp_9"
+ app:layout_constraintEnd_toEndOf="@id/view_top2"
+ app:layout_constraintTop_toTopOf="@id/view_top2"
+ tools:text="6777"/>
\ No newline at end of file
diff --git a/modulevoice/src/main/res/layout/ranking_list.xml b/modulevoice/src/main/res/layout/ranking_list.xml
index bbaf215a..f43509f7 100644
--- a/modulevoice/src/main/res/layout/ranking_list.xml
+++ b/modulevoice/src/main/res/layout/ranking_list.xml
@@ -1,813 +1,1348 @@
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ xmlns:tools="http://schemas.android.com/tools"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ tools:ignore="ResourceName">
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
+
+
+ android:id="@+id/im_user1"
+ android:layout_width="@dimen/dp_66"
+ android:layout_height="@dimen/dp_66"
+ tools:src="@mipmap/ic_launcher"
+ app:layout_constraintStart_toStartOf="@+id/im_rank_top_gj"
+ app:layout_constraintEnd_toEndOf="@+id/im_rank_top_gj"
+ app:layout_constraintTop_toTopOf="@+id/im_rank_top_gj"
+ android:layout_marginTop="@dimen/dp_49"
+ app:riv_oval="true"
+ tools:visibility="gone"/>
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
-
-
-
-
-
-
-
-
-
-
-
+ android:textColor="@color/white"
+ android:textSize="@dimen/sp_13"
+ tools:text="烟花"
+ app:layout_constraintHorizontal_bias="1.0"
+ tools:visibility="gone"/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ tools:text="ID:15426532"
+ tools:visibility="gone"/>
-
- >
-
-
-
-
-
-
-
-
-
+ android:textColor="@color/white"
+ android:textSize="@dimen/sp_9"
+ android:minWidth="@dimen/dp_30"
+ android:paddingStart="@dimen/dp_4"
+ android:paddingEnd="@dimen/dp_4"
+ android:maxWidth="@dimen/dp_51"
+ tools:text="9070"
+ app:layout_constraintBottom_toBottomOf="@+id/im_user2"
+ app:layout_constraintStart_toStartOf="@+id/im_user2"
+ app:layout_constraintEnd_toEndOf="@+id/im_user2"
+ tools:visibility="gone"
+ />
-
+
-
-
-
-
-
-
-
+ android:textColor="#5E4300"
+ android:textSize="@dimen/sp_9"
+ tools:text="ID:15426532"
+ tools:visibility="gone"/>
-
+
+
+ android:textColor="@color/white"
+ android:textSize="@dimen/sp_9"
+ android:minWidth="@dimen/dp_30"
+ android:paddingStart="@dimen/dp_4"
+ android:paddingEnd="@dimen/dp_4"
+ android:maxWidth="@dimen/dp_51"
+ tools:text="9070"
+ app:layout_constraintBottom_toBottomOf="@+id/im_user3"
+ app:layout_constraintStart_toStartOf="@+id/im_user3"
+ app:layout_constraintEnd_toEndOf="@+id/im_user3"
+ tools:visibility="gone"/>
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+ tools:text="烟花"
+ app:layout_constraintHorizontal_bias="1.0"
+ android:visibility="gone"
+ tools:visibility="visible"
+ />
-
+
-
+ android:id="@+id/iv_three_cp1_head"
+ android:layout_width="@dimen/dp_32"
+ android:layout_height="@dimen/dp_32"
+ android:layout_marginStart="@dimen/dp_3"
+ app:layout_constraintTop_toTopOf="@+id/im_cp3"
+ app:layout_constraintStart_toStartOf="@+id/im_cp3"
+ app:layout_constraintBottom_toBottomOf="@+id/im_cp3"
+ tools:src="@mipmap/ic_launcher"
+ android:visibility="gone"
+ tools:visibility="visible"
-
+ />
+ android:id="@+id/iv_three_cp2_head"
+ android:layout_width="@dimen/dp_32"
+ android:layout_height="@dimen/dp_32"
+ android:layout_marginEnd="@dimen/dp_3"
+ app:layout_constraintTop_toTopOf="@+id/im_cp3"
+ app:layout_constraintEnd_toEndOf="@+id/im_cp3"
+ app:layout_constraintBottom_toBottomOf="@+id/im_cp3"
+ tools:src="@mipmap/ic_launcher"
+ android:visibility="gone"
+ tools:visibility="visible"
+ />
-
-
-
-
+ android:id="@+id/im_cp3"
+ android:layout_width="0dp"
+ android:layout_height="@dimen/dp_36"
+ android:layout_marginTop="@dimen/dp_30"
+ android:layout_marginStart="@dimen/dp_20"
+ android:layout_marginEnd="@dimen/dp_20"
+ android:src="@mipmap/cp_tx_k"
+ android:scaleType="fitCenter"
+ app:layout_constraintTop_toTopOf="@+id/im_rank_top_jj"
+ app:layout_constraintStart_toStartOf="@id/im_rank_top_jj"
+ app:layout_constraintEnd_toEndOf="@id/im_rank_top_jj"
+ android:visibility="gone"
+ tools:visibility="visible"/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:layout_height="@dimen/dp_14"
+ android:background="@mipmap/ranking_za_hr"
+ android:gravity="center"
+ android:textColor="@color/white"
+ android:textSize="@dimen/sp_9"
+ android:minWidth="@dimen/dp_10"
+ android:maxWidth="@dimen/dp_30"
+ android:layout_marginBottom="-7dp"
+ tools:text="90"
+ app:layout_constraintBottom_toBottomOf="@+id/im_cp3"
+ app:layout_constraintStart_toStartOf="@+id/im_cp3"
+ app:layout_constraintEnd_toEndOf="@+id/im_cp3"
+ android:visibility="gone"
+ tools:visibility="visible"
+ />
-
+
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ android:id="@+id/recycle_view"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:paddingBottom="@dimen/dp_68"
+ android:layout_marginStart="@dimen/dp_16"
+ android:layout_marginEnd="@dimen/dp_16"
+ app:layout_constraintEnd_toEndOf="parent"
+ android:layout_marginTop="-12dp"
+ app:layout_constraintHorizontal_bias="0.0"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/im_rank_top_bj"
+ app:layout_constraintVertical_bias="1.0"/>
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+ android:paddingRight="@dimen/dp_20"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent">
-
+ >
-
+ app:riv_oval="true"/>
-
+ tools:text="Alan Bates"/>
-
-
+ tools:text="9070"/>
+
-
-
-
-
+ android:visibility="visible"/>
-
+ tools:text="Alan Bates"/>
-
+ tools:text="ID:"/>
-
-
-
+
-
+ tools:text="距上榜差 1232"/>
-
-
+
-
+
diff --git a/modulevoice/src/main/res/values-night/themes.xml b/modulevoice/src/main/res/values-night/themes.xml
deleted file mode 100644
index 1c850379..00000000
--- a/modulevoice/src/main/res/values-night/themes.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/modulevoice/src/main/res/values/themes.xml b/modulevoice/src/main/res/values/themes.xml
deleted file mode 100644
index 46ca6c9a..00000000
--- a/modulevoice/src/main/res/values/themes.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/timcommon/src/main/AndroidManifest.xml b/timcommon/src/main/AndroidManifest.xml
index 3b4f17f4..6e9aba46 100644
--- a/timcommon/src/main/AndroidManifest.xml
+++ b/timcommon/src/main/AndroidManifest.xml
@@ -20,7 +20,7 @@
diff --git a/tuichat/src/main/AndroidManifest.xml b/tuichat/src/main/AndroidManifest.xml
index 62a36193..ed47cc93 100644
--- a/tuichat/src/main/AndroidManifest.xml
+++ b/tuichat/src/main/AndroidManifest.xml
@@ -12,7 +12,7 @@
@@ -60,18 +60,18 @@
diff --git a/tuicore/src/main/AndroidManifest.xml b/tuicore/src/main/AndroidManifest.xml
index b80815dc..3f345e14 100644
--- a/tuicore/src/main/AndroidManifest.xml
+++ b/tuicore/src/main/AndroidManifest.xml
@@ -5,7 +5,7 @@
@@ -13,7 +13,7 @@
android:name="com.tencent.qcloud.tuicore.util.PermissionRequester$PermissionActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:multiprocess="true"
- android:launchMode="singleTask"
+
android:theme="@style/CoreActivityTranslucent"
android:windowSoftInputMode="stateHidden|stateAlwaysHidden" />