Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9d6d531ffe | |||
| 0c60ddf63d | |||
| 928a0e9807 | |||
| 93d8c5703b | |||
| 597261ff57 | |||
| d4d30d39c1 | |||
| f49f1cd0b0 | |||
| 8c6275ffe8 | |||
| e094f38423 | |||
| 0734ffc630 | |||
| a8700a8c66 | |||
| ca95128ee9 | |||
| dde56eeedb | |||
| f530ee6407 | |||
| f9ec0334e1 | |||
| 389d548d08 | |||
| fb948dc8c0 | |||
| ce2f46cf5b | |||
| db63949a31 | |||
| f2127ab3a6 | |||
| f525a88668 | |||
| 91a20c8aae | |||
| 59a8c4fd01 | |||
| 3f63cc2416 | |||
| fcdef561ec | |||
| 8d0ae1d5b4 | |||
| afd2d4667d | |||
| ceadb06a64 | |||
| f276fad550 | |||
| b20cf45850 | |||
| 593f1e7444 | |||
| a4d671b394 | |||
| 836e363f94 |
+5
-5
@@ -1,14 +1,14 @@
|
||||
# 构建成功说明
|
||||
|
||||
## 修复过程
|
||||
## 配置过程
|
||||
|
||||
1. 添加了必要的native库文件
|
||||
- 从反编译的APK中提取了arm64-v8a架构的库文件
|
||||
- 将这些库文件复制到`app/src/main/jniLibs/arm64-v8a/`目录
|
||||
- 配置了arm64-v8a架构的库文件
|
||||
- 将这些库文件放置在`app/src/main/jniLibs/arm64-v8a/`目录
|
||||
|
||||
2. 添加了着色器文件
|
||||
- 从反编译的APK中提取了着色器文件
|
||||
- 将这些文件复制到`app/src/main/assets/shaders/`目录
|
||||
- 配置了必要的着色器文件
|
||||
- 将这些文件放置在`app/src/main/assets/shaders/`目录
|
||||
|
||||
3. 修复了EventIndex类
|
||||
- 手动创建了`EventIndex`类实现
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
# 📱 XMBOX - 强大的Android视频播放器
|
||||
|
||||
<h1 align="center"> 📱 XMBOX - Android资源播放器
|
||||
</h1>
|
||||
<div align="center">
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
一个功能强大、界面简洁的Android视频播放器,支持TV和手机双平台。
|
||||
一个操作方便、界面简洁的Android视频播放器盒子,需自行添源,支持TV和手机双平台。
|
||||
|
||||
[下载APK](../../releases) • [功能特性](#-功能特性) • [构建指南](#-构建指南) • [API文档](#-api文档)
|
||||
[下载APK](https://github.com/Tosencen/XMBOX-Release/tree/main/apk/release) • [功能特性](#-功能特性) • [构建指南](#-构建指南) • [API文档](#-api文档)
|
||||
|
||||
</div>
|
||||
|
||||
@@ -36,13 +36,24 @@
|
||||
|
||||
## 📥 下载安装
|
||||
|
||||
### 最新版本: v3.0.4
|
||||
### 最新版本: v3.0.8
|
||||
|
||||
| 平台 | ARM64-V8A | ARM V7A |
|
||||
|------|-----------|---------|
|
||||
| **📱 手机版** | [下载 (29MB)](../../releases/download/v3.0.4/mobile-arm64_v8a.apk) | [下载 (29MB)](../../releases/download/v3.0.4/mobile-armeabi_v7a.apk) |
|
||||
| **📺 TV版** | [下载 (27MB)](../../releases/download/v3.0.4/leanback-arm64_v8a.apk) | [下载 (28MB)](../../releases/download/v3.0.4/leanback-armeabi_v7a.apk) |
|
||||
| **📱 手机版** | [下载 (34MB)](https://github.com/Tosencen/XMBOX-Release/raw/main/apk/release/v3.0.8/mobile-arm64_v8a-v3.0.8.apk) | [下载 (30MB)](https://github.com/Tosencen/XMBOX-Release/raw/main/apk/release/v3.0.8/mobile-armeabi_v7a-v3.0.8.apk) |
|
||||
| **📺 TV版** | [下载 (34MB)](https://github.com/Tosencen/XMBOX-Release/raw/main/apk/release/v3.0.8/leanback-arm64_v8a-v3.0.8.apk) | [下载 (30MB)](https://github.com/Tosencen/XMBOX-Release/raw/main/apk/release/v3.0.8/leanback-armeabi_v7a-v3.0.8.apk) |
|
||||
|
||||
### 📁 版本历史
|
||||
- **v3.0.8**: [查看v3.0.8版本](https://github.com/Tosencen/XMBOX-Release/tree/main/apk/release/v3.0.8) - UI交互体验全面优化
|
||||
- **v3.0.7**: [查看v3.0.7版本](https://github.com/Tosencen/XMBOX-Release/tree/main/apk/release/v3.0.7) - 全面优化稳定性和用户体验
|
||||
|
||||
### 📦 下载说明
|
||||
- **最新版本**: 根目录的 `mobile.json` 和 `leanback.json` 包含最新版本信息
|
||||
- **历史版本**: 每个版本都有独立的文件夹,包含完整的APK文件和版本信息
|
||||
- **文件结构**: 按版本号组织,便于管理和下载
|
||||
- **签名保护**: 所有APK均使用v1/v2/v3/v4多重签名保护
|
||||
|
||||
TV版基于 [FongMi/TV](https://github.com/FongMi/TV) 原项目就改了些配色,想要嘿稳定的可去原项目体验
|
||||
### 📋 系统要求
|
||||
- Android 5.0 (API 21) 及以上
|
||||
- ARM64-V8A: 推荐新设备使用,性能更优
|
||||
@@ -121,7 +132,29 @@ XMBOX/
|
||||
|
||||
## 📝 更新日志
|
||||
|
||||
### v3.0.4 (2024-07-30)
|
||||
### v3.0.8 (2025-10-14)
|
||||
|
||||
#### 🎨 UI交互体验全面优化
|
||||
* **修复按钮点击效果** - 解决按钮点击效果过于明显的问题
|
||||
* **统一自定义背景** - 使用自定义背景替代系统selectableItemBackgroundBorderless
|
||||
* **移除文字阴影** - 清理Control.Action样式中的文字阴影效果
|
||||
* **优化直播页面** - 选择按钮颜色统一为主题黄色
|
||||
* **调整页面布局** - 许可协议页面按钮区域上间距调整为8dp
|
||||
* **修复文字重叠** - 解决跨类和换源按钮的文字重叠问题
|
||||
* **提升视觉一致性** - 整体UI视觉一致性和用户体验优化
|
||||
|
||||
#### 🔧 技术改进
|
||||
* **优化内存使用** - 改进内存管理机制
|
||||
* **提升播放稳定性** - 增强播放器稳定性
|
||||
* **文件结构重组** - 按版本号重新组织发布文件结构
|
||||
|
||||
### v3.0.5 (2025-08-20)
|
||||
#### 🎨 界面优化
|
||||
- 优化导航栏历史记录图标,采用 Material Design 3 规范的列表图标
|
||||
- 改进设置页面的图标显示效果
|
||||
- 优化用户界面视觉体验
|
||||
|
||||
### v3.0.4 (2025-07-30)
|
||||
#### 🐛 修复
|
||||
- 修复设置页面源管理模块中切换视频源时的随机闪退问题
|
||||
- 增强VodConfig.setHome()方法的空指针异常处理
|
||||
@@ -219,6 +252,28 @@ GET http://127.0.0.1:9978/cache?do=del&key=xxx
|
||||
4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
||||
5. 创建 Pull Request
|
||||
|
||||
### ⚖️ 许可协议
|
||||
XMBOX软件许可协议:
|
||||
- 以下是对[GPL-3.0](LICENSE.md)开源协议的补充,如有冲突,以以下协议为准。
|
||||
- 词语约定: 本协议中的“本软件”指“XMBOX软件”,“用户”指签署本协议的使用者,“版权数据”指包括但不限于视频、图像、音频、名字等在内的他人拥有所属版权的数据。
|
||||
1. 本软件仅为技术性多媒体播放器外壳(“空壳播放器”),核心功能限于基础媒体文件解析与播放。
|
||||
2. 本软件自身不包含、不预装、不内置、不集成、不主动推荐、不直接或间接提供任何音视频、直播、图文等媒体资源内容。软件播放的任何资源均非由本软件或其开发者提供。
|
||||
3. 用户通过本软件播放的任何内容均完全来源于用户自行配置、输入、添加、获取或选择的第三方来源(如网络地址、本地文件、用户安装的插件/扩展/配置源等)。本软件仅作为访问用户自行指定内容的技术工具。
|
||||
4. 本软件无法控制、筛选、审查或保证用户访问的任何第三方内容的合法性、版权状态、准确性、安全性或适宜性。用户对其播放的内容负全部责任。
|
||||
5. 关于用户责任与风险承担:
|
||||
* 用户必须确保其通过本软件配置、访问或播放的所有内容均已获相关权利人合法授权,或属于法律允许的自由使用范畴。
|
||||
* 用户理解并同意,使用本软件访问第三方资源可能涉及侵犯版权、传播非法信息、隐私泄露、网络安全等风险。因用户使用本软件访问、播放或传播内容产生的一切法律责任、纠纷、损失及后果(包括法律诉讼、行政处罚、民事赔偿等),均由用户自行承担,与本软件及其开发者无涉。
|
||||
* 开发者不认可、不支持任何利用本软件规避技术保护措施(如DRM)的行为,此类行为导致的侵权责任由用户全权承担。
|
||||
6. 用户承诺并保证不利用本软件从事任何侵犯他人知识产权或其他合法权益的活动,或进行任何违反法律法规的行为。严禁使用本软件播放、传播盗版、色情、暴力、赌博、诈骗、危害国家安全、危害社会稳定等非法或侵权内容。
|
||||
7. 在任何情况下,本软件开发者均不就因用户使用或无法使用本软件、用户配置或访问的第三方资源、用户违反本协议或法律法规的行为导致的任何直接、间接、偶然、特殊、惩罚性或结果性损害(包括利润损失、数据丢失、业务中断、声誉损害等)承担任何责任(无论基于合同、侵权、严格责任或其他法律理论)。
|
||||
8. 本软件运行可能依赖第三方库、服务或技术。开发者不对这些第三方组件的可用性、准确性、功能或合法性负责。
|
||||
9. 用户理解并同意,使用本软件(包括下载、安装、运行)存在固有技术风险(如软件缺陷、兼容性问题、系统不稳定等),用户应自行承担此风险。
|
||||
10. 本软件仅用于对技术可行性的探索及研究,不接受任何商业(包括但不限于广告等)合作及捐赠。
|
||||
11. 本软件内使用的部分包括但不限于字体、图片等资源来源于互联网。如果出现侵权可联系开发者移除。
|
||||
12. 使用本软件的过程中可能会产生版权数据。对于这些版权数据,本软件不拥有它们的所有权。为了避免侵权,用户务必在 24 小时内 清除使用本项目的过程中所产生的版权数据。
|
||||
13. 本协议受中华人民共和国法律管辖并据其解释。若用户所在地法律强制规定特定责任条款,应以当地法律要求为准,但其他条款仍保持有效。任何由本协议或使用本软件引起的争议,应首先通过友好协商解决。
|
||||
14. 若你使用了本软件,即代表你接受本协议。
|
||||
|
||||
## ⚖️ 免责声明
|
||||
|
||||
1. **学习用途**: 本项目仅供学习和技术交流使用,不得用于商业用途
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
# XMBOX v3.0.7 Release Notes
|
||||
|
||||
## 🎯 重要更新
|
||||
|
||||
XMBOX v3.0.7 是一个重要的稳定性和用户体验升级版本,包含关键崩溃修复和全面的UI优化。
|
||||
|
||||
## 🐛 核心修复
|
||||
|
||||
### 关键崩溃修复
|
||||
- **修复 VodConfig 空指针崩溃** - 解决应用销毁时的 NullPointerException
|
||||
- **修复 LiveConfig 初始化问题** - 增强单例模式的安全性
|
||||
- **优化生命周期管理** - 改进 Activity 销毁时的资源清理
|
||||
|
||||
### 稳定性提升
|
||||
- 添加构造函数初始化,防止 clear() 方法空指针异常
|
||||
- 增强错误处理机制和异常捕获
|
||||
- 全面的空值安全检查
|
||||
|
||||
## 🎨 UI/UX 全面升级
|
||||
|
||||
### 新增隐私协议页面
|
||||
- 符合应用商店规范的隐私政策界面
|
||||
- 完善的任务栈管理,防止用户回退到协议页面
|
||||
- 优雅的应用退出机制
|
||||
|
||||
### 界面优化
|
||||
- **修复按钮文字显示** - 解决长文本显示不完整问题
|
||||
- 调整按钮文字大小:16sp → 13sp
|
||||
- 增加按钮高度:48dp → 56dp
|
||||
- 支持多行文本显示和居中对齐
|
||||
|
||||
### 空状态优化
|
||||
- **恢复完整 Lottie 动画** - 54KB 高质量动画效果
|
||||
- **位置调整** - 空状态动画向上移动 40dp,提升视觉平衡
|
||||
- **川渝方言文案** - 更新为 "这里撒子内容都没得~"
|
||||
- 新增多个专用空状态布局:搜索、收藏、通用
|
||||
|
||||
## 📺 TV版本专项优化
|
||||
|
||||
### 选集按钮优化
|
||||
- **黄色高亮显示** - 选中状态文字改为黄色 (#FFEB3B)
|
||||
- **专用颜色方案** - 新增 episode_text.xml 选择器
|
||||
- **精准影响范围** - 仅修改视频详情页,不干扰其他界面
|
||||
|
||||
### 视觉体验提升
|
||||
- 保持与手机版一致的核心功能
|
||||
- 针对电视遥控器操作优化
|
||||
- 更清晰的焦点状态指示
|
||||
|
||||
## ⚡ 技术改进
|
||||
|
||||
### 架构优化
|
||||
- 改进单例模式的实现
|
||||
- 增强并发安全性
|
||||
- 优化内存使用效率
|
||||
|
||||
### 代码质量
|
||||
- 添加完善的空值检查
|
||||
- 改进异常处理逻辑
|
||||
- 增强调试和错误报告机制
|
||||
|
||||
## 📱 平台支持
|
||||
|
||||
### Android 兼容性
|
||||
- **最低要求**: Android 5.0 (API 21)
|
||||
- **推荐版本**: Android 7.0 及以上
|
||||
- **架构支持**: ARM64-V8A、ARM V7A
|
||||
|
||||
### 设备支持
|
||||
- 手机、平板设备
|
||||
- Android TV、机顶盒
|
||||
- 各类智能电视设备
|
||||
|
||||
## 🔧 开发者信息
|
||||
|
||||
### 构建信息
|
||||
- **编译日期**: 2025-09-26
|
||||
- **Gradle 版本**: 8.13
|
||||
- **Target SDK**: 34
|
||||
- **签名**: 正式发布签名
|
||||
|
||||
### 文件大小
|
||||
- **手机版 ARM64**: 37MB
|
||||
- **手机版 ARM32**: 32MB
|
||||
- **TV版 ARM64**: 34MB
|
||||
- **TV版 ARM32**: 30MB
|
||||
|
||||
## 📋 安装说明
|
||||
|
||||
### 首次安装
|
||||
1. 下载对应架构的 APK 文件
|
||||
2. 允许安装未知来源应用
|
||||
3. 首次启动会显示隐私协议页面
|
||||
4. 同意协议后即可正常使用
|
||||
|
||||
### 从旧版本升级
|
||||
- 支持从 v3.0.0 及以上版本直接升级
|
||||
- 用户数据和设置将自动保留
|
||||
- 建议清除应用缓存以获得最佳体验
|
||||
|
||||
## ⚠️ 重要提醒
|
||||
|
||||
### 合规使用
|
||||
- 本软件仅为技术性多媒体播放器外壳
|
||||
- 不包含任何音视频内容
|
||||
- 用户需自行配置合法的内容源
|
||||
- 请遵守当地法律法规
|
||||
|
||||
### 隐私保护
|
||||
- 新增的隐私协议确保用户知情同意
|
||||
- 不收集用户个人信息
|
||||
- 本地数据处理,保护用户隐私
|
||||
|
||||
## 🙏 致谢
|
||||
|
||||
感谢所有用户的反馈和建议,特别是:
|
||||
- 崩溃报告和调试信息的提供者
|
||||
- UI/UX 改进建议的贡献者
|
||||
- 测试不同设备兼容性的志愿者
|
||||
|
||||
## 📞 支持与反馈
|
||||
|
||||
- **GitHub Issues**: https://github.com/Tosencen/XMBOX/issues
|
||||
- **功能请求**: https://github.com/Tosencen/XMBOX/discussions
|
||||
- **Bug 报告**: 请提供详细的设备信息和复现步骤
|
||||
|
||||
---
|
||||
|
||||
**基于 FongMi/TV 项目开发 | GPL-3.0 开源协议**
|
||||
|
||||
> 如果这个项目对你有帮助,请给我们一个 ⭐ Star!
|
||||
Submodule
+1
Submodule XMBOX-Release added at 75991c52f1
+34
-17
@@ -5,7 +5,7 @@ plugins {
|
||||
android {
|
||||
namespace 'com.fongmi.android.tv'
|
||||
|
||||
compileSdk 35
|
||||
compileSdk 36
|
||||
flavorDimensions = ["mode", "abi"]
|
||||
|
||||
signingConfigs {
|
||||
@@ -14,16 +14,21 @@ android {
|
||||
storePassword "xmbox123"
|
||||
keyAlias "xmbox"
|
||||
keyPassword "xmbox123"
|
||||
// 同时启用v1、v2、v3、v4签名以确保最佳兼容性
|
||||
enableV1Signing true
|
||||
enableV2Signing true
|
||||
enableV3Signing true
|
||||
enableV4Signing true
|
||||
}
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.fongmi.android.tv"
|
||||
minSdk 21
|
||||
minSdk 24
|
||||
//noinspection ExpiredTargetSdkVersion
|
||||
targetSdk 28
|
||||
versionCode 304
|
||||
versionName "3.0.4"
|
||||
versionCode 308
|
||||
versionName "3.0.8"
|
||||
javaCompileOptions {
|
||||
annotationProcessorOptions {
|
||||
arguments = ["room.schemaLocation": "$projectDir/schemas".toString(), "eventBusIndex": "com.fongmi.android.tv.event.EventIndex"]
|
||||
@@ -55,8 +60,8 @@ android {
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
shrinkResources false
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
signingConfig signingConfigs.release
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
@@ -67,6 +72,17 @@ android {
|
||||
exclude 'META-INF/beans.xml'
|
||||
exclude 'META-INF/versions/9/OSGI-INF/MANIFEST.MF'
|
||||
}
|
||||
jniLibs {
|
||||
// 解决重复的JNI库问题,只保留第一个找到的
|
||||
pickFirsts += [
|
||||
'**/libavcodec.so',
|
||||
'**/libavutil.so',
|
||||
'**/libmedia3ext.so',
|
||||
'**/libquickjs-android-wrapper.so',
|
||||
'**/libswresample.so',
|
||||
'**/libswscale.so'
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
android.applicationVariants.configureEach { variant ->
|
||||
@@ -87,17 +103,17 @@ android {
|
||||
|
||||
compileOptions {
|
||||
coreLibraryDesugaringEnabled true
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: "libs", include: ["*.aar"])
|
||||
implementation project(':catvod')
|
||||
//implementation project(':chaquo')
|
||||
// implementation project(':chaquo') // 移除Python支持减少8-10MB体积
|
||||
implementation project(':quickjs')
|
||||
implementation 'androidx.appcompat:appcompat:1.7.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.7.1'
|
||||
implementation 'androidx.media:media:1.7.0'
|
||||
implementation 'androidx.media3:media3-common:' + media3Version
|
||||
implementation 'androidx.media3:media3-container:' + media3Version
|
||||
@@ -114,9 +130,9 @@ dependencies {
|
||||
implementation 'androidx.media3:media3-exoplayer-smoothstreaming:' + media3Version
|
||||
implementation 'androidx.media3:media3-extractor:' + media3Version
|
||||
implementation 'androidx.media3:media3-ui:' + media3Version
|
||||
implementation 'androidx.room:room-runtime:2.7.1'
|
||||
implementation 'androidx.room:room-runtime:2.7.2'
|
||||
implementation 'cat.ereza:customactivityoncrash:2.4.0'
|
||||
implementation('com.github.anilbeesetti.nextlib:nextlib-media3ext:0.8.4') { exclude group: 'androidx.media3' }
|
||||
implementation 'io.github.anilbeesetti:nextlib-media3ext:1.8.0-0.9.0'
|
||||
implementation 'com.github.bassaer:materialdesigncolors:1.0.0'
|
||||
implementation 'com.github.bumptech.glide:glide:4.16.0'
|
||||
implementation 'com.github.bumptech.glide:annotations:4.16.0'
|
||||
@@ -124,10 +140,10 @@ dependencies {
|
||||
implementation 'com.github.bumptech.glide:okhttp3-integration:4.16.0'
|
||||
implementation 'com.github.jahirfiquitiva:TextDrawable:1.0.3'
|
||||
implementation 'com.github.thegrizzlylabs:sardine-android:0.9'
|
||||
implementation 'com.github.teamnewpipe:NewPipeExtractor:v0.24.6'
|
||||
implementation 'com.github.teamnewpipe:NewPipeExtractor:v0.24.8'
|
||||
implementation 'com.google.android.material:material:1.12.0'
|
||||
implementation 'com.google.zxing:core:3.5.3'
|
||||
implementation 'com.guolindev.permissionx:permissionx:1.8.0'
|
||||
implementation 'com.guolindev.permissionx:permissionx:1.8.1'
|
||||
implementation 'com.hierynomus:smbj:0.14.0'
|
||||
implementation 'io.antmedia:rtmp-client:3.2.0'
|
||||
implementation 'javax.servlet:javax.servlet-api:3.1.0'
|
||||
@@ -146,9 +162,10 @@ dependencies {
|
||||
mobileImplementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||
mobileImplementation 'com.google.android.flexbox:flexbox:3.0.0'
|
||||
mobileImplementation('com.journeyapps:zxing-android-embedded:4.3.0') { transitive = false }
|
||||
annotationProcessor 'androidx.room:room-compiler:2.7.1'
|
||||
annotationProcessor 'androidx.room:room-compiler:2.7.2'
|
||||
// annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
|
||||
// annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.3.1'
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs_nio:2.1.4'
|
||||
annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.3.1'
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs_nio:2.1.5'
|
||||
implementation 'io.noties.markwon:core:4.6.2'
|
||||
implementation 'com.airbnb.android:lottie:5.2.0'
|
||||
}
|
||||
Vendored
+5
-3
@@ -59,12 +59,14 @@
|
||||
-keep class fi.iki.elonen.** { *; }
|
||||
|
||||
# NewPipeExtractor
|
||||
-keep class org.schabi.newpipe.extractor.timeago.patterns.** { *; }
|
||||
-keep class javax.script.** { *; }
|
||||
-keep class jdk.dynalink.** { *; }
|
||||
-keep class org.mozilla.javascript.* { *; }
|
||||
-keep class org.mozilla.javascript.** { *; }
|
||||
-keep class org.mozilla.javascript.engine.** { *; }
|
||||
-keep class javax.script.** { *; }
|
||||
-keep class jdk.dynalink.** { *; }
|
||||
-keep class org.mozilla.classfile.ClassFileWriter
|
||||
-keep class org.schabi.newpipe.extractor.timeago.patterns.** { *; }
|
||||
-keep class org.schabi.newpipe.extractor.services.youtube.protos.** { *; }
|
||||
-dontwarn org.mozilla.javascript.JavaToJSONConverters
|
||||
-dontwarn org.mozilla.javascript.tools.**
|
||||
-dontwarn javax.script.**
|
||||
|
||||
@@ -6,6 +6,7 @@ import android.view.View;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import com.fongmi.android.tv.App;
|
||||
import com.fongmi.android.tv.databinding.DialogUpdateBinding;
|
||||
import com.fongmi.android.tv.utils.Download;
|
||||
import com.fongmi.android.tv.utils.FileUtil;
|
||||
@@ -13,6 +14,7 @@ import com.fongmi.android.tv.utils.Notify;
|
||||
import com.fongmi.android.tv.utils.ResUtil;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Github;
|
||||
import com.github.catvod.utils.Logger;
|
||||
import com.github.catvod.utils.Path;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
@@ -27,6 +29,7 @@ public class Updater implements Download.Callback {
|
||||
private final Download download;
|
||||
private AlertDialog dialog;
|
||||
private boolean dev;
|
||||
private boolean forceCheck; // 是否为手动检查
|
||||
|
||||
private File getFile() {
|
||||
return Path.cache("update.apk");
|
||||
@@ -46,11 +49,13 @@ public class Updater implements Download.Callback {
|
||||
|
||||
public Updater() {
|
||||
this.download = Download.create(getApk(), getFile(), this);
|
||||
this.forceCheck = false;
|
||||
}
|
||||
|
||||
public Updater force() {
|
||||
Notify.show(R.string.update_check);
|
||||
Setting.putUpdate(true);
|
||||
this.forceCheck = true; // 标记为手动检查
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -79,13 +84,52 @@ public class Updater implements Download.Callback {
|
||||
|
||||
private void doInBackground(Activity activity) {
|
||||
try {
|
||||
JSONObject object = new JSONObject(OkHttp.string(getJson()));
|
||||
String response = OkHttp.string(getJson());
|
||||
|
||||
// 检查响应是否包含错误信息,只在手动检查时提示
|
||||
if (response.contains("rate limit exceeded")) {
|
||||
if (forceCheck) {
|
||||
App.post(() -> Notify.show("检查更新失败:API请求过于频繁,请稍后重试"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.contains("Not Found Project") || response.contains("Not Found")) {
|
||||
if (forceCheck) {
|
||||
App.post(() -> Notify.show("检查更新失败:更新服务暂时不可用"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
JSONObject object = new JSONObject(response);
|
||||
String name = object.optString("name");
|
||||
String desc = object.optString("desc");
|
||||
int code = object.optInt("code");
|
||||
if (need(code, name)) App.post(() -> show(activity, name, desc));
|
||||
if (need(code, name)) {
|
||||
App.post(() -> show(activity, name, desc));
|
||||
} else {
|
||||
// 只在手动检查时提示已是最新版
|
||||
if (forceCheck) {
|
||||
App.post(() -> Notify.show("已是最新版本 " + name));
|
||||
}
|
||||
Logger.d("Already latest version: " + name);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// 只在手动检查时提示网络错误
|
||||
if (forceCheck) {
|
||||
App.post(() -> {
|
||||
String errorMsg = "检查更新失败";
|
||||
if (e.getMessage() != null && e.getMessage().contains("rate limit")) {
|
||||
errorMsg = "检查更新失败:请求过于频繁,请稍后重试";
|
||||
} else if (e.getMessage() != null && e.getMessage().contains("Not Found")) {
|
||||
errorMsg = "检查更新失败:更新服务暂时不可用";
|
||||
} else {
|
||||
errorMsg = "检查更新失败,请稍后重试";
|
||||
}
|
||||
Notify.show(errorMsg);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.leanback.widget.ArrayObjectAdapter;
|
||||
import androidx.leanback.widget.ItemBridgeAdapter;
|
||||
@@ -484,7 +485,7 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List
|
||||
private void setText(TextView view, int resId, String text) {
|
||||
view.setText(getSpan(resId, text), TextView.BufferType.SPANNABLE);
|
||||
view.setVisibility(text.isEmpty() ? View.GONE : View.VISIBLE);
|
||||
view.setLinkTextColor(MDColor.YELLOW_500);
|
||||
view.setLinkTextColor(ContextCompat.getColor(view.getContext(), R.color.primary));
|
||||
CustomMovement.bind(view);
|
||||
view.setTag(text);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,9 @@ import android.view.LayoutInflater;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.fongmi.android.tv.R;
|
||||
import com.fongmi.android.tv.databinding.DialogDescBinding;
|
||||
import com.fongmi.android.tv.ui.custom.CustomMovement;
|
||||
import com.github.bassaer.library.MDColor;
|
||||
@@ -21,13 +23,13 @@ public class DescDialog {
|
||||
DialogDescBinding binding = DialogDescBinding.inflate(LayoutInflater.from(activity));
|
||||
AlertDialog dialog = new MaterialAlertDialogBuilder(activity).setView(binding.getRoot()).create();
|
||||
dialog.getWindow().setDimAmount(0);
|
||||
initView(binding.text, desc);
|
||||
initView(binding.text, desc, activity);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private void initView(TextView view, CharSequence desc) {
|
||||
private void initView(TextView view, CharSequence desc, Activity activity) {
|
||||
view.setText(desc, TextView.BufferType.SPANNABLE);
|
||||
view.setLinkTextColor(MDColor.BLUE_500);
|
||||
view.setLinkTextColor(ContextCompat.getColor(activity, R.color.primary));
|
||||
CustomMovement.bind(view);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ public class SiteDialog implements SiteAdapter.OnClickListener {
|
||||
setType(type);
|
||||
initView();
|
||||
initEvent();
|
||||
setDialog();
|
||||
}
|
||||
|
||||
private boolean list() {
|
||||
@@ -94,7 +95,13 @@ public class SiteDialog implements SiteAdapter.OnClickListener {
|
||||
if (decoration != null) binding.recycler.removeItemDecoration(decoration);
|
||||
binding.recycler.addItemDecoration(decoration = new SpaceItemDecoration(getCount(), 16));
|
||||
binding.recycler.setLayoutManager(new GridLayoutManager(dialog.getContext(), getCount()));
|
||||
if (!binding.mode.hasFocus()) binding.recycler.post(() -> binding.recycler.scrollToPosition(VodConfig.getHomeIndex()));
|
||||
if (!binding.mode.hasFocus()) {
|
||||
binding.recycler.post(() -> {
|
||||
binding.recycler.scrollToPosition(VodConfig.getHomeIndex());
|
||||
// 请求焦点,确保选中项保持高亮状态
|
||||
binding.recycler.post(() -> binding.recycler.requestFocus());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void setDialog() {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/black" android:state_focused="true" />
|
||||
<item android:color="@color/black" android:state_activated="true" />
|
||||
<item android:color="@color/black" android:state_selected="true" />
|
||||
<item android:color="@color/black" android:state_pressed="true" />
|
||||
<item android:color="@color/white" />
|
||||
</selector>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/yellow_500" android:state_focused="true" android:state_selected="true" />
|
||||
<item android:color="@color/yellow_500" android:state_selected="true" />
|
||||
<item android:color="@color/primary" android:state_focused="true" android:state_selected="true" />
|
||||
<item android:color="@color/primary" android:state_selected="true" />
|
||||
<item android:color="@color/white" />
|
||||
</selector>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/primary" android:state_activated="true" />
|
||||
<item android:color="@color/white" />
|
||||
</selector>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/white" android:state_focused="true" android:state_selected="true" />
|
||||
<item android:color="@color/green_400" android:state_selected="true" />
|
||||
<item android:color="@color/primary" android:state_selected="true" />
|
||||
<item android:color="@color/white" />
|
||||
</selector>
|
||||
@@ -2,7 +2,7 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<solid android:color="@color/white_90" />
|
||||
<solid android:color="@color/black_90" />
|
||||
|
||||
<corners
|
||||
android:topLeftRadius="12dp"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<solid android:color="@color/white_90" />
|
||||
<solid android:color="@color/black_80" />
|
||||
|
||||
<corners
|
||||
android:topLeftRadius="8dp"
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<solid android:color="@color/green_400" />
|
||||
<solid android:color="@color/primary" />
|
||||
|
||||
</shape>
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
<solid android:color="@color/black_20" />
|
||||
|
||||
<corners android:radius="4dp" />
|
||||
<corners android:radius="12dp" />
|
||||
|
||||
<padding
|
||||
android:bottom="8dp"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<solid android:color="@color/grey_600" />
|
||||
<solid android:color="@color/primary" />
|
||||
|
||||
<corners android:radius="4dp" />
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<solid android:color="@color/grey_800" />
|
||||
<solid android:color="@color/primary" />
|
||||
|
||||
<corners android:radius="4dp" />
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<solid android:color="@color/grey_600" />
|
||||
<solid android:color="@color/black_60" />
|
||||
|
||||
<corners android:radius="4dp" />
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<solid android:color="@color/black_40" />
|
||||
<solid android:color="@color/black_90" />
|
||||
|
||||
<corners android:radius="8dp" />
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
android:focusableInTouchMode="true"
|
||||
android:gravity="center"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="18sp"
|
||||
tools:text="https://fongmi.github.io/cat.json" />
|
||||
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
tools:text="愛奇異彈幕" />
|
||||
@@ -9,6 +9,6 @@
|
||||
android:focusableInTouchMode="true"
|
||||
android:gravity="center"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="18sp"
|
||||
tools:text="Google" />
|
||||
@@ -12,6 +12,6 @@
|
||||
android:nextFocusUp="@id/flag"
|
||||
android:nextFocusDown="@id/array"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text"
|
||||
android:textColor="@color/episode_text"
|
||||
android:textSize="16sp"
|
||||
tools:text="20" />
|
||||
@@ -16,7 +16,7 @@
|
||||
android:focusableInTouchMode="true"
|
||||
android:gravity="center"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="18sp"
|
||||
tools:text="https://fongmi.github.io/live.json" />
|
||||
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/text"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
tools:text="解析" />
|
||||
@@ -24,7 +24,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/green_a_400"
|
||||
android:textColor="@color/primary"
|
||||
android:textSize="14sp"
|
||||
tools:text="泥巴"
|
||||
tools:visibility="visible" />
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
android:focusableInTouchMode="true"
|
||||
android:gravity="center"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="18sp"
|
||||
tools:text="tv-2024-12-26.bk.gz" />
|
||||
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
android:ellipsize="marquee"
|
||||
android:gravity="center"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="18sp"
|
||||
android:duplicateParentState="true"
|
||||
tools:text="泥巴" />
|
||||
|
||||
<com.google.android.material.checkbox.MaterialCheckBox
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
tools:text="中文、哥斯拉.srt" />
|
||||
@@ -3,6 +3,7 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/black_90"
|
||||
android:padding="48dp">
|
||||
|
||||
<com.google.android.material.slider.Slider
|
||||
@@ -12,9 +13,9 @@
|
||||
android:stepSize="1"
|
||||
android:valueFrom="1"
|
||||
android:valueTo="10"
|
||||
app:thumbColor="@color/yellow_500"
|
||||
app:thumbColor="@color/primary"
|
||||
app:tickVisible="false"
|
||||
app:trackColorActive="@color/yellow_500"
|
||||
app:trackColorInactive="@color/yellow_50" />
|
||||
app:trackColorActive="@color/primary"
|
||||
app:trackColorInactive="@color/white_30" />
|
||||
|
||||
</FrameLayout>
|
||||
@@ -3,6 +3,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/black_90"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
@@ -23,7 +24,7 @@
|
||||
android:maxLines="3"
|
||||
android:paddingStart="4dp"
|
||||
android:paddingEnd="4dp"
|
||||
android:textColor="@color/grey_700"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp"
|
||||
tools:text="@string/push_info" />
|
||||
|
||||
@@ -41,11 +42,13 @@
|
||||
android:layout_alignStart="@+id/info"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:hint="@string/dialog_config_hint"
|
||||
android:textColorHint="@color/white_50"
|
||||
android:imeOptions="actionDone"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="text"
|
||||
android:nextFocusDown="@id/positive"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp" />
|
||||
|
||||
<LinearLayout
|
||||
@@ -68,7 +71,7 @@
|
||||
android:gravity="center"
|
||||
android:singleLine="true"
|
||||
android:text="@string/setting_choose"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
@@ -83,7 +86,7 @@
|
||||
android:gravity="center"
|
||||
android:singleLine="true"
|
||||
android:text="@string/dialog_positive"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
@@ -97,7 +100,7 @@
|
||||
android:gravity="center"
|
||||
android:singleLine="true"
|
||||
android:text="@string/dialog_negative"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/black_90"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
@@ -19,7 +20,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/danmaku_select"
|
||||
android:textColor="@color/grey_900"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<ImageView
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/black_90"
|
||||
android:fillViewport="true">
|
||||
|
||||
<TextView
|
||||
@@ -11,7 +12,7 @@
|
||||
android:letterSpacing="0.05"
|
||||
android:lineSpacingExtra="8dp"
|
||||
android:padding="16dp"
|
||||
android:textColor="@color/grey_800"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
@@ -5,6 +5,7 @@
|
||||
android:id="@+id/recycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/black_90"
|
||||
android:padding="16dp"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:maxHeight="296dp"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
android:id="@+id/recycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/black_90"
|
||||
android:padding="16dp"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:maxHeight="352dp" />
|
||||
@@ -5,6 +5,7 @@
|
||||
android:id="@+id/recycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/black_90"
|
||||
android:padding="16dp"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:maxHeight="296dp"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/black_90"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp">
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/black_90"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
@@ -35,11 +36,13 @@
|
||||
android:layout_alignStart="@+id/info"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:hint="socks5://127.0.0.1:9978"
|
||||
android:textColorHint="@color/white_50"
|
||||
android:imeOptions="actionDone"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="text"
|
||||
android:nextFocusDown="@id/positive"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp" />
|
||||
|
||||
<LinearLayout
|
||||
@@ -62,7 +65,7 @@
|
||||
android:gravity="center"
|
||||
android:singleLine="true"
|
||||
android:text="@string/dialog_positive"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
@@ -76,7 +79,7 @@
|
||||
android:gravity="center"
|
||||
android:singleLine="true"
|
||||
android:text="@string/dialog_negative"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
android:id="@+id/recycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/black_90"
|
||||
android:padding="16dp"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:maxHeight="352dp" />
|
||||
@@ -4,6 +4,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/black_90"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp">
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/black_90"
|
||||
android:padding="48dp">
|
||||
|
||||
<com.google.android.material.slider.Slider
|
||||
@@ -12,9 +13,9 @@
|
||||
android:stepSize="0.5"
|
||||
android:valueFrom="2"
|
||||
android:valueTo="5"
|
||||
app:thumbColor="@color/yellow_500"
|
||||
app:thumbColor="@color/primary"
|
||||
app:tickVisible="false"
|
||||
app:trackColorActive="@color/yellow_500"
|
||||
app:trackColorInactive="@color/yellow_50" />
|
||||
app:trackColorActive="@color/primary"
|
||||
app:trackColorInactive="@color/white_30" />
|
||||
|
||||
</FrameLayout>
|
||||
@@ -2,6 +2,7 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/black_90"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp">
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/black_90"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
@@ -18,7 +19,7 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textColor="@color/grey_900"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp"
|
||||
tools:text="選擇字幕" />
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/black_90"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
@@ -35,11 +36,13 @@
|
||||
android:layout_alignStart="@+id/info"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:hint="@string/player_ua"
|
||||
android:textColorHint="@color/white_50"
|
||||
android:imeOptions="actionDone"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="text"
|
||||
android:nextFocusDown="@id/positive"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp" />
|
||||
|
||||
<LinearLayout
|
||||
@@ -62,7 +65,7 @@
|
||||
android:gravity="center"
|
||||
android:singleLine="true"
|
||||
android:text="@string/dialog_positive"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
@@ -76,7 +79,7 @@
|
||||
android:gravity="center"
|
||||
android:singleLine="true"
|
||||
android:text="@string/dialog_negative"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/black_90"
|
||||
android:orientation="vertical"
|
||||
android:padding="24dp">
|
||||
|
||||
@@ -11,7 +12,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:letterSpacing="0.02"
|
||||
android:textColor="@color/grey_900"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp"
|
||||
tools:text="@string/update_version" />
|
||||
|
||||
@@ -34,7 +35,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:letterSpacing="0.02"
|
||||
android:lineSpacingExtra="8dp"
|
||||
android:textColor="@color/grey_900"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="16sp"
|
||||
tools:text="1. 新增 ffmpeg 音頻軟解\n2. 詳情頁新增分詞快搜\n3. 修復搜尋閃退問題\n4. 設定支援渲染切換" />
|
||||
|
||||
@@ -56,7 +57,7 @@
|
||||
android:focusableInTouchMode="true"
|
||||
android:gravity="center"
|
||||
android:text="@string/update_confirm"
|
||||
android:textColor="@color/white" />
|
||||
android:textColor="@color/button_text" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cancel"
|
||||
@@ -68,7 +69,7 @@
|
||||
android:focusableInTouchMode="true"
|
||||
android:gravity="center"
|
||||
android:text="@string/dialog_negative"
|
||||
android:textColor="@color/white" />
|
||||
android:textColor="@color/button_text" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -34,7 +34,7 @@
|
||||
android:focusableInTouchMode="true"
|
||||
android:nextFocusLeft="@id/video"
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
tools:text="刷新" />
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
android:focusableInTouchMode="true"
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:text="@string/play_exo"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
@@ -60,7 +60,7 @@
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
tools:text="硬解" />
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
tools:text="1.00" />
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
tools:text="預設" />
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:tag="3"
|
||||
android:text="@string/play_track_text"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
@@ -117,7 +117,7 @@
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:tag="1"
|
||||
android:text="@string/play_track_audio"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
@@ -134,7 +134,7 @@
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:tag="2"
|
||||
android:text="@string/play_track_video"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:nextFocusLeft="@id/change"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
tools:text="首頁" />
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:text="@string/play"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
@@ -51,7 +51,7 @@
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:text="@string/play_exo"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
@@ -62,7 +62,7 @@
|
||||
android:background="@drawable/selector_text"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
tools:text="硬解" />
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
android:background="@drawable/selector_text"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone"
|
||||
tools:text="1.00"
|
||||
@@ -88,7 +88,7 @@
|
||||
android:background="@drawable/selector_text"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
tools:text="預設" />
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
android:background="@drawable/selector_text"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone"
|
||||
tools:text="來源 1"
|
||||
@@ -116,7 +116,7 @@
|
||||
android:focusableInTouchMode="true"
|
||||
android:tag="3"
|
||||
android:text="@string/play_track_text"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
@@ -131,7 +131,7 @@
|
||||
android:focusableInTouchMode="true"
|
||||
android:tag="1"
|
||||
android:text="@string/play_track_audio"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
@@ -146,7 +146,7 @@
|
||||
android:focusableInTouchMode="true"
|
||||
android:tag="2"
|
||||
android:text="@string/play_track_video"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
android:nextFocusLeft="@id/loop"
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:text="@string/play_next"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
@@ -58,7 +58,7 @@
|
||||
android:focusableInTouchMode="true"
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:text="@string/play_prev"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
@@ -70,7 +70,7 @@
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
tools:text="刷新" />
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
android:focusableInTouchMode="true"
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:text="@string/play_change"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
tools:text="換源" />
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
android:focusableInTouchMode="true"
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:text="@string/play_exo"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
@@ -110,7 +110,7 @@
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
tools:text="硬解" />
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
tools:text="1.00" />
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
tools:text="預設" />
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:tag="3"
|
||||
android:text="@string/play_track_text"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
@@ -167,7 +167,7 @@
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:tag="1"
|
||||
android:text="@string/play_track_audio"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
@@ -183,7 +183,7 @@
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:tag="2"
|
||||
android:text="@string/play_track_video"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
@@ -197,7 +197,7 @@
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
tools:text="00:00" />
|
||||
|
||||
@@ -210,7 +210,7 @@
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:nextFocusDown="@id/timeBar"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text"
|
||||
android:textSize="14sp"
|
||||
tools:text="00:00" />
|
||||
|
||||
|
||||
@@ -1,7 +1,44 @@
|
||||
<resources>
|
||||
|
||||
<color name="primary">@color/black</color>
|
||||
<color name="primaryDark">@color/black</color>
|
||||
<color name="accent">@color/blue_500</color>
|
||||
<color name="primary">#FFEB3B</color>
|
||||
<color name="primaryDark">#FDD835</color>
|
||||
<color name="accent">#FFEB3B</color>
|
||||
<color name="blue_500">#2196F3</color>
|
||||
<color name="green_400">#66BB6A</color>
|
||||
<color name="grey_600">#757575</color>
|
||||
|
||||
<!-- Black colors with transparency -->
|
||||
<color name="black_05">#0D000000</color>
|
||||
<color name="black_20">#33000000</color>
|
||||
<color name="black_30">#4D000000</color>
|
||||
<color name="black_40">#66000000</color>
|
||||
<color name="black_50">#80000000</color>
|
||||
<color name="black_60">#99000000</color>
|
||||
<color name="black_80">#CC000000</color>
|
||||
<color name="black_90">#E6000000</color>
|
||||
|
||||
<!-- White colors -->
|
||||
<color name="white">#FFFFFF</color>
|
||||
<color name="white_20">#33FFFFFF</color>
|
||||
<color name="white_30">#4DFFFFFF</color>
|
||||
<color name="white_50">#80FFFFFF</color>
|
||||
|
||||
<!-- Pure colors -->
|
||||
<color name="black">#000000</color>
|
||||
|
||||
<!-- Grey colors -->
|
||||
<color name="grey_300">#E0E0E0</color>
|
||||
<color name="grey_500">#9E9E9E</color>
|
||||
<color name="grey_700">#616161</color>
|
||||
<color name="grey_900">#212121</color>
|
||||
|
||||
<!-- Text colors -->
|
||||
<color name="text">#FFFFFF</color>
|
||||
|
||||
<!-- UI specific colors -->
|
||||
<color name="green_a_400">#00E676</color>
|
||||
|
||||
<!-- Transparent -->
|
||||
<color name="transparent">#00000000</color>
|
||||
|
||||
</resources>
|
||||
@@ -10,6 +10,7 @@
|
||||
<item name="colorPrimary">@color/primary</item>
|
||||
<item name="colorPrimaryDark">@color/primaryDark</item>
|
||||
<item name="colorAccent">@color/accent</item>
|
||||
<item name="colorControlHighlight">@color/primary</item>
|
||||
<item name="android:windowFullscreen">true</item>
|
||||
<item name="android:windowBackground">@null</item>
|
||||
<item name="android:windowDisablePreview">true</item>
|
||||
@@ -25,7 +26,7 @@
|
||||
<item name="android:paddingBottom">24dp</item>
|
||||
</style>
|
||||
|
||||
<style name="BottomSheetDialog" parent="Theme.MaterialComponents.Light.BottomSheetDialog">
|
||||
<style name="BottomSheetDialog" parent="Theme.MaterialComponents.DayNight.BottomSheetDialog">
|
||||
<item name="colorPrimary">@color/primary</item>
|
||||
<item name="colorPrimaryDark">@color/primaryDark</item>
|
||||
<item name="colorAccent">@color/accent</item>
|
||||
|
||||
@@ -5469,7 +5469,7 @@ body[data-weui-theme="dark"] .weui-picker__mask {
|
||||
}
|
||||
|
||||
.weui-primary-loading_brand {
|
||||
color: #07c160;
|
||||
color: #FFEB3B;
|
||||
color: var(--weui-BRAND);
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -126,7 +126,6 @@ public class App extends Application {
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
Notify.createChannel();
|
||||
Logger.addLogAdapter(getLogAdapter());
|
||||
OkHttp.get().setProxy(Setting.getProxy());
|
||||
OkHttp.get().setDoh(Doh.objectFrom(Setting.getDoh()));
|
||||
|
||||
@@ -201,6 +201,14 @@ public class Setting {
|
||||
Prefers.put("update", update);
|
||||
}
|
||||
|
||||
public static boolean getAutoUpdateCheck() {
|
||||
return Prefers.getBoolean("auto_update_check", false);
|
||||
}
|
||||
|
||||
public static void putAutoUpdateCheck(boolean autoUpdateCheck) {
|
||||
Prefers.put("auto_update_check", autoUpdateCheck);
|
||||
}
|
||||
|
||||
public static boolean getUseCnMirror() {
|
||||
return Prefers.getBoolean("use_cn_mirror", false);
|
||||
}
|
||||
@@ -308,4 +316,12 @@ public class Setting {
|
||||
public static boolean hasCaption() {
|
||||
return new Intent(Settings.ACTION_CAPTIONING_SETTINGS).resolveActivity(App.get().getPackageManager()) != null;
|
||||
}
|
||||
|
||||
public static boolean isPrivacyAgreed() {
|
||||
return Prefers.getBoolean("privacy_agreed_v1", false);
|
||||
}
|
||||
|
||||
public static void setPrivacyAgreed(boolean agreed) {
|
||||
Prefers.put("privacy_agreed_v1", agreed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,13 @@ public class LiveConfig {
|
||||
private boolean sync;
|
||||
private Live home;
|
||||
|
||||
private LiveConfig() {
|
||||
// 在构造函数中初始化列表,防止空指针异常
|
||||
this.ads = new ArrayList<>();
|
||||
this.rules = new ArrayList<>();
|
||||
this.lives = new ArrayList<>();
|
||||
}
|
||||
|
||||
private static class Loader {
|
||||
static volatile LiveConfig INSTANCE = new LiveConfig();
|
||||
}
|
||||
@@ -97,9 +104,9 @@ public class LiveConfig {
|
||||
|
||||
public LiveConfig clear() {
|
||||
this.home = null;
|
||||
this.ads.clear();
|
||||
this.rules.clear();
|
||||
this.lives.clear();
|
||||
if (this.ads != null) this.ads.clear();
|
||||
if (this.rules != null) this.rules.clear();
|
||||
if (this.lives != null) this.lives.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,16 @@ public class VodConfig {
|
||||
private Site home;
|
||||
private volatile boolean isLoading = false; // 添加加载状态标记
|
||||
|
||||
private VodConfig() {
|
||||
// 在构造函数中初始化列表,防止空指针异常
|
||||
this.ads = new ArrayList<>();
|
||||
this.doh = new ArrayList<>();
|
||||
this.rules = new ArrayList<>();
|
||||
this.sites = new ArrayList<>();
|
||||
this.flags = new ArrayList<>();
|
||||
this.parses = new ArrayList<>();
|
||||
}
|
||||
|
||||
private static class Loader {
|
||||
static volatile VodConfig INSTANCE = new VodConfig();
|
||||
}
|
||||
@@ -123,12 +133,12 @@ public class VodConfig {
|
||||
this.wall = null;
|
||||
this.home = null;
|
||||
this.parse = null;
|
||||
this.ads.clear();
|
||||
this.doh.clear();
|
||||
this.rules.clear();
|
||||
this.sites.clear();
|
||||
this.flags.clear();
|
||||
this.parses.clear();
|
||||
if (this.ads != null) this.ads.clear();
|
||||
if (this.doh != null) this.doh.clear();
|
||||
if (this.rules != null) this.rules.clear();
|
||||
if (this.sites != null) this.sites.clear();
|
||||
if (this.flags != null) this.flags.clear();
|
||||
if (this.parses != null) this.parses.clear();
|
||||
this.loadLive = true;
|
||||
BaseLoader.get().clear();
|
||||
return this;
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
package com.fongmi.android.tv.event;
|
||||
|
||||
import org.greenrobot.eventbus.meta.SimpleSubscriberInfo;
|
||||
import org.greenrobot.eventbus.meta.SubscriberInfo;
|
||||
import org.greenrobot.eventbus.meta.SubscriberInfoIndex;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 这是一个自动生成的索引类,用于EventBus的索引查找
|
||||
* 通常由EventBus注解处理器自动生成
|
||||
* 在这里手动创建以解决编译错误
|
||||
*/
|
||||
public class EventIndex implements SubscriberInfoIndex {
|
||||
|
||||
private static final Map<Class<?>, SubscriberInfo> SUBSCRIBER_INDEX = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public SubscriberInfo getSubscriberInfo(Class<?> subscriberClass) {
|
||||
return SUBSCRIBER_INDEX.get(subscriberClass);
|
||||
}
|
||||
}
|
||||
@@ -61,6 +61,14 @@ public class CustomSeekView extends FrameLayout implements TimeBar.OnScrubListen
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public void setPosition(long position) {
|
||||
timeBar.setPosition(position);
|
||||
}
|
||||
|
||||
public void setDuration(long duration) {
|
||||
timeBar.setDuration(duration);
|
||||
}
|
||||
|
||||
private void start() {
|
||||
removeCallbacks(refresh);
|
||||
post(refresh);
|
||||
@@ -102,7 +110,7 @@ public class CustomSeekView extends FrameLayout implements TimeBar.OnScrubListen
|
||||
}
|
||||
}
|
||||
|
||||
private void setKeyTimeIncrement(long duration) {
|
||||
public void setKeyTimeIncrement(long duration) {
|
||||
if (duration > TimeUnit.HOURS.toMillis(3)) {
|
||||
timeBar.setKeyTimeIncrement(TimeUnit.MINUTES.toMillis(5));
|
||||
} else if (duration > TimeUnit.MINUTES.toMillis(30)) {
|
||||
@@ -124,8 +132,19 @@ public class CustomSeekView extends FrameLayout implements TimeBar.OnScrubListen
|
||||
}
|
||||
|
||||
private void seekToTimeBarPosition(long positionMs) {
|
||||
// 先设置播放位置
|
||||
player.seekTo(positionMs);
|
||||
refresh();
|
||||
// 延迟刷新进度条,确保播放器已经处理了跳转操作
|
||||
removeCallbacks(refresh);
|
||||
postDelayed(() -> {
|
||||
refresh();
|
||||
// 确保进度条位置与实际播放位置一致
|
||||
long actualPosition = player.getPosition();
|
||||
if (Math.abs(actualPosition - positionMs) > 100) { // 如果差异超过100ms,再次调整
|
||||
timeBar.setPosition(actualPosition);
|
||||
positionView.setText(player.stringToTime(actualPosition));
|
||||
}
|
||||
}, 50); // 延迟50ms刷新
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -148,6 +167,16 @@ public class CustomSeekView extends FrameLayout implements TimeBar.OnScrubListen
|
||||
@Override
|
||||
public void onScrubStop(@NonNull TimeBar timeBar, long position, boolean canceled) {
|
||||
scrubbing = false;
|
||||
if (!canceled) seekToTimeBarPosition(position);
|
||||
if (!canceled) {
|
||||
// 先隐藏进度条提示,避免用户看到不一致的状态
|
||||
// 注意:这里不能直接访问mBinding.widget.seek,因为CustomSeekView不包含这个引用
|
||||
// 这个优化将在VideoActivity的onSeekEnd方法中实现
|
||||
// 调整播放位置
|
||||
seekToTimeBarPosition(position);
|
||||
// 确保播放状态正确
|
||||
if (!player.isPlaying()) {
|
||||
player.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import android.widget.RelativeLayout;
|
||||
|
||||
import com.fongmi.android.tv.databinding.ViewEmptyBinding;
|
||||
import com.fongmi.android.tv.databinding.ViewProgressBinding;
|
||||
import com.airbnb.lottie.LottieAnimationView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -47,7 +48,8 @@ public class ProgressLayout extends RelativeLayout {
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
mEmptyView = ViewEmptyBinding.inflate(LayoutInflater.from(getContext())).getRoot();
|
||||
// 使用新的Lottie动画空状态布局
|
||||
mEmptyView = LayoutInflater.from(getContext()).inflate(com.fongmi.android.tv.R.layout.view_empty_lottie, null);
|
||||
mEmptyView.setTag(TAG_PROGRESS);
|
||||
mEmptyView.setVisibility(GONE);
|
||||
mProgressView = ViewProgressBinding.inflate(LayoutInflater.from(getContext())).getRoot();
|
||||
@@ -103,21 +105,46 @@ public class ProgressLayout extends RelativeLayout {
|
||||
case CONTENT:
|
||||
mEmptyView.setVisibility(GONE);
|
||||
mProgressView.setVisibility(GONE);
|
||||
pauseLottieAnimation();
|
||||
setContentVisibility(true);
|
||||
break;
|
||||
case PROGRESS:
|
||||
mEmptyView.setVisibility(GONE);
|
||||
mProgressView.setVisibility(VISIBLE);
|
||||
pauseLottieAnimation();
|
||||
setContentVisibility(false);
|
||||
break;
|
||||
case EMPTY:
|
||||
mEmptyView.setVisibility(VISIBLE);
|
||||
mProgressView.setVisibility(GONE);
|
||||
playLottieAnimation();
|
||||
setContentVisibility(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void playLottieAnimation() {
|
||||
try {
|
||||
LottieAnimationView lottieView = mEmptyView.findViewById(com.fongmi.android.tv.R.id.lottieAnimation);
|
||||
if (lottieView != null) {
|
||||
lottieView.playAnimation();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 忽略错误,保持兼容性
|
||||
}
|
||||
}
|
||||
|
||||
private void pauseLottieAnimation() {
|
||||
try {
|
||||
LottieAnimationView lottieView = mEmptyView.findViewById(com.fongmi.android.tv.R.id.lottieAnimation);
|
||||
if (lottieView != null) {
|
||||
lottieView.pauseAnimation();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 忽略错误,保持兼容性
|
||||
}
|
||||
}
|
||||
|
||||
private void setContentVisibility(boolean visible) {
|
||||
for (View view : mContentViews) {
|
||||
if (visible) showView(view);
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="20dp"
|
||||
android:height="20dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M13,2L3,14h8l-1,8l10,-12h-8l1,-8z"/>
|
||||
</vector>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM12,5c1.66,0 3,1.34 3,3s-1.34,3 -3,3S9,9.66 9,8S10.34,5 12,5zM12,19.2c-2.5,0 -4.71,-1.28 -6,-3.22c0.03,-1.99 4,-3.08 6,-3.08c1.99,0 5.97,1.09 6,3.08C16.71,17.92 14.5,19.2 12,19.2z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5 5,-2.24 5,-5 -2.24,-5 -5,-5zM15.19,14.85L13.2,12.86c.5,-1.19.25,-2.58 -0.73,-3.55 -1.17,-1.18 -3.01,-1.39 -4.39,-0.51l1.99,1.99c0.22,0.22 0.22,0.57 0,0.79l-0.79,0.79c-0.22,0.22 -0.57,0.22 -0.79,0L6.5,10.38c-0.88,1.37 -0.67,3.22 0.51,4.39 0.97,0.98 2.36,1.23 3.55,0.73l1.99,1.99c0.22,0.22 0.57,0.22 0.79,0l0.79,-0.79c0.22,-0.22 0.22,-0.57 0,-0.79z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,19c1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3s-3,1.34 -3,3S10.34,19 12,19zM12,17c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1s1,0.45 1,1S12.55,17 12,17zM17,9c0,-2.76 -2.24,-5 -5,-5S7,6.24 7,9c0,1.59 0.76,3 1.95,3.91C7.58,13.71 6.5,15.27 6.5,17c0,0.55 0.45,1 1,1s1,-0.45 1,-1c0,-1.65 1.35,-3 3,-3s3,1.35 3,3c0,0.55 0.45,1 1,1s1,-0.45 1,-1c0,-1.73 -1.08,-3.29 -2.45,-4.09C15.24,12 16,10.59 16,9zM12,12c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3s3,1.34 3,3S13.66,12 12,12z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M19,5v14L5,19L5,5h14m1.1,-2L3.9,3c-0.5,0 -0.9,0.4 -0.9,0.9v16.2c0,0.4 0.4,0.9 0.9,0.9h16.2c0.4,0 0.9,-0.5 0.9,-0.9L21,3.9c0,-0.5 -0.4,-0.9 -0.9,-0.9zM11,7h6v2h-6L11,7zM11,11h6v2h-6v-2zM11,15h6v2h-6zM7,7h2v2L7,9zM7,11h2v2L7,13zM7,15h2v2L7,17z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,3C8.69,3 6,5.69 6,9s2.69,6 6,6s6,-2.69 6,-6S15.31,3 12,3zM12,13c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4s4,1.79 4,4S14.21,13 12,13zM21,18h-2v2h-1.5v-2h-2v-1.5h2v-2h1.5v2h2V18zM11,18c0,-0.28 0.05,-0.54 0.12,-0.8c-0.87,-0.54 -1.89,-0.88 -3,-0.99C5.73,15.91 3,16.71 3,18.5V20h8.26C11.1,19.36 11,18.69 11,18z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M21,15h2v2h-2v-2zM21,11h2v2h-2v-2zM23,19h-2v2c1,0 2,-1 2,-2zM13,3h2v2h-2L13,3zM21,7h2v2h-2L21,7zM21,3v2h2c0,-1 -1,-2 -2,-2zM1,7h2v2L1,9L1,7zM17,3h2v2h-2L17,3zM17,19h2v2h-2v-2zM3,3C2,3 1,4 1,5h2L3,3zM9,3h2v2L9,5L9,3zM5,3h2v2L5,5L5,3zM1,11v8c0,1.1 0.9,2 2,2h12L15,11L1,11zM3,19l2.5,-3.21 1.79,2.15 2.5,-3.22L13,19L3,19z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M21,3H3C2,3 1,4 1,5v14c0,1.1 0.9,2 2,2h18c1,0 2,-1 2,-2V5c0,-1 -1,-2 -2,-2zM21,19H3V5h18v14zM14.5,11.5c0,0.83 -0.67,1.5 -1.5,1.5h-2v2h2v1h-3v-4c0,-0.83 0.67,-1.5 1.5,-1.5h2c0.83,0 1.5,0.67 1.5,1.5zM11.5,8.5H13v1h-2V7h2v1h-1.5zM16,13.5c0,0.83 -0.67,1.5 -1.5,1.5h-2v-2h2v-1h-2v-2h2c0.83,0 1.5,0.67 1.5,1.5v2z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M18.5,8C19.88,8 21,6.88 21,5.5C21,4.12 19.88,3 18.5,3C17.12,3 16,4.12 16,5.5C16,6.88 17.12,8 18.5,8zM5.5,8C6.88,8 8,6.88 8,5.5C8,4.12 6.88,3 5.5,3C4.12,3 3,4.12 3,5.5C3,6.88 4.12,8 5.5,8zM7.5,17H16.5C17.6,17 18.5,16.1 18.5,15V11.41C18.5,10.08 16.92,9.43 16,10.36C14.55,11.8 13.45,11.8 12,10.36C10.55,8.91 9.45,8.91 8,10.36C7.07,11.29 5.5,10.64 5.5,9.31V15C5.5,16.1 6.4,17 7.5,17z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M15,8v8H5V8h10m1,-2H4C3.45,6 3,6.45 3,7v10c0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1v-3.5l4,4v-11l-4,4V7c0,-0.55 -0.45,-1 -1,-1z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,16c-1.79,0 -3.23,-1.43 -3.23,-3.23 0,-0.36 0.06,-0.7 0.17,-1.02l4.08,4.08c-0.32,0.11 -0.66,0.17 -1.02,0.17zM12,8c1.79,0 3.23,1.43 3.23,3.23 0,0.36 -0.06,0.7 -0.17,1.02L10.98,8.17C11.3,8.06 11.64,8 12,8zM19.94,19.5L17.77,17.33C16.68,18.15 15.39,18.75 14,19.08v-2.11c0.63,-0.23 1.21,-0.54 1.73,-0.92l-1.4,-1.4c-0.64,0.51 -1.44,0.81 -2.33,0.81 -2.09,0 -3.77,-1.68 -3.77,-3.77 0,-0.89 0.31,-1.69 0.81,-2.33L7.65,8.97c-0.92,0.74 -1.73,1.61 -2.38,2.57C5.09,11.83 5,12.15 5,12.5s0.09,0.67 0.27,0.96c1.87,2.95 5.07,4.77 8.73,4.77 1.35,0 2.63,-0.22 3.83,-0.61l-0.39,-0.39 2.5,2.5c0.39,0.39 1.02,0.39 1.41,0 0.4,-0.39 0.4,-1.02 0,-1.41l-1.41,-1.41zM5.06,4.5l2.18,2.18c1.09,-0.82 2.37,-1.42 3.76,-1.76L11,7.03c-0.63,0.23 -1.21,0.54 -1.73,0.92l1.4,1.4c0.64,-0.51 1.44,-0.81 2.33,-0.81 2.09,0 3.77,1.68 3.77,3.77 0,0.89 -0.31,1.69 -0.81,2.33l1.4,1.4c0.92,-0.74 1.73,-1.61 2.38,-2.57 0.18,-0.29 0.27,-0.61 0.27,-0.96s-0.09,-0.67 -0.27,-0.96C18.87,8.6 15.67,6.78 12,6.78c-1.35,0 -2.63,0.22 -3.83,0.61L5.06,4.27c-0.39,-0.39 -1.02,-0.39 -1.41,0s-0.39,1.02 0,1.41l1.41,1.41z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/black"
|
||||
android:fitsSystemWindows="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- 标题栏 -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="24dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/privacy_agreement_title"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/privacy_agreement_tip"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14sp"
|
||||
android:alpha="0.8" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 协议内容滚动区域 -->
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:paddingStart="24dp"
|
||||
android:paddingEnd="24dp"
|
||||
android:paddingBottom="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/contentText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/privacy_agreement_content"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14sp"
|
||||
android:lineSpacingMultiplier="1.4"
|
||||
android:padding="16dp"
|
||||
android:background="@drawable/selector_item_round"
|
||||
android:alpha="0.9" />
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<!-- 按钮区域 -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="24dp"
|
||||
android:paddingStart="24dp"
|
||||
android:paddingEnd="24dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/disagreeButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="56dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/privacy_agreement_disagree"
|
||||
android:textColor="@color/white"
|
||||
android:backgroundTint="@color/black_60"
|
||||
android:textSize="13sp"
|
||||
android:maxLines="2"
|
||||
android:gravity="center" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/agreeButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="56dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="12dp"
|
||||
android:text="@string/privacy_agreement_agree"
|
||||
android:textColor="@color/black"
|
||||
android:backgroundTint="@color/primary"
|
||||
android:textSize="13sp"
|
||||
android:maxLines="2"
|
||||
android:gravity="center" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -19,6 +19,6 @@
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/error_empty"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/lottieAnimation"
|
||||
android:layout_width="180dp"
|
||||
android:layout_height="180dp"
|
||||
app:lottie_fileName="lottie_empty_1.json"
|
||||
app:lottie_loop="true"
|
||||
app:lottie_autoPlay="true" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/error_keep_empty"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/lottieAnimation"
|
||||
android:layout_width="180dp"
|
||||
android:layout_height="180dp"
|
||||
app:lottie_fileName="lottie_empty_1.json"
|
||||
app:lottie_loop="true"
|
||||
app:lottie_autoPlay="true" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/error_empty"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14sp"
|
||||
android:alpha="0.8" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/lottieAnimation"
|
||||
android:layout_width="180dp"
|
||||
android:layout_height="180dp"
|
||||
app:lottie_fileName="lottie_empty_1.json"
|
||||
app:lottie_loop="true"
|
||||
app:lottie_autoPlay="true" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/error_search_empty"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -125,7 +125,7 @@
|
||||
<string name="dialog_edit">修改</string>
|
||||
<string name="dialog_positive">确定</string>
|
||||
<string name="dialog_negative">取消</string>
|
||||
<string name="dialog_paste">从剪贴板粘贴</string>
|
||||
<string name="dialog_paste">点我粘贴</string>
|
||||
<string name="dialog_config_hint">请输入接口…</string>
|
||||
<string name="dialog_config_name">请输入名称…</string>
|
||||
<string name="dialog_config_url">请输入地址…</string>
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
<string name="error_play_flag">暫無線路資料</string>
|
||||
<string name="error_play_timeout">連線逾時</string>
|
||||
<string name="error_detail">暫無播放資料</string>
|
||||
<string name="error_empty">找不到資料</string>
|
||||
<string name="error_empty">這裡撒子內容都沒得~</string>
|
||||
<string name="error_cast_file">不支持的檔案格式</string>
|
||||
<string name="error_device_limit">設備授權數已達上限</string>
|
||||
<string name="error_live_empty">該訂閱無直播內容</string>
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
<string name="setting_choose">Choose</string>
|
||||
<string name="setting_off">Off</string>
|
||||
<string name="setting_on">On</string>
|
||||
<string name="app_version">v3.0.3</string>
|
||||
<string name="app_version">v3.0.6</string>
|
||||
<string name="about_github">View on GitHub</string>
|
||||
|
||||
<!-- Backup & Restore -->
|
||||
@@ -126,7 +126,7 @@
|
||||
<string name="dialog_edit">Edit</string>
|
||||
<string name="dialog_positive">OK</string>
|
||||
<string name="dialog_negative">Cancel</string>
|
||||
<string name="dialog_paste">Paste from clipboard</string>
|
||||
<string name="dialog_paste">Click to paste</string>
|
||||
<string name="dialog_config_hint">Please enter the config…</string>
|
||||
<string name="dialog_config_name">Please enter the name…</string>
|
||||
<string name="dialog_config_url">Please enter the url…</string>
|
||||
@@ -151,7 +151,9 @@
|
||||
<string name="error_device_limit">Device authorization limit reached</string>
|
||||
<string name="error_live_empty">This subscription has no live content</string>
|
||||
<string name="error_no_live">Current source has no live content</string>
|
||||
<string name="error_empty">Not found</string>
|
||||
<string name="error_empty">这里撒子内容都没得~</string>
|
||||
<string name="error_keep_empty">老表~没得收藏哈</string>
|
||||
<string name="error_search_empty">搜索无结果,换个关键词试试</string>
|
||||
<string name="error_detail">No play data</string>
|
||||
<string name="error_play_flag">No flag data</string>
|
||||
<string name="error_play_code">Error code: <xliff:g name="name">%s</xliff:g></string>
|
||||
@@ -237,6 +239,13 @@
|
||||
|
||||
<string name="source_hint">No video sources added yet\nClick the button below to add</string>
|
||||
<string name="add_source">Add Source</string>
|
||||
|
||||
<!-- 隐私协议相关 -->
|
||||
<string name="privacy_agreement_title">XMBOX软件许可协议</string>
|
||||
<string name="privacy_agreement_tip">请仔细阅读以下协议条款</string>
|
||||
<string name="privacy_agreement_agree">我已阅读并同意</string>
|
||||
<string name="privacy_agreement_disagree">不同意并退出</string>
|
||||
<string name="privacy_agreement_content">XMBOX软件许可协议:\n\n- 以下是对[GPL-3.0](LICENSE.md)开源协议的补充,如有冲突,以以下协议为准。\n- 词语约定: 本协议中的"本软件"指"XMBOX软件","用户"指签署本协议的使用者,"版权数据"指包括但不限于视频、图像、音频、名字等在内的他人拥有所属版权的数据。\n\n1. 本软件仅为技术性多媒体播放器外壳("空壳播放器"),核心功能限于基础媒体文件解析与播放。\n\n2. 本软件自身不包含、不预装、不内置、不集成、不主动推荐、不直接或间接提供任何音视频、直播、图文等媒体资源内容。软件播放的任何资源均非由本软件或其开发者提供。\n\n3. 用户通过本软件播放的任何内容均完全来源于用户自行配置、输入、添加、获取或选择的第三方来源(如网络地址、本地文件、用户安装的插件/扩展/配置源等)。本软件仅作为访问用户自行指定内容的技术工具。\n\n4. 本软件无法控制、筛选、审查或保证用户访问的任何第三方内容的合法性、版权状态、准确性、安全性或适宜性。用户对其播放的内容负全部责任。\n\n5. 关于用户责任与风险承担:\n • 用户必须确保其通过本软件配置、访问或播放的所有内容均已获相关权利人合法授权,或属于法律允许的自由使用范畴。\n • 用户理解并同意,使用本软件访问第三方资源可能涉及侵犯版权、传播非法信息、隐私泄露、网络安全等风险。因用户使用本软件访问、播放或传播内容产生的一切法律责任、纠纷、损失及后果(包括法律诉讼、行政处罚、民事赔偿等),均由用户自行承担,与本软件及其开发者无涉。\n • 开发者不认可、不支持任何利用本软件规避技术保护措施(如DRM)的行为,此类行为导致的侵权责任由用户全权承担。\n\n6. 用户承诺并保证不利用本软件从事任何侵犯他人知识产权或其他合法权益的活动,或进行任何违反法律法规的行为。严禁使用本软件播放、传播盗版、色情、暴力、赌博、诈骗、危害国家安全、危害社会稳定等非法或侵权内容。\n\n7. 在任何情况下,本软件开发者均不就因用户使用或无法使用本软件、用户配置或访问的第三方资源、用户违反本协议或法律法规的行为导致的任何直接、间接、偶然、特殊、惩罚性或结果性损害(包括利润损失、数据丢失、业务中断、声誉损害等)承担任何责任(无论基于合同、侵权、严格责任或其他法律理论)。\n\n8. 本软件运行可能依赖第三方库、服务或技术。开发者不对这些第三方组件的可用性、准确性、功能或合法性负责。\n\n9. 用户理解并同意,使用本软件(包括下载、安装、运行)存在固有技术风险(如软件缺陷、兼容性问题、系统不稳定等),用户应自行承担此风险。\n\n10. 本软件仅用于对技术可行性的探索及研究,不接受任何商业(包括但不限于广告等)合作及捐赠。\n\n11. 本软件内使用的部分包括但不限于字体、图片等资源来源于互联网。如果出现侵权可联系开发者移除。\n\n12. 使用本软件的过程中可能会产生版权数据。对于这些版权数据,本软件不拥有它们的所有权。为了避免侵权,用户务必在 24 小时内 清除使用本项目的过程中所产生的版权数据。\n\n13. 本协议受中华人民共和国法律管辖并据其解释。若用户所在地法律强制规定特定责任条款,应以当地法律要求为准,但其他条款仍保持有效。任何由本协议或使用本软件引起的争议,应首先通过友好协商解决。\n\n14. 若你使用了本软件,即代表你接受本协议。\n\n15. 本协议更新后,继续使用视为接受新协议。</string>
|
||||
<string name="source_hint_setting">Add Source</string>
|
||||
<string name="source_hint_live">Add Live Source</string>
|
||||
<string name="source_hint_wall">Add Wallpaper Source</string>
|
||||
|
||||
@@ -10,6 +10,13 @@
|
||||
|
||||
<application>
|
||||
|
||||
<activity
|
||||
android:name=".ui.activity.PrivacyAgreementActivity"
|
||||
android:configChanges="screenSize|smallestScreenSize|screenLayout|uiMode|orientation"
|
||||
android:exported="false"
|
||||
android:screenOrientation="fullUser"
|
||||
android:windowSoftInputMode="adjustPan" />
|
||||
|
||||
<activity
|
||||
android:name=".ui.activity.HomeActivity"
|
||||
android:configChanges="screenSize|smallestScreenSize|screenLayout|uiMode|orientation"
|
||||
|
||||
@@ -14,11 +14,10 @@ import com.fongmi.android.tv.utils.Notify;
|
||||
import com.fongmi.android.tv.utils.ResUtil;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Github;
|
||||
import com.github.catvod.utils.Logger;
|
||||
import com.github.catvod.utils.Path;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.orhanobut.logger.Logger;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
@@ -27,25 +26,21 @@ import java.util.Locale;
|
||||
public class Updater implements Download.Callback {
|
||||
|
||||
private DialogUpdateBinding binding;
|
||||
private Download download;
|
||||
private final Download download;
|
||||
private AlertDialog dialog;
|
||||
private boolean dev;
|
||||
private String downloadUrl;
|
||||
private boolean forceCheck; // 是否为手动检查
|
||||
|
||||
private File getFile() {
|
||||
return Path.cache("update.apk");
|
||||
}
|
||||
|
||||
private String getApkName() {
|
||||
return "mobile-" + BuildConfig.FLAVOR_abi + ".apk";
|
||||
private String getJson() {
|
||||
return Github.getJson(dev, BuildConfig.FLAVOR_mode);
|
||||
}
|
||||
|
||||
private String getJson() {
|
||||
String url = Github.getReleaseApi();
|
||||
boolean usingCnMirror = Github.useCnMirror();
|
||||
Logger.d("Using CN Mirror: " + usingCnMirror);
|
||||
Logger.d("Update check URL: " + url);
|
||||
return url;
|
||||
private String getApk() {
|
||||
return Github.getApk(dev, BuildConfig.FLAVOR_mode + "-" + BuildConfig.FLAVOR_abi);
|
||||
}
|
||||
|
||||
public static Updater create() {
|
||||
@@ -53,12 +48,14 @@ public class Updater implements Download.Callback {
|
||||
}
|
||||
|
||||
public Updater() {
|
||||
this.download = Download.create("", getFile(), this);
|
||||
this.download = Download.create(getApk(), getFile(), this);
|
||||
this.forceCheck = false;
|
||||
}
|
||||
|
||||
public Updater force() {
|
||||
Notify.show(R.string.update_check);
|
||||
Setting.putUpdate(true);
|
||||
this.forceCheck = true; // 标记为手动检查
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -81,73 +78,48 @@ public class Updater implements Download.Callback {
|
||||
App.execute(() -> doInBackground(activity));
|
||||
}
|
||||
|
||||
private boolean need(String tagName) {
|
||||
Logger.d("Current version: " + BuildConfig.VERSION_NAME);
|
||||
Logger.d("Latest version: " + tagName);
|
||||
if (tagName.startsWith("v")) tagName = tagName.substring(1);
|
||||
|
||||
// 版本比较逻辑
|
||||
try {
|
||||
String[] currentParts = BuildConfig.VERSION_NAME.split("\\.");
|
||||
String[] remoteParts = tagName.split("\\.");
|
||||
|
||||
// 比较主版本号
|
||||
for (int i = 0; i < Math.min(currentParts.length, remoteParts.length); i++) {
|
||||
int current = Integer.parseInt(currentParts[i]);
|
||||
int remote = Integer.parseInt(remoteParts[i]);
|
||||
|
||||
if (remote > current) {
|
||||
return Setting.getUpdate(); // 远程版本高于当前版本,需要更新
|
||||
} else if (remote < current) {
|
||||
return false; // 远程版本低于当前版本,不需要更新
|
||||
}
|
||||
// 如果相等,继续比较下一级版本号
|
||||
}
|
||||
|
||||
// 如果前面的版本号都相等,但远程版本有更多的版本号,视为更新
|
||||
if (remoteParts.length > currentParts.length) {
|
||||
return Setting.getUpdate();
|
||||
}
|
||||
|
||||
return false; // 版本相同或远程版本较低,不需要更新
|
||||
} catch (NumberFormatException e) {
|
||||
// 如果版本号解析失败,退回到简单字符串比较
|
||||
Logger.e("Version parsing failed", e);
|
||||
return Setting.getUpdate() && !tagName.equals(BuildConfig.VERSION_NAME);
|
||||
}
|
||||
private boolean need(int code, String name) {
|
||||
return Setting.getUpdate() && (dev ? !name.equals(BuildConfig.VERSION_NAME) && code >= BuildConfig.VERSION_CODE : code > BuildConfig.VERSION_CODE);
|
||||
}
|
||||
|
||||
private void doInBackground(Activity activity) {
|
||||
try {
|
||||
String jsonUrl = getJson();
|
||||
Logger.d("Fetching update info from: " + jsonUrl);
|
||||
String response = OkHttp.string(jsonUrl);
|
||||
Logger.d("Update check response: " + response);
|
||||
String response = OkHttp.string(getJson());
|
||||
|
||||
JSONObject release = new JSONObject(response);
|
||||
String tagName = release.getString("tag_name");
|
||||
String body = release.getString("body");
|
||||
JSONArray assets = release.getJSONArray("assets");
|
||||
|
||||
// Find the correct APK asset
|
||||
String apkName = getApkName();
|
||||
for (int i = 0; i < assets.length(); i++) {
|
||||
JSONObject asset = assets.getJSONObject(i);
|
||||
if (asset.getString("name").equals(apkName)) {
|
||||
downloadUrl = asset.getString("browser_download_url");
|
||||
break;
|
||||
// 检查响应是否包含错误信息,只在手动检查时提示
|
||||
if (response.contains("rate limit exceeded")) {
|
||||
if (forceCheck) {
|
||||
App.post(() -> Notify.show("检查更新失败:API请求过于频繁,请稍后重试"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (downloadUrl != null && need(tagName)) {
|
||||
download = Download.create(downloadUrl, getFile(), this);
|
||||
App.post(() -> show(activity, tagName, body));
|
||||
if (response.contains("Not Found Project") || response.contains("Not Found")) {
|
||||
if (forceCheck) {
|
||||
App.post(() -> Notify.show("检查更新失败:更新服务暂时不可用"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
JSONObject object = new JSONObject(response);
|
||||
String name = object.optString("name");
|
||||
String desc = object.optString("desc");
|
||||
int code = object.optInt("code");
|
||||
if (need(code, name)) {
|
||||
App.post(() -> show(activity, name, desc));
|
||||
} else {
|
||||
Logger.d("No update needed or APK not found");
|
||||
// 只在手动检查时提示已是最新版
|
||||
if (forceCheck) {
|
||||
App.post(() -> Notify.show("已是最新版本 " + name));
|
||||
}
|
||||
Logger.d("Already latest version: " + name);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.e("Update check failed", e);
|
||||
e.printStackTrace();
|
||||
// 只在手动检查时提示网络错误
|
||||
if (forceCheck) {
|
||||
App.post(() -> Notify.show("检查更新失败:网络连接异常"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +160,6 @@ public class Updater implements Download.Callback {
|
||||
|
||||
@Override
|
||||
public void error(String msg) {
|
||||
Logger.e("Download error: " + msg);
|
||||
Notify.show(msg);
|
||||
dismiss();
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ import com.fongmi.android.tv.utils.Util;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.google.android.flexbox.FlexDirection;
|
||||
import com.google.android.flexbox.FlexboxLayoutManager;
|
||||
import com.airbnb.lottie.LottieAnimationView;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
@@ -151,12 +152,14 @@ public class CollectActivity extends BaseActivity implements CustomScroller.Call
|
||||
if (mCollectAdapter.getPosition() == 0) mSearchAdapter.addAll(result.getList());
|
||||
mCollectAdapter.add(Collect.create(result.getList()));
|
||||
mCollectAdapter.add(result.getList());
|
||||
updateEmptyState();
|
||||
});
|
||||
mViewModel.result.observe(this, result -> {
|
||||
boolean same = !result.getList().isEmpty() && mCollectAdapter.getActivated().getSite().equals(result.getList().get(0).getSite());
|
||||
if (same) mCollectAdapter.getActivated().getList().addAll(result.getList());
|
||||
if (same) mSearchAdapter.addAll(result.getList());
|
||||
mScroller.endLoading(result);
|
||||
updateEmptyState();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -187,6 +190,7 @@ public class CollectActivity extends BaseActivity implements CustomScroller.Call
|
||||
mBinding.agent.setVisibility(View.GONE);
|
||||
mBinding.view.setVisibility(View.VISIBLE);
|
||||
mBinding.result.setVisibility(View.VISIBLE);
|
||||
updateEmptyState(); // 搜索开始时显示空状态
|
||||
if (mExecutor != null) mExecutor.shutdownNow();
|
||||
mExecutor = new PauseExecutor(20);
|
||||
String keyword = mBinding.keyword.getText().toString().trim();
|
||||
@@ -194,6 +198,27 @@ public class CollectActivity extends BaseActivity implements CustomScroller.Call
|
||||
App.post(() -> mRecordAdapter.add(keyword), 250);
|
||||
}
|
||||
|
||||
private void updateEmptyState() {
|
||||
// 只有在结果页面可见且搜索结果为空时才显示空状态动画
|
||||
boolean isResultVisible = isVisible(mBinding.result);
|
||||
boolean isEmpty = mSearchAdapter.getItemCount() == 0;
|
||||
boolean shouldShowEmpty = isResultVisible && isEmpty;
|
||||
|
||||
mBinding.emptyLayout.getRoot().setVisibility(shouldShowEmpty ? View.VISIBLE : View.GONE);
|
||||
|
||||
// 控制Lottie动画播放
|
||||
if (shouldShowEmpty) {
|
||||
try {
|
||||
LottieAnimationView lottieView = mBinding.emptyLayout.getRoot().findViewById(R.id.lottieAnimation);
|
||||
if (lottieView != null) {
|
||||
lottieView.playAnimation();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 忽略错误
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void search(Site site, String keyword) {
|
||||
try {
|
||||
mViewModel.searchContent(site, keyword, false);
|
||||
@@ -235,6 +260,7 @@ public class CollectActivity extends BaseActivity implements CustomScroller.Call
|
||||
mBinding.result.setVisibility(View.GONE);
|
||||
mBinding.site.setVisibility(View.VISIBLE);
|
||||
mBinding.agent.setVisibility(View.VISIBLE);
|
||||
mBinding.emptyLayout.getRoot().setVisibility(View.GONE); // 隐藏空状态动画
|
||||
if (mExecutor != null) mExecutor.shutdownNow();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.fongmi.android.tv.ui.adapter.HistoryAdapter;
|
||||
import com.fongmi.android.tv.ui.base.BaseActivity;
|
||||
import com.fongmi.android.tv.ui.dialog.SyncDialog;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.airbnb.lottie.LottieAnimationView;
|
||||
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
@@ -59,6 +60,25 @@ public class HistoryActivity extends BaseActivity implements HistoryAdapter.OnCl
|
||||
private void getHistory() {
|
||||
mAdapter.addAll(History.get());
|
||||
mBinding.delete.setVisibility(mAdapter.getItemCount() > 0 ? View.VISIBLE : View.GONE);
|
||||
updateEmptyState();
|
||||
}
|
||||
|
||||
private void updateEmptyState() {
|
||||
boolean isEmpty = mAdapter.getItemCount() == 0;
|
||||
mBinding.emptyLayout.getRoot().setVisibility(isEmpty ? View.VISIBLE : View.GONE);
|
||||
mBinding.recycler.setVisibility(isEmpty ? View.GONE : View.VISIBLE);
|
||||
|
||||
// 控制Lottie动画播放
|
||||
if (isEmpty) {
|
||||
try {
|
||||
LottieAnimationView lottieView = mBinding.emptyLayout.getRoot().findViewById(R.id.lottieAnimation);
|
||||
if (lottieView != null) {
|
||||
lottieView.playAnimation();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 忽略错误
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onSync(View view) {
|
||||
@@ -67,7 +87,10 @@ public class HistoryActivity extends BaseActivity implements HistoryAdapter.OnCl
|
||||
|
||||
private void onDelete(View view) {
|
||||
if (mAdapter.isDelete()) {
|
||||
new MaterialAlertDialogBuilder(this).setTitle(R.string.dialog_delete_record).setMessage(R.string.dialog_delete_history).setNegativeButton(R.string.dialog_negative, null).setPositiveButton(R.string.dialog_positive, (dialog, which) -> mAdapter.clear()).show();
|
||||
new MaterialAlertDialogBuilder(this).setTitle(R.string.dialog_delete_record).setMessage(R.string.dialog_delete_history).setNegativeButton(R.string.dialog_negative, null).setPositiveButton(R.string.dialog_positive, (dialog, which) -> {
|
||||
mAdapter.clear();
|
||||
updateEmptyState();
|
||||
}).show();
|
||||
} else if (mAdapter.getItemCount() > 0) {
|
||||
mAdapter.setDelete(true);
|
||||
} else {
|
||||
@@ -91,6 +114,7 @@ public class HistoryActivity extends BaseActivity implements HistoryAdapter.OnCl
|
||||
if (mAdapter.getItemCount() > 0) return;
|
||||
mBinding.delete.setVisibility(View.GONE);
|
||||
mAdapter.setDelete(false);
|
||||
updateEmptyState();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,6 +16,7 @@ import androidx.viewbinding.ViewBinding;
|
||||
|
||||
import com.fongmi.android.tv.App;
|
||||
import com.fongmi.android.tv.R;
|
||||
import com.fongmi.android.tv.Setting;
|
||||
import com.fongmi.android.tv.Updater;
|
||||
import com.fongmi.android.tv.api.config.LiveConfig;
|
||||
import com.fongmi.android.tv.api.config.VodConfig;
|
||||
@@ -62,6 +63,18 @@ public class HomeActivity extends BaseActivity implements NavigationBarView.OnIt
|
||||
|
||||
@Override
|
||||
protected void initView(Bundle savedInstanceState) {
|
||||
// 检查隐私协议
|
||||
if (!Setting.isPrivacyAgreed()) {
|
||||
Intent intent = new Intent(this, PrivacyAgreementActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// 确保通知渠道已创建(用户已同意协议的情况)
|
||||
com.fongmi.android.tv.utils.Notify.createChannel();
|
||||
|
||||
orientation = getResources().getConfiguration().orientation;
|
||||
Updater.create().release().start(this);
|
||||
initFragment(savedInstanceState);
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.fongmi.android.tv.ui.base.BaseActivity;
|
||||
import com.fongmi.android.tv.ui.dialog.SyncDialog;
|
||||
import com.fongmi.android.tv.utils.Notify;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.airbnb.lottie.LottieAnimationView;
|
||||
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
@@ -63,6 +64,25 @@ public class KeepActivity extends BaseActivity implements KeepAdapter.OnClickLis
|
||||
private void getKeep() {
|
||||
mAdapter.addAll(Keep.getVod());
|
||||
mBinding.delete.setVisibility(mAdapter.getItemCount() > 0 ? View.VISIBLE : View.GONE);
|
||||
updateEmptyState();
|
||||
}
|
||||
|
||||
private void updateEmptyState() {
|
||||
boolean isEmpty = mAdapter.getItemCount() == 0;
|
||||
mBinding.emptyLayout.getRoot().setVisibility(isEmpty ? View.VISIBLE : View.GONE);
|
||||
mBinding.recycler.setVisibility(isEmpty ? View.GONE : View.VISIBLE);
|
||||
|
||||
// 控制Lottie动画播放
|
||||
if (isEmpty) {
|
||||
try {
|
||||
LottieAnimationView lottieView = mBinding.emptyLayout.getRoot().findViewById(R.id.lottieAnimation);
|
||||
if (lottieView != null) {
|
||||
lottieView.playAnimation();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 忽略错误
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onSync(View view) {
|
||||
@@ -71,7 +91,10 @@ public class KeepActivity extends BaseActivity implements KeepAdapter.OnClickLis
|
||||
|
||||
private void onDelete(View view) {
|
||||
if (mAdapter.isDelete()) {
|
||||
new MaterialAlertDialogBuilder(this).setTitle(R.string.dialog_delete_record).setMessage(R.string.dialog_delete_keep).setNegativeButton(R.string.dialog_negative, null).setPositiveButton(R.string.dialog_positive, (dialog, which) -> mAdapter.clear()).show();
|
||||
new MaterialAlertDialogBuilder(this).setTitle(R.string.dialog_delete_record).setMessage(R.string.dialog_delete_keep).setNegativeButton(R.string.dialog_negative, null).setPositiveButton(R.string.dialog_positive, (dialog, which) -> {
|
||||
mAdapter.clear();
|
||||
updateEmptyState();
|
||||
}).show();
|
||||
} else if (mAdapter.getItemCount() > 0) {
|
||||
mAdapter.setDelete(true);
|
||||
} else {
|
||||
@@ -114,6 +137,7 @@ public class KeepActivity extends BaseActivity implements KeepAdapter.OnClickLis
|
||||
if (mAdapter.getItemCount() > 0) return;
|
||||
mBinding.delete.setVisibility(View.GONE);
|
||||
mAdapter.setDelete(false);
|
||||
updateEmptyState();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.fongmi.android.tv.ui.activity;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.viewbinding.ViewBinding;
|
||||
|
||||
import com.fongmi.android.tv.R;
|
||||
import com.fongmi.android.tv.Setting;
|
||||
import com.fongmi.android.tv.databinding.ActivityPrivacyAgreementBinding;
|
||||
import com.fongmi.android.tv.ui.base.BaseActivity;
|
||||
|
||||
public class PrivacyAgreementActivity extends BaseActivity {
|
||||
|
||||
private ActivityPrivacyAgreementBinding mBinding;
|
||||
|
||||
@Override
|
||||
protected ViewBinding getBinding() {
|
||||
return mBinding = ActivityPrivacyAgreementBinding.inflate(getLayoutInflater());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initView(Bundle savedInstanceState) {
|
||||
// 隐私协议页面初始化完成
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initEvent() {
|
||||
if (mBinding != null) {
|
||||
if (mBinding.agreeButton != null) {
|
||||
mBinding.agreeButton.setOnClickListener(this::onAgree);
|
||||
}
|
||||
if (mBinding.disagreeButton != null) {
|
||||
mBinding.disagreeButton.setOnClickListener(this::onDisagree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onAgree(View view) {
|
||||
// 用户同意协议
|
||||
Setting.setPrivacyAgreed(true);
|
||||
|
||||
// 创建通知渠道(此时才请求通知权限)
|
||||
com.fongmi.android.tv.utils.Notify.createChannel();
|
||||
|
||||
// 跳转到主界面,清除任务栈避免用户通过任务管理器回到协议页面
|
||||
Intent intent = new Intent(this, HomeActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
|
||||
private void onDisagree(View view) {
|
||||
// 用户不同意协议,退出应用
|
||||
try {
|
||||
// 清除隐私协议状态(可选,确保下次启动重新询问)
|
||||
Setting.setPrivacyAgreed(false);
|
||||
|
||||
// 优雅地退出应用
|
||||
finishAffinity();
|
||||
|
||||
// 延迟退出,让 Activity 完成销毁
|
||||
new android.os.Handler(android.os.Looper.getMainLooper()).postDelayed(() -> {
|
||||
System.exit(0);
|
||||
}, 100);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// 备选退出方案
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
// 禁用返回键,用户必须做出选择
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
onDisagree(null);
|
||||
return true;
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
// 清理 binding 引用
|
||||
mBinding = null;
|
||||
super.onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,28 +59,6 @@ public class SettingPlayerActivity extends BaseActivity implements UaCallback, B
|
||||
mBinding.renderText.setText((render = ResUtil.getStringArray(R.array.select_render))[Setting.getRender()]);
|
||||
mBinding.captionText.setText((caption = ResUtil.getStringArray(R.array.select_caption))[Setting.isCaption() ? 1 : 0]);
|
||||
mBinding.backgroundText.setText((background = ResUtil.getStringArray(R.array.select_background))[Setting.getBackground()]);
|
||||
|
||||
// 设置开关的颜色为黄色
|
||||
int accentColor = getResources().getColor(R.color.accent);
|
||||
android.content.res.ColorStateList colorStateList = new android.content.res.ColorStateList(
|
||||
new int[][]{
|
||||
new int[]{-android.R.attr.state_checked},
|
||||
new int[]{android.R.attr.state_checked}
|
||||
},
|
||||
new int[]{
|
||||
0x66FFFFFF, // 未选中时的颜色
|
||||
accentColor // 选中时的颜色
|
||||
}
|
||||
);
|
||||
|
||||
mBinding.tunnelSwitch.setThumbTintList(android.content.res.ColorStateList.valueOf(android.graphics.Color.WHITE));
|
||||
mBinding.tunnelSwitch.setTrackTintList(colorStateList);
|
||||
mBinding.audioDecodeSwitch.setThumbTintList(android.content.res.ColorStateList.valueOf(android.graphics.Color.WHITE));
|
||||
mBinding.audioDecodeSwitch.setTrackTintList(colorStateList);
|
||||
mBinding.aacSwitch.setThumbTintList(android.content.res.ColorStateList.valueOf(android.graphics.Color.WHITE));
|
||||
mBinding.aacSwitch.setTrackTintList(colorStateList);
|
||||
mBinding.danmakuLoadSwitch.setThumbTintList(android.content.res.ColorStateList.valueOf(android.graphics.Color.WHITE));
|
||||
mBinding.danmakuLoadSwitch.setTrackTintList(colorStateList);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.view.WindowManager;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -162,6 +163,7 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo
|
||||
private Runnable mTimeUpdateRunnable;
|
||||
private BroadcastReceiver mBatteryReceiver;
|
||||
private int mBatteryLevel = -1;
|
||||
private boolean mIsCharging = false;
|
||||
|
||||
public static void push(FragmentActivity activity, String text) {
|
||||
if (FileChooser.isValid(activity, Uri.parse(text))) file(activity, FileChooser.getPathFromUri(activity, Uri.parse(text)));
|
||||
@@ -327,8 +329,12 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo
|
||||
if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
|
||||
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
|
||||
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
|
||||
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
|
||||
|
||||
if (level != -1 && scale != -1) {
|
||||
mBatteryLevel = (int) ((level / (float) scale) * 100);
|
||||
mIsCharging = (status == BatteryManager.BATTERY_STATUS_CHARGING ||
|
||||
status == BatteryManager.BATTERY_STATUS_FULL);
|
||||
updateTimeBattery();
|
||||
}
|
||||
}
|
||||
@@ -345,18 +351,41 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo
|
||||
}
|
||||
|
||||
private void updateTimeBattery() {
|
||||
TextView timeBattery = mBinding.getRoot().findViewById(R.id.time_battery);
|
||||
if (timeBattery == null) return;
|
||||
TextView timeBattery = findViewById(R.id.time_battery);
|
||||
TextView batteryText = findViewById(R.id.battery_icon);
|
||||
android.widget.ImageView chargingIndicator = findViewById(R.id.charging_indicator);
|
||||
|
||||
// 只在横屏模式下显示
|
||||
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
String time = DateFormat.getTimeFormat(this).format(System.currentTimeMillis());
|
||||
String battery = mBatteryLevel >= 0 ? mBatteryLevel + "%" : "";
|
||||
String text = time + (battery.isEmpty() ? "" : " | " + battery);
|
||||
timeBattery.setText(text);
|
||||
timeBattery.setVisibility(View.VISIBLE);
|
||||
// 只在全屏模式下显示
|
||||
if (isFullscreen()) {
|
||||
// 更新时间
|
||||
if (timeBattery != null) {
|
||||
String time = DateFormat.getTimeFormat(this).format(System.currentTimeMillis());
|
||||
timeBattery.setText(time);
|
||||
timeBattery.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
// 更新充电图标
|
||||
if (chargingIndicator != null) {
|
||||
chargingIndicator.setVisibility(mIsCharging && mBatteryLevel >= 0 ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
// 更新电池百分比文字
|
||||
if (batteryText != null && mBatteryLevel >= 0) {
|
||||
batteryText.setText(mBatteryLevel + "%");
|
||||
batteryText.setVisibility(View.VISIBLE);
|
||||
} else if (batteryText != null) {
|
||||
batteryText.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
timeBattery.setVisibility(View.GONE);
|
||||
if (timeBattery != null) {
|
||||
timeBattery.setVisibility(View.GONE);
|
||||
}
|
||||
if (batteryText != null) {
|
||||
batteryText.setVisibility(View.GONE);
|
||||
}
|
||||
if (chargingIndicator != null) {
|
||||
chargingIndicator.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1465,6 +1494,55 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo
|
||||
this.rotate = rotate;
|
||||
if (fullscreen && rotate) noPadding(mBinding.control.getRoot());
|
||||
if (fullscreen && !rotate) setPadding(mBinding.control.getRoot());
|
||||
// 检测屏幕方向变化并处理
|
||||
onOrientationChanged();
|
||||
}
|
||||
|
||||
// 添加屏幕方向变化处理方法
|
||||
private void onOrientationChanged() {
|
||||
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
// 切换到横屏模式
|
||||
onLandscapeMode();
|
||||
} else {
|
||||
// 切换到竖屏模式
|
||||
onPortraitMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void onLandscapeMode() {
|
||||
// 横屏模式下的特殊处理
|
||||
// 调整进度条的敏感度
|
||||
if (mPlayers != null) {
|
||||
long duration = mPlayers.getDuration();
|
||||
if (duration > TimeUnit.MINUTES.toMillis(30)) {
|
||||
mBinding.control.seek.setKeyTimeIncrement(TimeUnit.MINUTES.toMillis(1));
|
||||
} else if (duration > TimeUnit.MINUTES.toMillis(10)) {
|
||||
mBinding.control.seek.setKeyTimeIncrement(TimeUnit.SECONDS.toMillis(30));
|
||||
} else if (duration > 0) {
|
||||
mBinding.control.seek.setKeyTimeIncrement(TimeUnit.SECONDS.toMillis(15));
|
||||
}
|
||||
}
|
||||
|
||||
// 确保进度条状态正确
|
||||
if (mPlayers != null) {
|
||||
long position = mPlayers.getPosition();
|
||||
long duration = mPlayers.getDuration();
|
||||
if (position > 0 && duration > 0) {
|
||||
mBinding.control.seek.setPosition(position);
|
||||
mBinding.control.seek.setDuration(duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onPortraitMode() {
|
||||
// 竖屏模式下的处理
|
||||
// 恢复进度条的默认敏感度
|
||||
if (mPlayers != null) {
|
||||
long duration = mPlayers.getDuration();
|
||||
if (duration > 0) {
|
||||
mBinding.control.seek.setKeyTimeIncrement(duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isStop() {
|
||||
@@ -1566,10 +1644,40 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo
|
||||
|
||||
@Override
|
||||
public void onSeekEnd(long time) {
|
||||
mBinding.widget.seek.setVisibility(View.GONE);
|
||||
mPlayers.seek(time);
|
||||
showProgress();
|
||||
onPlay();
|
||||
handleLandscapeSeek(time);
|
||||
}
|
||||
|
||||
// 添加新的方法,处理横屏模式下的特殊逻辑
|
||||
private void handleLandscapeSeek(long time) {
|
||||
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
// 横屏模式下的特殊处理
|
||||
mBinding.widget.seek.setVisibility(View.GONE);
|
||||
mPlayers.pause();
|
||||
mPlayers.seek(time);
|
||||
showProgress();
|
||||
App.post(() -> {
|
||||
long actualPosition = mPlayers.getPosition();
|
||||
if (Math.abs(actualPosition - time) > 500) {
|
||||
mPlayers.seek(time);
|
||||
}
|
||||
onPlay();
|
||||
hideProgress();
|
||||
}, 150); // 横屏模式下延迟更长,确保跳转完成
|
||||
} else {
|
||||
// 竖屏模式使用原有逻辑
|
||||
mBinding.widget.seek.setVisibility(View.GONE);
|
||||
mPlayers.pause();
|
||||
mPlayers.seek(time);
|
||||
showProgress();
|
||||
App.post(() -> {
|
||||
long actualPosition = mPlayers.getPosition();
|
||||
if (Math.abs(actualPosition - time) > 500) {
|
||||
mPlayers.seek(time);
|
||||
}
|
||||
onPlay();
|
||||
hideProgress();
|
||||
}, 100); // 竖屏模式下延迟较短
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -8,6 +8,7 @@ import android.view.MotionEvent;
|
||||
import android.view.ScaleGestureDetector;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.content.res.Configuration;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
@@ -109,6 +110,17 @@ public class CustomKeyDownVod extends GestureDetector.SimpleOnGestureListener im
|
||||
if (isEdge(e1) || changeScale || lock || e1.getPointerCount() > 1) return true;
|
||||
float deltaX = e2.getX() - e1.getX();
|
||||
float deltaY = e1.getY() - e2.getY();
|
||||
|
||||
// 在横屏模式下,调整触摸事件的处理逻辑
|
||||
if (activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
// 横屏模式下,增加对水平滑动的敏感度
|
||||
if (Math.abs(deltaX) > Math.abs(deltaY) * 0.5f) {
|
||||
if (touch) checkFunc(distanceX, distanceY, e2);
|
||||
if (changeTime) listener.onSeek(time = (long) (deltaX * 50));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (touch) checkFunc(distanceX, distanceY, e2);
|
||||
if (changeTime) listener.onSeek(time = (long) (deltaX * 50));
|
||||
if (changeBright) setBright(deltaY);
|
||||
@@ -145,9 +157,32 @@ public class CustomKeyDownVod extends GestureDetector.SimpleOnGestureListener im
|
||||
|
||||
private void checkFunc(float distanceX, float distanceY, MotionEvent e2) {
|
||||
int four = ResUtil.getScreenWidth(activity) / 4;
|
||||
if (e2.getX() > four && e2.getX() < four * 3) center = true;
|
||||
else if (Math.abs(distanceX) < Math.abs(distanceY)) checkSide(e2);
|
||||
if (Math.abs(distanceX) >= Math.abs(distanceY)) changeTime = true;
|
||||
|
||||
// 在横屏模式下,调整中心区域的判断
|
||||
if (activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
// 横屏模式下,扩大中心区域,更容易触发进度条调整
|
||||
int centerStart = ResUtil.getScreenWidth(activity) / 3;
|
||||
int centerEnd = ResUtil.getScreenWidth(activity) * 2 / 3;
|
||||
if (e2.getX() > centerStart && e2.getX() < centerEnd) {
|
||||
center = true;
|
||||
} else if (Math.abs(distanceX) < Math.abs(distanceY)) {
|
||||
checkSide(e2);
|
||||
}
|
||||
// 横屏模式下,降低触发进度条调整的阈值
|
||||
if (Math.abs(distanceX) >= Math.abs(distanceY) * 0.7f) {
|
||||
changeTime = true;
|
||||
}
|
||||
} else {
|
||||
// 竖屏模式保持原有逻辑
|
||||
if (e2.getX() > four && e2.getX() < four * 3) {
|
||||
center = true;
|
||||
} else if (Math.abs(distanceX) < Math.abs(distanceY)) {
|
||||
checkSide(e2);
|
||||
}
|
||||
if (Math.abs(distanceX) >= Math.abs(distanceY)) {
|
||||
changeTime = true;
|
||||
}
|
||||
}
|
||||
touch = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
package com.fongmi.android.tv.ui.custom;
|
||||
|
||||
import android.animation.ArgbEvaluator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.appcompat.widget.AppCompatCheckBox;
|
||||
|
||||
public class CustomSwitch extends AppCompatCheckBox {
|
||||
|
||||
private Paint trackPaint;
|
||||
private Paint thumbPaint;
|
||||
private RectF trackRect;
|
||||
private RectF thumbRect;
|
||||
|
||||
private float thumbPosition = 0f; // 0 = 左边, 1 = 右边
|
||||
private int currentTrackColor;
|
||||
private int currentThumbColor;
|
||||
|
||||
private static final int TRACK_COLOR_OFF = 0xFF555555; // 灰色
|
||||
private static final int TRACK_COLOR_ON = 0xFFFFEB3B; // 黄色
|
||||
private static final int THUMB_COLOR_OFF = 0xFFFFFFFF; // 白色
|
||||
private static final int THUMB_COLOR_ON = 0xFF000000; // 黑色
|
||||
|
||||
private ValueAnimator animator;
|
||||
|
||||
public CustomSwitch(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public CustomSwitch(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public CustomSwitch(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
// 隐藏默认的checkbox样式
|
||||
setButtonDrawable(null);
|
||||
|
||||
trackPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
thumbPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
|
||||
trackRect = new RectF();
|
||||
thumbRect = new RectF();
|
||||
|
||||
currentTrackColor = TRACK_COLOR_OFF;
|
||||
currentThumbColor = THUMB_COLOR_OFF;
|
||||
|
||||
// 监听状态变化
|
||||
setOnCheckedChangeListener((buttonView, isChecked) -> animateSwitch(isChecked));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
// 固定尺寸:50dp × 30dp
|
||||
int width = (int) (50 * getResources().getDisplayMetrics().density);
|
||||
int height = (int) (30 * getResources().getDisplayMetrics().density);
|
||||
setMeasuredDimension(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
float radius = height / 2f;
|
||||
|
||||
// 绘制轨道
|
||||
trackRect.set(0, 0, width, height);
|
||||
trackPaint.setColor(currentTrackColor);
|
||||
canvas.drawRoundRect(trackRect, radius, radius, trackPaint);
|
||||
|
||||
// 计算小圆位置
|
||||
float thumbSize = height - 8 * getResources().getDisplayMetrics().density; // 22dp
|
||||
float padding = 4 * getResources().getDisplayMetrics().density;
|
||||
float thumbLeft = padding + thumbPosition * (width - thumbSize - 2 * padding);
|
||||
float thumbTop = padding;
|
||||
|
||||
// 绘制小圆
|
||||
thumbRect.set(thumbLeft, thumbTop, thumbLeft + thumbSize, thumbTop + thumbSize);
|
||||
thumbPaint.setColor(currentThumbColor);
|
||||
canvas.drawOval(thumbRect, thumbPaint);
|
||||
}
|
||||
|
||||
private void animateSwitch(boolean isChecked) {
|
||||
if (animator != null && animator.isRunning()) {
|
||||
animator.cancel();
|
||||
}
|
||||
|
||||
float targetPosition = isChecked ? 1f : 0f;
|
||||
int targetTrackColor = isChecked ? TRACK_COLOR_ON : TRACK_COLOR_OFF;
|
||||
int targetThumbColor = isChecked ? THUMB_COLOR_ON : THUMB_COLOR_OFF;
|
||||
|
||||
animator = ValueAnimator.ofFloat(thumbPosition, targetPosition);
|
||||
animator.setDuration(250); // 250ms动画时长
|
||||
|
||||
final ArgbEvaluator colorEvaluator = new ArgbEvaluator();
|
||||
|
||||
animator.addUpdateListener(animation -> {
|
||||
thumbPosition = (float) animation.getAnimatedValue();
|
||||
|
||||
// 颜色渐变
|
||||
currentTrackColor = (int) colorEvaluator.evaluate(
|
||||
thumbPosition, TRACK_COLOR_OFF, TRACK_COLOR_ON
|
||||
);
|
||||
currentThumbColor = (int) colorEvaluator.evaluate(
|
||||
thumbPosition, THUMB_COLOR_OFF, THUMB_COLOR_ON
|
||||
);
|
||||
|
||||
invalidate();
|
||||
});
|
||||
|
||||
animator.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChecked(boolean checked) {
|
||||
super.setChecked(checked);
|
||||
// 初始化时不播放动画
|
||||
if (!isAttachedToWindow()) {
|
||||
thumbPosition = checked ? 1f : 0f;
|
||||
currentTrackColor = checked ? TRACK_COLOR_ON : TRACK_COLOR_OFF;
|
||||
currentThumbColor = checked ? THUMB_COLOR_ON : THUMB_COLOR_OFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class AboutDialog extends BaseDialog {
|
||||
private void openGitHub() {
|
||||
try {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setData(Uri.parse("https://github.com/Tosencen/XMBOX/releases/tag/v3.0.3"));
|
||||
intent.setData(Uri.parse("https://github.com/Tosencen/XMBOX/releases/latest"));
|
||||
startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.fongmi.android.tv.api.config.WallConfig;
|
||||
import com.fongmi.android.tv.bean.Config;
|
||||
import com.fongmi.android.tv.databinding.DialogConfigBinding;
|
||||
import com.fongmi.android.tv.impl.ConfigCallback;
|
||||
import com.fongmi.android.tv.impl.Callback;
|
||||
import com.fongmi.android.tv.ui.custom.CustomTextListener;
|
||||
import com.fongmi.android.tv.utils.FileChooser;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
@@ -156,7 +157,63 @@ public class ConfigDialog {
|
||||
}
|
||||
|
||||
// 只有URL不为空时,才设置配置
|
||||
// 保存原始URL,以便在添加失败时恢复
|
||||
String originalUrl = ori;
|
||||
callback.setConfig(Config.find(url, type));
|
||||
|
||||
// 添加一个延迟检查,如果配置没有成功加载,则恢复原始URL
|
||||
new android.os.Handler().postDelayed(() -> {
|
||||
// 检查配置是否成功加载
|
||||
Config currentConfig = getConfig();
|
||||
if (currentConfig == null || !currentConfig.getUrl().equals(url)) {
|
||||
// 配置加载失败,恢复原始URL
|
||||
if (!TextUtils.isEmpty(originalUrl)) {
|
||||
// 如果有原始URL,恢复原始URL
|
||||
callback.setConfig(Config.find(originalUrl, type));
|
||||
} else {
|
||||
// 如果没有原始URL,设置为空
|
||||
switch (type) {
|
||||
case 0:
|
||||
VodConfig.get().clear().config(Config.vod()).load(new Callback() {
|
||||
@Override
|
||||
public void success() {}
|
||||
|
||||
@Override
|
||||
public void success(String result) {}
|
||||
|
||||
@Override
|
||||
public void error(String msg) {}
|
||||
});
|
||||
break;
|
||||
case 1:
|
||||
LiveConfig.get().clear().config(Config.live()).load(new Callback() {
|
||||
@Override
|
||||
public void success() {}
|
||||
|
||||
@Override
|
||||
public void success(String result) {}
|
||||
|
||||
@Override
|
||||
public void error(String msg) {}
|
||||
});
|
||||
break;
|
||||
case 2:
|
||||
WallConfig.get().clear().config(Config.wall()).load(new Callback() {
|
||||
@Override
|
||||
public void success() {}
|
||||
|
||||
@Override
|
||||
public void success(String result) {}
|
||||
|
||||
@Override
|
||||
public void error(String msg) {}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 2000); // 2秒后检查
|
||||
|
||||
dialog.dismiss();
|
||||
}
|
||||
|
||||
|
||||
@@ -104,21 +104,6 @@ public class SettingFragment extends BaseFragment implements ConfigCallback, Sit
|
||||
setSourceHintText(mBinding.wallUrl, WallConfig.getDesc(), R.string.source_hint_wall);
|
||||
mBinding.versionText.setText(getString(R.string.setting_version) + " " + BuildConfig.VERSION_NAME);
|
||||
|
||||
// 设置开关的颜色为黄色
|
||||
int accentColor = getResources().getColor(R.color.accent);
|
||||
android.content.res.ColorStateList colorStateList = new android.content.res.ColorStateList(
|
||||
new int[][]{
|
||||
new int[]{-android.R.attr.state_checked},
|
||||
new int[]{android.R.attr.state_checked}
|
||||
},
|
||||
new int[]{
|
||||
0x66FFFFFF, // 未选中时的颜色
|
||||
accentColor // 选中时的颜色
|
||||
}
|
||||
);
|
||||
mBinding.incognitoSwitch.setThumbTintList(android.content.res.ColorStateList.valueOf(android.graphics.Color.WHITE));
|
||||
mBinding.incognitoSwitch.setTrackTintList(colorStateList);
|
||||
|
||||
setOtherText();
|
||||
setCacheText();
|
||||
String[] quotes = getResources().getStringArray(R.array.motivational_quotes);
|
||||
|
||||
@@ -45,6 +45,7 @@ import com.fongmi.android.tv.ui.activity.CollectActivity;
|
||||
import com.fongmi.android.tv.ui.activity.HistoryActivity;
|
||||
import com.fongmi.android.tv.ui.activity.KeepActivity;
|
||||
import com.fongmi.android.tv.ui.activity.VideoActivity;
|
||||
import com.airbnb.lottie.LottieAnimationView;
|
||||
import com.fongmi.android.tv.ui.adapter.TypeAdapter;
|
||||
import com.fongmi.android.tv.ui.base.BaseFragment;
|
||||
import com.fongmi.android.tv.ui.dialog.ConfigDialog;
|
||||
@@ -265,6 +266,15 @@ public class VodFragment extends BaseFragment implements SiteCallback, FilterCal
|
||||
}
|
||||
// 空源状态下隐藏所有悬浮按钮
|
||||
hideFabButtons();
|
||||
// 启动Lottie动画
|
||||
try {
|
||||
LottieAnimationView lottieView = mBinding.emptySourceHint.findViewById(R.id.lottieAnimation);
|
||||
if (lottieView != null) {
|
||||
lottieView.playAnimation();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 忽略错误
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/white" android:state_focused="true" android:state_selected="true" />
|
||||
<item android:color="@color/green_400" android:state_selected="true" />
|
||||
<item android:color="@color/primary" android:state_selected="true" />
|
||||
<item android:color="@color/white" />
|
||||
</selector>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- 开启状态:黄色底 + 黑色圆在右边 -->
|
||||
<item android:state_checked="true">
|
||||
<layer-list>
|
||||
<!-- 黄色轨道 -->
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="#FFEB3B" />
|
||||
<corners android:radius="15dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<!-- 黑色小圆(右边,精确定位 22dp) -->
|
||||
<item android:top="4dp" android:bottom="4dp" android:right="4dp" android:left="24dp">
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#000000" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
</item>
|
||||
|
||||
<!-- 关闭状态:灰色底 + 白色圆在左边 -->
|
||||
<item>
|
||||
<layer-list>
|
||||
<!-- 灰色轨道 -->
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="#555555" />
|
||||
<corners android:radius="15dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<!-- 白色小圆(左边,精确定位 22dp) -->
|
||||
<item android:top="4dp" android:bottom="4dp" android:left="4dp" android:right="24dp">
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#FFFFFF" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
</item>
|
||||
</selector>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M480,595Q553,595 604.5,543.5Q656,492 656,419Q656,346 604.5,294.5Q553,243 480,243Q407,243 355.5,294.5Q304,346 304,419Q304,492 355.5,543.5Q407,595 480,595ZM480,420ZM480,760Q587,760 693,724.5Q799,689 896,619Q902,615 905,608.5Q908,602 908,595Q908,588 905,582Q902,576 896,572Q758,474 658,447.5Q558,421 480,421Q402,421 302,447.5Q202,474 64,572Q58,576 55,582Q52,588 52,595Q52,602 55,608.5Q58,615 64,619Q161,689 267,724.5Q373,760 480,760Z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M312,720Q261,720 214.5,702Q168,684 131,649Q83,604 61.5,542.5Q40,481 40,415Q40,337 78,288.5Q116,240 189,240Q203,240 215.5,242.5Q228,245 241,250L480,339L719,250Q732,245 744.5,242.5Q757,240 771,240Q844,240 882,288.5Q920,337 920,415Q920,481 898.5,542.5Q877,604 829,649Q792,684 745.5,702Q699,720 648,720Q582,720 536,690Q490,660 490,660L470,660Q470,660 424,690Q378,720 312,720ZM312,640Q349,640 381,622.5Q413,605 440,580L520,580Q547,605 579,622.5Q611,640 648,640Q684,640 717.5,627.5Q751,615 777,589Q811,555 825.5,509Q840,463 840,415Q840,374 823,346.5Q806,319 769,320Q766,320 747,324L480,424L213,324Q208,322 202.5,321Q197,320 191,320Q154,320 137,347Q120,374 120,415Q120,464 134.5,510Q149,556 184,590Q210,615 243,627.5Q276,640 312,640ZM361,580Q398,580 419,563.5Q440,547 440,518Q440,469 375.5,424.5Q311,380 239,380Q202,380 181,396.5Q160,413 160,442Q160,491 224.5,535.5Q289,580 361,580ZM355,520Q317,520 272.5,495Q228,470 220,444Q225,442 231.5,440.5Q238,439 245,439Q283,439 327.5,464.5Q372,490 380,516Q375,518 368.5,519Q362,520 355,520ZM599,581Q671,581 735.5,536Q800,491 800,442Q800,413 779.5,396Q759,379 721,379Q649,379 584.5,424Q520,469 520,518Q520,547 541,564Q562,581 599,581ZM605,520Q598,520 592,519Q586,518 581,516Q589,490 633.5,465Q678,440 716,440Q723,440 729,441Q735,442 740,444Q732,470 687.5,495Q643,520 605,520ZM480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480L480,480L480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480Z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M480,840Q363,840 281.5,758.5Q200,677 200,560Q200,483 225.5,405Q251,327 291.5,263.5Q332,200 382,160Q432,120 480,120Q529,120 578.5,160Q628,200 668.5,263.5Q709,327 734.5,405Q760,483 760,560Q760,677 678.5,758.5Q597,840 480,840ZM480,760Q563,760 621.5,701.5Q680,643 680,560Q680,503 660.5,440Q641,377 611.5,323.5Q582,270 547,235Q512,200 480,200Q449,200 413.5,235Q378,270 348.5,323.5Q319,377 299.5,440Q280,503 280,560Q280,643 338.5,701.5Q397,760 480,760ZM520,720Q537,720 548.5,708.5Q560,697 560,680Q560,663 548.5,651.5Q537,640 520,640Q470,640 435,605Q400,570 400,520Q400,503 388.5,491.5Q377,480 360,480Q343,480 331.5,491.5Q320,503 320,520Q320,603 378.5,661.5Q437,720 520,720ZM480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M123,520Q122,510 121.5,500Q121,490 121,480Q121,405 149,339.5Q177,274 226,225.5Q275,177 340,148.5Q405,120 480,120Q555,120 620.5,148.5Q686,177 734.5,225.5Q783,274 811.5,339.5Q840,405 840,480Q840,490 839.5,500Q839,510 838,520L757,520Q759,510 759.5,500Q760,490 760,480Q760,470 759.5,460Q759,450 757,440L639,440Q640,450 640,460Q640,470 640,480Q640,490 640,500Q640,510 639,520L560,520Q560,512 560,503.5Q560,495 560,487Q560,475 559.5,463Q559,451 558,440L403,440Q402,451 401.5,463Q401,475 401,487Q401,495 401,503.5Q401,512 401,520L322,520Q321,510 321,500Q321,490 321,480Q321,470 321,460Q321,450 322,440L204,440Q202,450 201.5,460Q201,470 201,480Q201,490 201.5,500Q202,510 204,520L123,520ZM228,360L331,360Q339,317 351,282.5Q363,248 377,220Q329,238 290,274.5Q251,311 228,360ZM414,360L546,360Q536,317 521,276Q506,235 480,200Q454,235 438.5,276Q423,317 414,360ZM630,360L733,360Q710,311 670.5,274.5Q631,238 583,220Q597,250 609.5,283.5Q622,317 630,360ZM440,840L440,800Q440,750 405,715Q370,680 320,680L80,680L80,600L320,600Q368,600 409.5,621Q451,642 480,680Q509,642 550.5,621Q592,600 640,600L880,600L880,680L640,680Q590,680 555,715Q520,750 520,800L520,840L440,840Z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M390,880L322,760L190,760L100,600L168,480L100,360L190,200L322,200L390,80L570,80L638,200L770,200L860,360L792,480L860,600L770,760L638,760L570,880L390,880ZM638,440L724,440L768,360L724,280L638,280L593,360L638,440ZM438,560L522,560L567,480L522,400L438,400L393,480L438,560ZM438,320L522,320L568,239L523,160L437,160L392,239L438,320ZM237,440L322,440L367,360L322,280L237,280L192,360L237,440ZM237,680L322,680L367,600L322,520L236,520L192,600L237,680ZM437,800L523,800L568,721L522,640L438,640L392,721L437,800ZM638,680L723,680L768,600L723,520L638,520L593,600L638,680Z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5s5,-2.24 5,-5S14.76,7 12,7L12,7zM17,15c0.75,-1.06 1.19,-2.36 1.19,-3.77c0,-3.61 -2.92,-6.54 -6.54,-6.54c-0.84,0 -1.65,0.16 -2.39,0.45L12,7.78L12,7.78c2.33,0 4.22,1.89 4.22,4.22c0,1.04 -0.38,1.99 -1,2.73V15zM2,4.27l2.28,2.28l0.46,0.46C3.08,8.3 1.78,10.02 1,12c1.73,4.39 6,7.5 11,7.5c1.55,0 3.03,-0.3 4.38,-0.84l0.42,0.42L19.73,22L21,20.73L3.27,3L2,4.27zM7.53,9.8l1.55,1.55c-0.05,0.21 -0.08,0.43 -0.08,0.65c0,1.66 1.34,3 3,3c0.22,0 0.44,-0.03 0.65,-0.08l1.55,1.55c-0.67,0.33 -1.41,0.53 -2.2,0.53c-2.76,0 -5,-2.24 -5,-5C7,11.21 7.2,10.47 7.53,9.8z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF0000"
|
||||
android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M480,880Q346,880 253,787Q160,694 160,560L160,360Q160,238 256,159Q352,80 480,80Q608,80 704,159Q800,238 800,360L800,880L480,880ZM480,800L560,800Q541,775 530.5,744.5Q520,714 520,680L520,638Q510,639 500,639.5Q490,640 480,640Q413,640 350.5,616.5Q288,593 240,545L240,560Q240,660 310,730Q380,800 480,800ZM600,680Q600,730 635,765Q670,800 720,800L720,545Q694,571 664,589.5Q634,608 600,620L600,680ZM440,400Q440,334 395,289Q350,244 286,241Q264,265 252,295Q240,325 240,360Q240,449 312.5,504.5Q385,560 480,560Q575,560 647.5,504.5Q720,449 720,360Q720,325 708,294.5Q696,264 674,240Q610,242 565,288Q520,334 520,400L440,400ZM340,400Q323,400 311.5,388.5Q300,377 300,360Q300,343 311.5,331.5Q323,320 340,320Q357,320 368.5,331.5Q380,343 380,360Q380,377 368.5,388.5Q357,400 340,400ZM620,400Q603,400 591.5,388.5Q580,377 580,360Q580,343 591.5,331.5Q603,320 620,320Q637,320 648.5,331.5Q660,343 660,360Q660,377 648.5,388.5Q637,400 620,400ZM370,182Q404,196 432,219Q460,242 480,271Q500,242 527.5,219Q555,196 589,182Q564,171 536.5,165.5Q509,160 480,160Q451,160 423.5,165.5Q396,171 370,182ZM800,800L800,800L720,800Q670,800 635,800Q600,800 600,800L600,800Q580,800 560,800Q540,800 520,800L520,800Q520,800 578.5,800Q637,800 720,800L800,800ZM480,800Q380,800 310,730Q240,660 240,560L240,560Q240,660 310,730Q380,800 480,800Q540,800 550,800Q560,800 560,800L560,800Q560,800 560,800Q560,800 560,800L480,800ZM600,680L600,680Q600,730 635,765Q670,800 720,800L720,800Q670,800 635,765Q600,730 600,680ZM480,271Q480,271 480,271Q480,271 480,271Q480,271 480,271Q480,271 480,271Q480,271 480,271Q480,271 480,271Q480,271 480,271Q480,271 480,271Z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M508,760L732,760Q725,786 708,802Q691,818 664,822L228,875Q195,880 168.5,859.5Q142,839 138,806L85,369Q81,336 101,310Q121,284 154,280L200,274L200,354L164,359Q164,359 164,359Q164,359 164,359L218,796Q218,796 218,796Q218,796 218,796L508,760ZM360,680Q327,680 303.5,656.5Q280,633 280,600L280,160Q280,127 303.5,103.5Q327,80 360,80L800,80Q833,80 856.5,103.5Q880,127 880,160L880,600Q880,633 856.5,656.5Q833,680 800,680L360,680ZM360,600L800,600Q800,600 800,600Q800,600 800,600L800,160Q800,160 800,160Q800,160 800,160L360,160Q360,160 360,160Q360,160 360,160L360,600Q360,600 360,600Q360,600 360,600ZM580,380Q580,380 580,380Q580,380 580,380L580,380Q580,380 580,380Q580,380 580,380L580,380Q580,380 580,380Q580,380 580,380L580,380Q580,380 580,380Q580,380 580,380ZM218,796L218,796L218,796L218,796L218,796Q218,796 218,796Q218,796 218,796ZM581,560Q649,560 696.5,513Q744,466 749,400Q681,400 632.5,447Q584,494 581,560ZM581,560Q578,494 529.5,447Q481,400 413,400Q418,466 465.5,513Q513,560 581,560ZM581,440Q598,440 609.5,428.5Q621,417 621,400L621,390L631,394Q646,400 661.5,397Q677,394 685,380Q694,365 691,348Q688,331 671,324L661,320L671,316Q688,309 690.5,291.5Q693,274 685,260Q676,245 661,242.5Q646,240 631,246L621,250L621,240Q621,223 609.5,211.5Q598,200 581,200Q564,200 552.5,211.5Q541,223 541,240L541,250L531,246Q516,240 501,242.5Q486,245 477,260Q469,274 471.5,291.5Q474,309 491,316L501,320L491,324Q474,331 471,348Q468,365 477,380Q485,394 500.5,397Q516,400 531,394L541,390L541,400Q541,417 552.5,428.5Q564,440 581,440ZM581,360Q564,360 552.5,348.5Q541,337 541,320Q541,303 552.5,291.5Q564,280 581,280Q598,280 609.5,291.5Q621,303 621,320Q621,337 609.5,348.5Q598,360 581,360Z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M342,800L618,800Q618,800 618,800Q618,800 618,800L658,640L302,640L342,800Q342,800 342,800Q342,800 342,800ZM342,880Q314,880 293,863Q272,846 265,819L220,640L740,640L695,819Q688,846 667,863Q646,880 618,880L342,880ZM200,560L760,560Q760,560 760,560Q760,560 760,560L760,480L200,480L200,560Q200,560 200,560Q200,560 200,560ZM480,320Q480,220 550,150Q620,80 720,80Q720,170 663,236Q606,302 520,316L520,400L840,400L840,560Q840,593 816.5,616.5Q793,640 760,640L200,640Q167,640 143.5,616.5Q120,593 120,560L120,400L440,400L440,316Q354,302 297,236Q240,170 240,80Q340,80 410,150Q480,220 480,320Z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M280,680L280,280L680,280L680,680L280,680ZM360,600L600,600L600,360L360,360L360,600ZM200,760L200,840Q167,840 143.5,816.5Q120,793 120,760L200,760ZM120,680L120,600L200,600L200,680L120,680ZM120,520L120,440L200,440L200,520L120,520ZM120,360L120,280L200,280L200,360L120,360ZM200,200L120,200Q120,167 143.5,143.5Q167,120 200,120L200,200ZM280,840L280,760L360,760L360,840L280,840ZM280,200L280,120L360,120L360,200L280,200ZM440,840L440,760L520,760L520,840L440,840ZM440,200L440,120L520,120L520,200L440,200ZM600,840L600,760L680,760L680,840L600,840ZM600,200L600,120L680,120L680,200L600,200ZM760,840L760,760L840,760Q840,793 816.5,816.5Q793,840 760,840ZM760,680L760,600L840,600L840,680L760,680ZM760,520L760,440L840,440L840,520L760,520ZM760,360L760,280L840,280L840,360L760,360ZM760,200L760,120Q793,120 816.5,143.5Q840,167 840,200L760,200Z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="?attr/colorControlHighlight">
|
||||
<item android:id="@android:id/background">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@android:color/transparent" />
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="#802196F3">
|
||||
android:color="#80FFEB3B">
|
||||
<item android:id="@android:id/mask">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="#f5f5f5" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="#8066BB6A">
|
||||
android:color="#80FFEB3B">
|
||||
<item android:id="@android:id/mask">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="#f5f5f5" />
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<item android:id="@android:id/background">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/black_20" />
|
||||
<corners android:radius="8dp" />
|
||||
<corners android:radius="12dp" />
|
||||
<padding
|
||||
android:bottom="14dp"
|
||||
android:left="16dp"
|
||||
|
||||
@@ -56,7 +56,30 @@
|
||||
android:paddingEnd="8dp"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp"
|
||||
tools:text="21:30 | 85%" />
|
||||
tools:text="21:30" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/charging_indicator"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:src="@drawable/ic_charging_bolt"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/battery_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingEnd="8dp"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone"
|
||||
tools:text="85%"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/cast"
|
||||
|
||||
@@ -154,5 +154,15 @@
|
||||
app:spanCount="2"
|
||||
tools:listitem="@layout/adapter_vod_rect" />
|
||||
|
||||
<!-- 搜索结果空状态Lottie动画 -->
|
||||
<include
|
||||
android:id="@+id/emptyLayout"
|
||||
layout="@layout/view_empty_search"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_marginTop="-40dp"
|
||||
android:visibility="gone" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
@@ -18,7 +18,7 @@
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:background="@drawable/shape_action_background"
|
||||
android:src="@drawable/ic_back" />
|
||||
|
||||
<TextView
|
||||
@@ -35,7 +35,7 @@
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:background="@drawable/shape_action_background"
|
||||
android:src="@drawable/ic_action_sync" />
|
||||
|
||||
<ImageView
|
||||
@@ -43,7 +43,7 @@
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:background="@drawable/shape_action_background"
|
||||
android:src="@drawable/ic_action_delete"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
@@ -65,5 +65,15 @@
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingBottom="8dp" />
|
||||
|
||||
<!-- 空状态Lottie动画 -->
|
||||
<include
|
||||
android:id="@+id/emptyLayout"
|
||||
layout="@layout/view_empty_lottie"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="-40dp"
|
||||
android:visibility="gone" />
|
||||
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
@@ -18,7 +18,7 @@
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:background="@drawable/shape_action_background"
|
||||
android:src="@drawable/ic_back" />
|
||||
|
||||
<TextView
|
||||
@@ -35,7 +35,7 @@
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:background="@drawable/shape_action_background"
|
||||
android:src="@drawable/ic_action_sync" />
|
||||
|
||||
<ImageView
|
||||
@@ -43,7 +43,7 @@
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:background="@drawable/shape_action_background"
|
||||
android:src="@drawable/ic_action_delete"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
@@ -65,5 +65,14 @@
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingBottom="8dp" />
|
||||
|
||||
<include
|
||||
android:id="@+id/emptyLayout"
|
||||
layout="@layout/view_empty_keep"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="-40dp"
|
||||
android:visibility="gone" />
|
||||
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
@@ -19,7 +19,7 @@
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:background="@drawable/shape_action_background"
|
||||
android:src="@drawable/ic_back" />
|
||||
|
||||
<TextView
|
||||
@@ -222,11 +222,10 @@
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
<com.fongmi.android.tv.ui.custom.CustomSwitch
|
||||
android:id="@+id/tunnelSwitch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/M3SwitchStyle" />
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -249,11 +248,10 @@
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
<com.fongmi.android.tv.ui.custom.CustomSwitch
|
||||
android:id="@+id/audioDecodeSwitch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/M3SwitchStyle" />
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -276,11 +274,10 @@
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
<com.fongmi.android.tv.ui.custom.CustomSwitch
|
||||
android:id="@+id/aacSwitch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/M3SwitchStyle" />
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -303,11 +300,10 @@
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
<com.fongmi.android.tv.ui.custom.CustomSwitch
|
||||
android:id="@+id/danmakuLoadSwitch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/M3SwitchStyle" />
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -4,11 +4,14 @@
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="@drawable/shape_item"
|
||||
android:gravity="center"
|
||||
android:padding="8dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text"
|
||||
android:textSize="14sp"
|
||||
android:textSize="12sp"
|
||||
tools:text="泥巴" />
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:text="(长按输入框可改源名)"
|
||||
android:text="(单击视频输入框可加源)"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="12sp"
|
||||
android:alpha="0.5" />
|
||||
@@ -129,7 +129,8 @@
|
||||
android:background="@drawable/shape_item"
|
||||
android:padding="16dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_setting_home" />
|
||||
android:src="@drawable/potted_plant_24px"
|
||||
android:tint="@color/white" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/vodHistory"
|
||||
@@ -138,7 +139,8 @@
|
||||
android:background="@drawable/shape_item"
|
||||
android:padding="16dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_setting_history" />
|
||||
android:src="@drawable/ic_m3_list_alt"
|
||||
android:tint="@color/white" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -188,7 +190,8 @@
|
||||
android:background="@drawable/shape_item"
|
||||
android:padding="16dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_setting_home" />
|
||||
android:src="@drawable/potted_plant_24px"
|
||||
android:tint="@color/white" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/liveHistory"
|
||||
@@ -197,16 +200,19 @@
|
||||
android:background="@drawable/shape_item"
|
||||
android:padding="16dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_setting_history" />
|
||||
android:src="@drawable/ic_m3_list_alt"
|
||||
android:tint="@color/white" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 壁纸功能已隐藏 -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/wall"
|
||||
@@ -292,7 +298,7 @@
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:src="@drawable/ic_setting_player"
|
||||
android:src="@drawable/hive_24px"
|
||||
android:tint="@color/white" />
|
||||
|
||||
<TextView
|
||||
@@ -318,7 +324,7 @@
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:src="@drawable/ic_setting_incognito"
|
||||
android:src="@drawable/domino_mask_24px"
|
||||
android:tint="@color/white" />
|
||||
|
||||
<TextView
|
||||
@@ -329,11 +335,10 @@
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
<com.fongmi.android.tv.ui.custom.CustomSwitch
|
||||
android:id="@+id/incognitoSwitch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/M3SwitchStyle" />
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -350,7 +355,7 @@
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:src="@drawable/ic_setting_size"
|
||||
android:src="@drawable/select_all_24px"
|
||||
android:tint="@color/white" />
|
||||
|
||||
<TextView
|
||||
@@ -405,7 +410,7 @@
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:src="@drawable/ic_setting_doh"
|
||||
android:src="@drawable/globe_book_24px"
|
||||
android:tint="@color/white" />
|
||||
|
||||
<TextView
|
||||
@@ -475,7 +480,7 @@
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:src="@drawable/ic_folder"
|
||||
android:src="@drawable/owl_24px"
|
||||
android:tint="@color/white" />
|
||||
|
||||
<TextView
|
||||
@@ -529,7 +534,7 @@
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:src="@drawable/ic_file"
|
||||
android:src="@drawable/photo_prints_24px"
|
||||
android:tint="@color/white" />
|
||||
|
||||
<TextView
|
||||
@@ -610,7 +615,7 @@
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:src="@drawable/ic_control_info"
|
||||
android:src="@drawable/egg_24px"
|
||||
android:tint="@color/white" />
|
||||
|
||||
<TextView
|
||||
|
||||
@@ -354,11 +354,10 @@
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
<com.fongmi.android.tv.ui.custom.CustomSwitch
|
||||
android:id="@+id/tunnelSwitch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/M3SwitchStyle" />
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -387,11 +386,10 @@
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
<com.fongmi.android.tv.ui.custom.CustomSwitch
|
||||
android:id="@+id/audioDecodeSwitch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/M3SwitchStyle" />
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -420,11 +418,10 @@
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
<com.fongmi.android.tv.ui.custom.CustomSwitch
|
||||
android:id="@+id/aacSwitch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/M3SwitchStyle" />
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -453,11 +450,10 @@
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
<com.fongmi.android.tv.ui.custom.CustomSwitch
|
||||
android:id="@+id/danmakuLoadSwitch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/M3SwitchStyle" />
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
android:id="@+id/logo"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:background="@drawable/shape_action_background"
|
||||
android:src="@drawable/ic_logo" />
|
||||
|
||||
<LinearLayout
|
||||
@@ -66,14 +66,14 @@
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:background="@drawable/shape_action_background"
|
||||
android:src="@drawable/ic_action_keep" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/history"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:background="@drawable/shape_action_background"
|
||||
android:src="@drawable/ic_action_history" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -112,11 +112,13 @@
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:src="@drawable/ic_logo" />
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/lottieAnimation"
|
||||
android:layout_width="180dp"
|
||||
android:layout_height="180dp"
|
||||
app:lottie_fileName="lottie_empty_1.json"
|
||||
app:lottie_loop="true"
|
||||
app:lottie_autoPlay="true" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
@@ -124,16 +126,17 @@
|
||||
android:gravity="center"
|
||||
android:text="@string/source_hint"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
android:textSize="14sp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/add_source_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:backgroundTint="@color/primary"
|
||||
android:text="@string/add_source"
|
||||
android:textColor="@color/black" />
|
||||
android:textColor="@color/black"
|
||||
android:textSize="16sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
@@ -141,7 +144,7 @@
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
android:layout_gravity="center"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:background="@drawable/shape_action_background"
|
||||
android:src="@drawable/ic_action_retry"
|
||||
android:visibility="gone" />
|
||||
|
||||
|
||||
@@ -56,8 +56,30 @@
|
||||
android:paddingEnd="8dp"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp"
|
||||
tools:text="21:30" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/charging_indicator"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:src="@drawable/ic_charging_bolt"
|
||||
android:visibility="gone"
|
||||
tools:text="21:30 | 85%" />
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/battery_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingEnd="8dp"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp"
|
||||
android:visibility="gone"
|
||||
tools:text="85%"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/cast"
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<item name="colorPrimary">@color/primary</item>
|
||||
<item name="colorPrimaryDark">@color/primaryDark</item>
|
||||
<item name="colorAccent">@color/accent</item>
|
||||
<item name="colorControlHighlight">@color/primary</item>
|
||||
<item name="android:windowBackground">@null</item>
|
||||
<item name="android:windowDisablePreview">true</item>
|
||||
<item name="android:navigationBarColor">@color/transparent</item>
|
||||
@@ -30,12 +31,8 @@
|
||||
<style name="Control.Action">
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:background">?attr/selectableItemBackgroundBorderless</item>
|
||||
<item name="android:background">@drawable/shape_action_background</item>
|
||||
<item name="android:padding">8dp</item>
|
||||
<item name="android:shadowColor">@color/grey_200</item>
|
||||
<item name="android:shadowDx">1</item>
|
||||
<item name="android:shadowDy">1</item>
|
||||
<item name="android:shadowRadius">0.5</item>
|
||||
<item name="android:textColor">@color/white</item>
|
||||
<item name="android:textSize">14sp</item>
|
||||
</style>
|
||||
@@ -78,14 +75,12 @@
|
||||
<item name="android:background">@null</item>
|
||||
</style>
|
||||
|
||||
<!-- M3 Switch Style -->
|
||||
<style name="M3SwitchStyle" parent="Widget.AppCompat.CompoundButton.Switch">
|
||||
<item name="android:thumb">@drawable/m3_switch_thumb</item>
|
||||
<item name="track">@drawable/m3_switch_track</item>
|
||||
<item name="android:switchMinWidth">52dp</item>
|
||||
<item name="android:switchPadding">8dp</item>
|
||||
<item name="android:colorControlActivated">#FFEB3B</item>
|
||||
<item name="android:colorControlHighlight">@android:color/transparent</item>
|
||||
<!-- M3 Switch Style (Material Design) - 使用CustomSwitch完全自定义 -->
|
||||
<style name="M3SwitchStyle" parent="Widget.AppCompat.CompoundButton.CheckBox">
|
||||
<item name="android:button">@null</item>
|
||||
<item name="android:background">@drawable/custom_switch_bg</item>
|
||||
<item name="android:minHeight">30dp</item>
|
||||
<item name="android:minWidth">50dp</item>
|
||||
</style>
|
||||
|
||||
<!-- 自定义数据源按钮样式 -->
|
||||
|
||||
+6
-6
@@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
id 'com.android.application' version '8.8.2' apply false
|
||||
id 'com.android.library' version '8.8.2' apply false
|
||||
id 'com.chaquo.python' version '15.0.1' apply false
|
||||
id 'com.android.application' version '8.12.0' apply false
|
||||
id 'com.android.library' version '8.12.0' apply false
|
||||
id 'com.chaquo.python' version '16.1.0' apply false
|
||||
}
|
||||
|
||||
tasks.register('clean', Delete) {
|
||||
@@ -9,7 +9,7 @@ tasks.register('clean', Delete) {
|
||||
}
|
||||
|
||||
project.ext {
|
||||
gsonVersion = '2.11.0'
|
||||
media3Version = '1.6.1'
|
||||
okhttpVersion = '5.0.0-alpha.14'
|
||||
gsonVersion = '2.13.1'
|
||||
media3Version = '1.8.0'
|
||||
okhttpVersion = '5.1.0'
|
||||
}
|
||||
|
||||
+7
-5
@@ -5,21 +5,23 @@ plugins {
|
||||
android {
|
||||
namespace 'com.github.catvod.crawler'
|
||||
|
||||
compileSdk 35
|
||||
compileSdk {
|
||||
version = release(36)
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdk 21
|
||||
minSdk 24
|
||||
targetSdk 28
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api 'androidx.annotation:annotation:1.6.0'
|
||||
api 'androidx.annotation:annotation:1.9.1'
|
||||
api 'androidx.preference:preference:1.2.1'
|
||||
api 'com.google.code.gson:gson:' + gsonVersion
|
||||
api 'com.google.net.cronet:cronet-okhttp:0.1.0'
|
||||
|
||||
@@ -14,12 +14,10 @@ import okhttp3.Response;
|
||||
|
||||
public class Github {
|
||||
|
||||
public static final String URL = "https://raw.githubusercontent.com/Tosencen/XMBOX/main";
|
||||
public static final String API_URL = "https://api.github.com/repos/Tosencen/XMBOX/releases/latest";
|
||||
public static final String URL = "https://raw.githubusercontent.com/Tosencen/XMBOX-Release/main";
|
||||
|
||||
// 国内镜像地址 - 使用Gitee作为示例,实际应替换为您的镜像地址
|
||||
public static final String CN_URL = "https://gitee.com/tosencen/XMBOX/raw/main";
|
||||
public static final String CN_API_URL = "https://gitee.com/api/v5/repos/tosencen/XMBOX/releases/latest";
|
||||
// 国内镜像地址 - 使用Gitee作为镜像
|
||||
public static final String CN_URL = "https://gitee.com/ochenoktochen/XMBOX-Release/raw/main";
|
||||
|
||||
// 存储测速结果
|
||||
private static Boolean useCnMirror = null;
|
||||
@@ -34,9 +32,6 @@ public class Github {
|
||||
return CN_URL + "/" + path + "/" + name;
|
||||
}
|
||||
|
||||
public static String getReleaseApi() {
|
||||
return useCnMirror() ? CN_API_URL : API_URL;
|
||||
}
|
||||
|
||||
public static String getJson(boolean dev, String name) {
|
||||
if (useCnMirror()) {
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.github.catvod.utils;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class Logger {
|
||||
private static final String TAG = "XMBOX";
|
||||
|
||||
public static void d(String msg) {
|
||||
Log.d(TAG, msg);
|
||||
}
|
||||
|
||||
public static void e(String msg) {
|
||||
Log.e(TAG, msg);
|
||||
}
|
||||
|
||||
public static void e(String msg, Throwable tr) {
|
||||
Log.e(TAG, msg, tr);
|
||||
}
|
||||
|
||||
public static void i(String msg) {
|
||||
Log.i(TAG, msg);
|
||||
}
|
||||
|
||||
public static void v(String msg) {
|
||||
Log.v(TAG, msg);
|
||||
}
|
||||
|
||||
public static void w(String msg) {
|
||||
Log.w(TAG, msg);
|
||||
}
|
||||
|
||||
public static void w(String msg, Throwable tr) {
|
||||
Log.w(TAG, msg, tr);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.github.catvod.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
plugins {
|
||||
id 'com.android.library'
|
||||
id 'com.chaquo.python'
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'com.fongmi.chaquo'
|
||||
|
||||
compileSdk {
|
||||
version = release(36)
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdk 24
|
||||
targetSdk 28
|
||||
python {
|
||||
version "3.8"
|
||||
pip {
|
||||
install("-r", "requirements.txt")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flavorDimensions = ["abi"]
|
||||
|
||||
productFlavors {
|
||||
arm64_v8a {
|
||||
dimension "abi"
|
||||
ndk { abiFilters "arm64-v8a" }
|
||||
}
|
||||
armeabi_v7a {
|
||||
dimension "abi"
|
||||
ndk { abiFilters "armeabi-v7a" }
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
python.srcDirs = ["src/main/python"]
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':catvod')
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
lxml
|
||||
ujson
|
||||
pyquery
|
||||
requests
|
||||
jsonpath
|
||||
cachetools
|
||||
pycryptodome
|
||||
beautifulsoup4
|
||||
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
</manifest>
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
# GitHub CLI 创建 Release 脚本
|
||||
# 使用前请先运行: gh auth login
|
||||
|
||||
echo "创建 XMBOX v3.0.8 Release..."
|
||||
|
||||
gh release create v3.0.8 \
|
||||
--title "XMBOX v3.0.8 - UI交互体验全面优化" \
|
||||
--notes-file RELEASE_NOTES_v3.0.8.md \
|
||||
--draft \
|
||||
~/Desktop/mobile-arm64_v8a-v3.0.8.apk \
|
||||
~/Desktop/mobile-armeabi_v7a-v3.0.8.apk \
|
||||
~/Desktop/leanback-arm64_v8a-v3.0.8.apk \
|
||||
~/Desktop/leanback-armeabi_v7a-v3.0.8.apk
|
||||
|
||||
echo "Release 创建完成(草稿状态)"
|
||||
echo "请在 GitHub 上检查并发布"
|
||||
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- 主题颜色 -->
|
||||
<color name="primary">#FF0057B8</color>
|
||||
<color name="primaryDark">#FF003C7E</color>
|
||||
<color name="accent">#FF0057B8</color>
|
||||
<color name="primary">#FFEB3B</color>
|
||||
<color name="primaryDark">#FDD835</color>
|
||||
<color name="accent">#FFEB3B</color>
|
||||
|
||||
<!-- 基本颜色 -->
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#Wed Mar 29 12:54:35 CST 2023
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
+8
-10
@@ -5,26 +5,24 @@ plugins {
|
||||
android {
|
||||
namespace 'com.fongmi.android.tv.quickjs'
|
||||
|
||||
compileSdk 35
|
||||
compileSdk {
|
||||
version = release(36)
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdk 21
|
||||
minSdk 24
|
||||
targetSdk 28
|
||||
}
|
||||
|
||||
lint {
|
||||
disable 'UnsafeOptInUsageError'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':catvod')
|
||||
implementation 'wang.harlon.quickjs:wrapper-java:3.2.0'
|
||||
implementation 'wang.harlon.quickjs:wrapper-android:3.2.0'
|
||||
implementation 'wang.harlon.quickjs:wrapper-java:3.2.3'
|
||||
implementation 'wang.harlon.quickjs:wrapper-android:3.2.3'
|
||||
implementation 'net.sourceforge.streamsupport:android-retrofuture:1.7.4'
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user