2 Commits

Author SHA1 Message Date
您的名字 514368bc07 feat: 升级到v3.1.0
- 实现定时按钮倒计时显示功能
- 适配pixel主题化图标展示
- 优化TimerDialog按钮宽度设计
2025-10-28 19:40:13 +08:00
您的名字 794e1a32fe feat: 优化播放进度条交互体验
- 修复拖拽时圆球消失问题
- 添加动态轨道高度变化效果(按住时4dp,松开时2dp)
- 优化圆球大小设置(固定14dp)
- 添加ProGuard规则保护DefaultTimeBar反射字段
- 改进触摸事件处理逻辑
- 增强拖拽体验的流畅性

修复内容:
- CustomSeekView: 重构触摸事件处理和动态高度调整
- 布局文件: 统一设置圆球大小为14dp
- ProGuard: 保护Media3 DefaultTimeBar字段不被混淆
2025-10-24 16:53:19 +08:00
25 changed files with 202 additions and 247 deletions
-21
View File
@@ -35,24 +35,3 @@ google-services.json
# APK files # APK files
apk/release/*.apk apk/release/*.apk
# Local configuration files
gradle.properties.local
local.properties
local-repo/
# Temporary files
cleanup_project.sh
*.tmp
*.temp
# System files
.DS_Store
Thumbs.db
# Duplicate release directories
XMBOX-Release/
# Tools and utilities (not part of the project)
other/tools/bfg.jar
other/tools/cleaner.bat
+17 -25
View File
@@ -2,7 +2,7 @@
</h1> </h1>
<div align="center"> <div align="center">
![Version](https://img.shields.io/badge/version-3.1.0-blue.svg) ![Version](https://img.shields.io/badge/version-3.0.9-blue.svg)
![Android](https://img.shields.io/badge/platform-Android-green.svg) ![Android](https://img.shields.io/badge/platform-Android-green.svg)
![License](https://img.shields.io/badge/license-GPL--3.0-orange.svg) ![License](https://img.shields.io/badge/license-GPL--3.0-orange.svg)
![Build](https://img.shields.io/badge/build-passing-brightgreen.svg) ![Build](https://img.shields.io/badge/build-passing-brightgreen.svg)
@@ -10,7 +10,6 @@
一个操作方便、界面简洁的Android视频播放器盒子,需自行添源,支持TV和手机双平台。 一个操作方便、界面简洁的Android视频播放器盒子,需自行添源,支持TV和手机双平台。
[下载APK](https://github.com/Tosencen/XMBOX-Release/tree/main/apk/release) • [功能特性](#-功能特性) • [构建指南](#-构建指南) • [API文档](#-api文档) [下载APK](https://github.com/Tosencen/XMBOX-Release/tree/main/apk/release) • [功能特性](#-功能特性) • [构建指南](#-构建指南) • [API文档](#-api文档)
<img width="1920" height="864" alt="Group 15" src="https://github.com/user-attachments/assets/e69741bd-a21d-417e-ad85-e747032f6daf" />
</div> </div>
@@ -37,17 +36,17 @@
## 📥 下载安装 ## 📥 下载安装
### 最新版本: v3.1.0 ### 最新版本: v3.0.9
| 平台 | ARM64-V8A | ARM V7A | | 平台 | ARM64-V8A | ARM V7A |
|------|-----------|---------| |------|-----------|---------|
| **📱 手机版** | [下载 (34.4MB)](https://github.com/Tosencen/XMBOX-Release/raw/main/apk/release/v3.1.0/mobile-arm64_v8a-v3.1.0.apk) | [下载 (30.4MB)](https://github.com/Tosencen/XMBOX-Release/raw/main/apk/release/v3.1.0/mobile-armeabi_v7a-v3.1.0.apk) | | **📱 手机版** | [下载 (35.8MB)](https://github.com/Tosencen/XMBOX-Release/raw/main/apk/release/v3.0.9/mobile-arm64_v8a-v3.0.9.apk) | [下载 (31.6MB)](https://github.com/Tosencen/XMBOX-Release/raw/main/apk/release/v3.0.9/mobile-armeabi_v7a-v3.0.9.apk) |
| **📺 TV版** | [下载 (34.5MB)](https://github.com/Tosencen/XMBOX-Release/raw/main/apk/release/v3.1.0/leanback-arm64_v8a-v3.1.0.apk) | [下载 (30.5MB)](https://github.com/Tosencen/XMBOX-Release/raw/main/apk/release/v3.1.0/leanback-armeabi_v7a-v3.1.0.apk) | | **📺 TV版** | [下载 (35.9MB)](https://github.com/Tosencen/XMBOX-Release/raw/main/apk/release/v3.0.9/leanback-arm64_v8a-v3.0.9.apk) | [下载 (31.7MB)](https://github.com/Tosencen/XMBOX-Release/raw/main/apk/release/v3.0.9/leanback-armeabi_v7a-v3.0.9.apk) |
### 📁 版本历史 ### 📁 版本历史
- **v3.1.0**: [查看v3.1.0版本](https://github.com/Tosencen/XMBOX-Release/tree/main/apk/release/v3.1.0) - 定时器优化和画中画修复版本
- **v3.0.9**: [查看v3.0.9版本](https://github.com/Tosencen/XMBOX-Release/tree/main/apk/release/v3.0.9) - 新增直播开关控制和UI交互优化 - **v3.0.9**: [查看v3.0.9版本](https://github.com/Tosencen/XMBOX-Release/tree/main/apk/release/v3.0.9) - 新增直播开关控制和UI交互优化
- **v3.0.8**: [查看v3.0.8版本](https://github.com/Tosencen/XMBOX-Release/tree/main/apk/release/v3.0.8) - UI交互体验全面优化 - **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` 包含最新版本信息 - **最新版本**: 根目录的 `mobile.json``leanback.json` 包含最新版本信息
@@ -134,35 +133,23 @@ XMBOX/
## 📝 更新日志 ## 📝 更新日志
### v3.1.0 (2025-10-28)
#### ✨ 新功能
* **定时倒计时显示** - 实现定时按钮倒计时显示功能,用户可以实时看到剩余时间
* **主题化图标适配** - 适配pixel主题化图标展示,提升视觉体验
#### 🎨 UI优化
* **TimerDialog优化** - 优化TimerDialog按钮宽度设计,界面更加协调
* **进度条交互改进** - 优化播放进度条交互体验,操作更流畅
* **视觉一致性提升** - 改进界面视觉一致性,整体更加统一
#### 🐛 修复
* **更新链接修复** - 修复更新跳转链接,现在可以正确跳转到具体版本页面
#### 🔧 技术改进
* **定时功能优化** - 提升定时功能用户体验
* **内存优化** - 进一步优化内存使用
* **稳定性增强** - 提升播放稳定性
### v3.0.9 (2025-10-24) ### v3.0.9 (2025-10-24)
#### ✨ 新功能 #### ✨ 新功能
* **直播开关控制** - 新增直播tab显示/隐藏开关,用户可根据需要控制直播功能 * **直播开关控制** - 新增直播tab显示/隐藏开关,用户可根据需要控制直播功能
* **实时倍速显示** - 播放控制对话框新增实时倍速数值显示,提升用户体验 * **实时倍速显示** - 播放控制对话框新增实时倍速数值显示,提升用户体验
* **源管理优化** - 优化源管理模块间距动态调整,界面更加协调
#### 🎨 UI优化 #### 🎨 UI优化
* **滑杆交互优化** - 滑杆圆球大小优化至20dp直径,提升操作体验
* **刻度显示改进** - 改进滑杆刻度显示,非激活轨道显示刻度,激活轨道保持干净 * **刻度显示改进** - 改进滑杆刻度显示,非激活轨道显示刻度,激活轨道保持干净
* **播放进度条增强** - 增强播放进度条动态大小调整功能,修复圆球跳回问题 * **播放进度条增强** - 增强播放进度条动态大小调整功能,修复圆球跳回问题
* **直播开关逻辑** - 完善直播开关逻辑和UI交互,确保功能一致性
#### 🔧 技术改进
* **优化内存使用** - 进一步优化内存管理机制
* **提升播放稳定性** - 增强播放器稳定性
* **增强UI交互体验** - 改进用户界面交互响应
### v3.0.8 (2025-10-14) ### v3.0.8 (2025-10-14)
@@ -175,6 +162,11 @@ XMBOX/
* **修复文字重叠** - 解决跨类和换源按钮的文字重叠问题 * **修复文字重叠** - 解决跨类和换源按钮的文字重叠问题
* **提升视觉一致性** - 整体UI视觉一致性和用户体验优化 * **提升视觉一致性** - 整体UI视觉一致性和用户体验优化
#### 🔧 技术改进
* **优化内存使用** - 改进内存管理机制
* **提升播放稳定性** - 增强播放器稳定性
* **文件结构重组** - 按版本号重新组织发布文件结构
### v3.0.5 (2025-08-20) ### v3.0.5 (2025-08-20)
#### 🎨 界面优化 #### 🎨 界面优化
- 优化导航栏历史记录图标,采用 Material Design 3 规范的列表图标 - 优化导航栏历史记录图标,采用 Material Design 3 规范的列表图标
+62
View File
@@ -0,0 +1,62 @@
# XMBOX Release Files
## 📁 文件结构
```
apk/release/
├── mobile.json # 最新版本信息 (手机版)
├── leanback.json # 最新版本信息 (TV版)
├── v3.0.7/ # v3.0.7版本文件
│ ├── mobile.json # v3.0.7版本信息
│ ├── leanback.json # v3.0.7版本信息
│ ├── mobile-arm64_v8a.apk
│ ├── mobile-armeabi_v7a.apk
│ ├── leanback-arm64_v8a.apk
│ └── leanback-armeabi_v7a.apk
└── v3.0.8/ # v3.0.8版本文件
├── mobile.json # v3.0.8版本信息
├── leanback.json # v3.0.8版本信息
├── mobile-arm64_v8a-v3.0.8.apk
├── mobile-armeabi_v7a-v3.0.8.apk
├── leanback-arm64_v8a-v3.0.8.apk
└── leanback-armeabi_v7a-v3.0.8.apk
```
## 📱 版本说明
### v3.0.8 (最新版本)
- **发布时间**: 2025-10-14
- **版本代码**: 308
- **主要更新**: UI交互体验全面优化
### v3.0.7
- **发布时间**: 2025-09-26
- **版本代码**: 307
- **主要更新**: 全面优化稳定性和用户体验
## 🔗 下载链接
### 最新版本 (v3.0.8)
- **手机版 ARM64**: [mobile-arm64_v8a-v3.0.8.apk](v3.0.8/mobile-arm64_v8a-v3.0.8.apk)
- **手机版 ARMv7**: [mobile-armeabi_v7a-v3.0.8.apk](v3.0.8/mobile-armeabi_v7a-v3.0.8.apk)
- **TV版 ARM64**: [leanback-arm64_v8a-v3.0.8.apk](v3.0.8/leanback-arm64_v8a-v3.0.8.apk)
- **TV版 ARMv7**: [leanback-armeabi_v7a-v3.0.8.apk](v3.0.8/leanback-armeabi_v7a-v3.0.8.apk)
### 历史版本
- **v3.0.7**: [查看v3.0.7版本文件](v3.0.7/)
## 📋 版本信息
每个版本目录都包含对应的JSON配置文件,包含:
- `name`: 版本号
- `desc`: 版本描述和更新内容
- `code`: 版本代码
- `downloads`: 下载链接映射 (仅根目录文件)
## 🔐 签名信息
所有APK文件均使用多重签名保护:
- ✅ v1 (JAR签名) - 最佳兼容性
- ✅ v2 (APK签名方案v2) - 全文件签名
- ✅ v3 (APK签名方案v3) - 支持密钥轮换
- ✅ v4 (APK签名方案v4) - 增量签名
+9
View File
@@ -0,0 +1,9 @@
{
"name": "3.0.8",
"desc": "XMBOX TV版 v3.0.8 (Android TV/机顶盒专用)\n\n✨ UI优化:\n• 修复按钮点击效果过于明显的问题\n• 统一使用自定义背景替代系统selectableItemBackgroundBorderless\n• 移除Control.Action样式中的文字阴影效果\n• 优化直播页面选择按钮颜色为主题黄色\n• 调整许可协议页面按钮区域上间距为8dp\n• 修复跨类和换源按钮的文字重叠问题\n• 提升整体UI视觉一致性和用户体验\n\n🔧 改进优化:\n• 优化大屏界面体验\n• 提升播放稳定性\n\n📺 专为电视优化:遥控器导航 | 10-foot UI | ARM64/ARMv7",
"code": 308,
"downloads": {
"arm64_v8a": "v3.0.8/leanback-arm64_v8a-v3.0.8.apk",
"armeabi_v7a": "v3.0.8/leanback-armeabi_v7a-v3.0.8.apk"
}
}
+9
View File
@@ -0,0 +1,9 @@
{
"name": "3.0.8",
"desc": "XMBOX 手机版 v3.0.8\n\n✨ UI优化:\n• 修复按钮点击效果过于明显的问题\n• 统一使用自定义背景替代系统selectableItemBackgroundBorderless\n• 移除Control.Action样式中的文字阴影效果\n• 优化直播页面选择按钮颜色为主题黄色\n• 调整许可协议页面按钮区域上间距为8dp\n• 修复跨类和换源按钮的文字重叠问题\n• 提升整体UI视觉一致性和用户体验\n\n🔧 改进优化:\n• 优化内存使用\n• 提升播放稳定性\n\n📱 支持架构:ARM64-v8a | ARMv7a",
"code": 308,
"downloads": {
"arm64_v8a": "v3.0.8/mobile-arm64_v8a-v3.0.8.apk",
"armeabi_v7a": "v3.0.8/mobile-armeabi_v7a-v3.0.8.apk"
}
}
@@ -0,0 +1,5 @@
{
"name": "3.0.7",
"desc": "XMBOX TV版 v3.0.7 (Android TV/机顶盒专用)\n\n✨ UI优化:\n• 全新自定义开关按钮(黄色/黑色Material Design风格)\n• 优化电量百分比显示(16sp字号,2dp间距)\n• 精简设置页面,隐藏壁纸功能\n\n🔒 安全增强:\n• 启用v1/v2/v3/v4多重签名保护\n• 提升应用安全性和兼容性\n\n🔧 改进优化:\n• 修复设置页面崩溃问题\n• 优化大屏界面体验\n• 提升播放稳定性\n\n📺 专为电视优化:遥控器导航 | 10-foot UI | ARM64/ARMv7",
"code": 307
}
@@ -0,0 +1,5 @@
{
"name": "3.0.7",
"desc": "XMBOX 手机版 v3.0.7\n\n✨ UI优化:\n• 全新自定义开关按钮(黄色/黑色Material Design风格)\n• 优化电量百分比显示(16sp字号,2dp间距)\n• 精简设置页面,隐藏壁纸功能\n\n🔒 安全增强:\n• 启用v1/v2/v3/v4多重签名保护\n• 提升应用安全性和兼容性\n\n🔧 改进优化:\n• 修复设置页面崩溃问题\n• 优化内存使用\n• 提升播放稳定性\n\n📱 支持架构:ARM64-v8a | ARMv7a",
"code": 307
}
+5 -5
View File
@@ -1,9 +1,9 @@
{ {
"name": "3.1.0", "name": "3.0.9",
"desc": "XMBOX TV版 v3.1.0\n\n✨ 新功能:\n• 实现定时按钮倒计时显示功能\n• 适配pixel主题化图标展示\n\n🎨 UI优化:\n• 优化TimerDialog按钮宽度设计\n• 优化播放进度条交互体验\n• 改进界面视觉一致性\n\n🐛 修复:\n• 修复更新跳转链接,跳转到具体版本页面\n\n🔧 改进优化:\n• 提升定时功能用户体验\n• 优化内存使用\n• 提升播放稳定性\n\n📺 支持架构:ARM64-v8a | ARMv7a", "desc": "XMBOX TV版 v3.0.9 (Android TV/机顶盒专用)\n\n✨ 新功能:\n• 新增直播开关控制功能,可隐藏/显示直播tab\n• 新增实时倍速显示功能,播放控制对话框显示当前倍速\n• 优化源管理模块间距动态调整\n\n🎨 UI优化:\n• 滑杆圆球大小优化至20dp直径,提升操作体验\n• 改进滑杆刻度显示,非激活轨道显示刻度\n• 增强播放进度条动态大小调整功能\n• 修复播放进度条圆球跳回问题\n• 完善直播开关逻辑和UI交互\n\n🔧 改进优化:\n• 优化大屏界面体验\n• 提升播放稳定性\n• 增强UI交互体验\n\n📺 专为电视优化:遥控器导航 | 10-foot UI | ARM64/ARMv7",
"code": 310, "code": 309,
"downloads": { "downloads": {
"arm64_v8a": "v3.1.0/leanback-arm64_v8a-v3.1.0.apk", "arm64_v8a": "v3.0.9/leanback-arm64_v8a-v3.0.9.apk",
"armeabi_v7a": "v3.1.0/leanback-armeabi_v7a-v3.1.0.apk" "armeabi_v7a": "v3.0.9/leanback-armeabi_v7a-v3.0.9.apk"
} }
} }
+5 -5
View File
@@ -1,9 +1,9 @@
{ {
"name": "3.1.0", "name": "3.0.9",
"desc": "XMBOX 手机版 v3.1.0\n\n✨ 新功能:\n• 实现定时按钮倒计时显示功能\n• 适配pixel主题化图标展示\n\n🎨 UI优化:\n• 优化TimerDialog按钮宽度设计\n• 优化播放进度条交互体验\n• 改进界面视觉一致性\n\n🐛 修复:\n• 修复更新跳转链接,跳转到具体版本页面\n\n🔧 改进优化:\n• 提升定时功能用户体验\n• 优化内存使用\n• 提升播放稳定性\n\n📱 支持架构:ARM64-v8a | ARMv7a", "desc": "XMBOX 手机版 v3.0.9\n\n✨ 新功能:\n• 新增直播开关控制功能,可隐藏/显示直播tab\n• 新增实时倍速显示功能,播放控制对话框显示当前倍速\n• 优化源管理模块间距动态调整\n\n🎨 UI优化:\n• 滑杆圆球大小优化至20dp直径,提升操作体验\n• 改进滑杆刻度显示,非激活轨道显示刻度\n• 增强播放进度条动态大小调整功能\n• 修复播放进度条圆球跳回问题\n• 完善直播开关逻辑和UI交互\n\n🔧 改进优化:\n• 优化内存使用\n• 提升播放稳定性\n• 增强UI交互体验\n\n📱 支持架构:ARM64-v8a | ARMv7a",
"code": 310, "code": 309,
"downloads": { "downloads": {
"arm64_v8a": "v3.1.0/mobile-arm64_v8a-v3.1.0.apk", "arm64_v8a": "v3.0.9/mobile-arm64_v8a-v3.0.9.apk",
"armeabi_v7a": "v3.1.0/mobile-armeabi_v7a-v3.1.0.apk" "armeabi_v7a": "v3.0.9/mobile-armeabi_v7a-v3.0.9.apk"
} }
} }
-10
View File
@@ -1,10 +0,0 @@
{
"name": "3.1.0",
"desc": "XMBOX TV版 v3.1.0\n\n✨ 新功能:\n• 实现定时按钮倒计时显示功能\n• 适配pixel主题化图标展示\n\n🎨 UI优化:\n• 优化TimerDialog按钮宽度设计\n• 优化播放进度条交互体验\n• 改进界面视觉一致性\n\n🐛 修复:\n• 修复更新跳转链接,跳转到具体版本页面\n\n🔧 改进优化:\n• 提升定时功能用户体验\n• 优化内存使用\n• 提升播放稳定性\n\n📺 支持架构:ARM64-v8a | ARMv7a",
"code": 310,
"downloads": {
"arm64_v8a": "v3.1.0/leanback-arm64_v8a-v3.1.0.apk",
"armeabi_v7a": "v3.1.0/leanback-armeabi_v7a-v3.1.0.apk"
}
}
-10
View File
@@ -1,10 +0,0 @@
{
"name": "3.1.0",
"desc": "XMBOX 手机版 v3.1.0\n\n✨ 新功能:\n• 实现定时按钮倒计时显示功能\n• 适配pixel主题化图标展示\n\n🎨 UI优化:\n• 优化TimerDialog按钮宽度设计\n• 优化播放进度条交互体验\n• 改进界面视觉一致性\n\n🐛 修复:\n• 修复更新跳转链接,跳转到具体版本页面\n\n🔧 改进优化:\n• 提升定时功能用户体验\n• 优化内存使用\n• 提升播放稳定性\n\n📱 支持架构:ARM64-v8a | ARMv7a",
"code": 310,
"downloads": {
"arm64_v8a": "v3.1.0/mobile-arm64_v8a-v3.1.0.apk",
"armeabi_v7a": "v3.1.0/mobile-armeabi_v7a-v3.1.0.apk"
}
}
@@ -20,7 +20,6 @@ import com.github.catvod.utils.Logger;
import com.github.catvod.utils.Path; import com.github.catvod.utils.Path;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
import java.io.File; import java.io.File;
@@ -34,7 +33,6 @@ public class Updater implements Download.Callback {
private boolean dev; private boolean dev;
private boolean forceCheck; // 是否为手动检查 private boolean forceCheck; // 是否为手动检查
private String latestVersion; // 存储检测到的最新版本 private String latestVersion; // 存储检测到的最新版本
private String releaseApkUrl; // 从 GitHub Release 获取的 APK 下载链接
private File getFile() { private File getFile() {
return Path.root("Download", "XMBOX-update.apk"); return Path.root("Download", "XMBOX-update.apk");
@@ -45,12 +43,6 @@ public class Updater implements Download.Callback {
} }
private String getApk() { private String getApk() {
// 优先使用从 GitHub Release 获取的 APK URL
if (releaseApkUrl != null && !releaseApkUrl.isEmpty()) {
Logger.d("APK download URL from Release: " + releaseApkUrl);
return releaseApkUrl;
}
// 使用JSON中指定的具体下载路径 // 使用JSON中指定的具体下载路径
try { try {
String response = OkHttp.string(getJson()); String response = OkHttp.string(getJson());
@@ -64,18 +56,14 @@ public class Updater implements Download.Callback {
String baseUrl = Github.useCnMirror() ? String baseUrl = Github.useCnMirror() ?
"https://gitee.com/ochenoktochen/XMBOX-Release/raw/main" : "https://gitee.com/ochenoktochen/XMBOX-Release/raw/main" :
"https://raw.githubusercontent.com/Tosencen/XMBOX-Release/main"; "https://raw.githubusercontent.com/Tosencen/XMBOX-Release/main";
String fullUrl = baseUrl + "/apk/" + (dev ? "dev" : "release") + "/" + downloadPath; return baseUrl + "/apk/" + (dev ? "dev" : "release") + "/" + downloadPath;
Logger.d("APK download URL: " + fullUrl);
return fullUrl;
} }
} }
} catch (Exception e) { } catch (Exception e) {
Logger.e("Failed to get download path from JSON: " + e.getMessage()); Logger.e("Failed to get download path from JSON: " + e.getMessage());
} }
// 回退到原来的方式 // 回退到原来的方式
String fallbackUrl = Github.getApk(dev, BuildConfig.FLAVOR_mode + "-" + BuildConfig.FLAVOR_abi); return Github.getApk(dev, BuildConfig.FLAVOR_mode + "-" + BuildConfig.FLAVOR_abi);
Logger.d("APK fallback URL: " + fallbackUrl);
return fallbackUrl;
} }
public static Updater create() { public static Updater create() {
@@ -118,60 +106,13 @@ public class Updater implements Download.Callback {
} }
private void doInBackground(Activity activity) { private void doInBackground(Activity activity) {
Logger.d("Updater: Starting update check...");
try {
// 优先使用 JSON 方式检测更新(兼容性更好)
String response = OkHttp.string(getJson());
JSONObject object = new JSONObject(response);
String name = object.optString("name");
String desc = object.optString("desc");
int code = object.optInt("code");
Logger.d("Updater: JSON Remote version: " + name + ", code: " + code);
Logger.d("Updater: Local version: " + BuildConfig.VERSION_NAME + ", code: " + BuildConfig.VERSION_CODE);
// 使用 JSON 中的版本信息
if (need(code, name)) {
Logger.d("Updater: Update needed (from JSON), showing dialog");
this.latestVersion = name; // 保存最新版本号
// 从 JSON 获取下载链接
JSONObject downloads = object.optJSONObject("downloads");
if (downloads != null) {
String abi = BuildConfig.FLAVOR_abi;
String downloadPath = downloads.optString(abi);
if (!downloadPath.isEmpty()) {
String baseUrl = Github.useCnMirror() ?
"https://gitee.com/ochenoktochen/XMBOX-Release/raw/main" :
"https://raw.githubusercontent.com/Tosencen/XMBOX-Release/main";
this.releaseApkUrl = baseUrl + "/apk/" + (dev ? "dev" : "release") + "/" + downloadPath;
Logger.d("Updater: APK URL from JSON: " + this.releaseApkUrl);
}
}
App.post(() -> show(activity, name, desc));
} else {
Logger.d("Updater: No update needed (from JSON)");
if (forceCheck) {
App.post(() -> Notify.show("已是最新版本 " + name));
}
}
} catch (Exception e) {
Logger.e("Updater: JSON check failed, trying GitHub API: " + e.getMessage());
// JSON 检测失败,尝试使用 GitHub Releases API
checkViaGitHubAPI(activity);
}
}
private void checkViaGitHubAPI(Activity activity) {
try { try {
// 直接使用GitHub Releases API检测最新版本
String releasesUrl = "https://api.github.com/repos/Tosencen/XMBOX/releases/latest"; String releasesUrl = "https://api.github.com/repos/Tosencen/XMBOX/releases/latest";
Logger.d("Updater: Trying GitHub Releases API: " + releasesUrl);
String response = OkHttp.string(releasesUrl); String response = OkHttp.string(releasesUrl);
// 检查响应是否包含错误信息
if (response.contains("rate limit exceeded")) { if (response.contains("rate limit exceeded")) {
Logger.e("Updater: Rate limit exceeded");
if (forceCheck) { if (forceCheck) {
App.post(() -> Notify.show("检查更新失败:API请求过于频繁,请稍后重试")); App.post(() -> Notify.show("检查更新失败:API请求过于频繁,请稍后重试"));
} }
@@ -179,9 +120,8 @@ public class Updater implements Download.Callback {
} }
if (response.contains("Not Found") || response.contains("404")) { if (response.contains("Not Found") || response.contains("404")) {
Logger.e("Updater: Release not found");
if (forceCheck) { if (forceCheck) {
App.post(() -> Notify.show("检查更新失败:无法连接到更新服务器")); App.post(() -> Notify.show("检查更新失败:更新服务暂时不可用"));
} }
return; return;
} }
@@ -189,33 +129,32 @@ public class Updater implements Download.Callback {
JSONObject release = new JSONObject(response); JSONObject release = new JSONObject(response);
String tagName = release.optString("tag_name"); String tagName = release.optString("tag_name");
String body = release.optString("body"); String body = release.optString("body");
// 提取版本号(去掉v前缀)
String version = tagName.startsWith("v") ? tagName.substring(1) : tagName; String version = tagName.startsWith("v") ? tagName.substring(1) : tagName;
Logger.d("Updater: GitHub API Remote version: " + version);
// 从 assets 中查找 APK
JSONArray assets = release.optJSONArray("assets");
if (assets != null) {
String targetApkName = BuildConfig.FLAVOR_mode + "-" + BuildConfig.FLAVOR_abi + "-v" + version + ".apk";
for (int i = 0; i < assets.length(); i++) {
JSONObject asset = assets.getJSONObject(i);
if (targetApkName.equals(asset.optString("name"))) {
this.releaseApkUrl = asset.optString("browser_download_url");
break;
}
}
}
if (needUpdate(version)) { if (needUpdate(version)) {
this.latestVersion = version; this.latestVersion = version; // 保存最新版本号
App.post(() -> show(activity, version, body)); App.post(() -> show(activity, version, body));
} else if (forceCheck) { } else {
if (forceCheck) {
App.post(() -> Notify.show("已是最新版本 " + version)); App.post(() -> Notify.show("已是最新版本 " + version));
} }
}
} catch (Exception e) { } catch (Exception e) {
Logger.e("Updater: GitHub API check failed: " + e.getMessage()); e.printStackTrace();
if (forceCheck) { if (forceCheck) {
App.post(() -> Notify.show("检查更新失败:无法连接到更新服务器")); 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);
});
} }
} }
} }
@@ -131,8 +131,6 @@ public class App extends Application {
OkHttp.get().setDoh(Doh.objectFrom(Setting.getDoh())); OkHttp.get().setDoh(Doh.objectFrom(Setting.getDoh()));
EventBus.builder().addIndex(new EventIndex()).installDefaultEventBus(); EventBus.builder().addIndex(new EventIndex()).installDefaultEventBus();
CaocConfig.Builder.create().backgroundMode(CaocConfig.BACKGROUND_MODE_SILENT).errorActivity(CrashActivity.class).apply(); CaocConfig.Builder.create().backgroundMode(CaocConfig.BACKGROUND_MODE_SILENT).errorActivity(CrashActivity.class).apply();
// Ensure default notification channel exists for foreground playback service (TV flavor too)
Notify.createChannel();
// 初始化自动缓存清理 // 初始化自动缓存清理
initCacheCleaner(); initCacheCleaner();
@@ -4,7 +4,6 @@ import android.Manifest;
import android.app.Notification; import android.app.Notification;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.text.TextUtils; import android.text.TextUtils;
@@ -41,7 +40,7 @@ public class Notify {
public static void createChannel() { public static void createChannel() {
NotificationManagerCompat notifyMgr = NotificationManagerCompat.from(App.get()); NotificationManagerCompat notifyMgr = NotificationManagerCompat.from(App.get());
notifyMgr.createNotificationChannel(new NotificationChannelCompat.Builder(DEFAULT, NotificationManagerCompat.IMPORTANCE_LOW).setName("XMBOX").build()); notifyMgr.createNotificationChannel(new NotificationChannelCompat.Builder(DEFAULT, NotificationManagerCompat.IMPORTANCE_LOW).setName("TV").build());
} }
public static String getError(int resId, Throwable e) { public static String getError(int resId, Throwable e) {
@@ -50,7 +49,7 @@ public class Notify {
} }
public static void show(Notification notification) { public static void show(Notification notification) {
if (Build.VERSION.SDK_INT >= 33 && ActivityCompat.checkSelfPermission(App.get(), Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) return; if (ActivityCompat.checkSelfPermission(App.get(), Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) return;
NotificationManagerCompat.from(App.get()).notify(ID, notification); NotificationManagerCompat.from(App.get()).notify(ID, notification);
} }
@@ -20,7 +20,6 @@ import com.github.catvod.utils.Logger;
import com.github.catvod.utils.Path; import com.github.catvod.utils.Path;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
import java.io.File; import java.io.File;
@@ -34,7 +33,6 @@ public class Updater implements Download.Callback {
private boolean dev; private boolean dev;
private boolean forceCheck; // 是否为手动检查 private boolean forceCheck; // 是否为手动检查
private String latestVersion; // 存储检测到的最新版本 private String latestVersion; // 存储检测到的最新版本
private String releaseApkUrl; // 从 GitHub Release 获取的 APK 下载链接
private File getFile() { private File getFile() {
return Path.root("Download", "XMBOX-update.apk"); return Path.root("Download", "XMBOX-update.apk");
@@ -45,12 +43,6 @@ public class Updater implements Download.Callback {
} }
private String getApk() { private String getApk() {
// 优先使用从 GitHub Release 获取的 APK URL
if (releaseApkUrl != null && !releaseApkUrl.isEmpty()) {
Logger.d("APK download URL from Release: " + releaseApkUrl);
return releaseApkUrl;
}
// 使用JSON中指定的具体下载路径 // 使用JSON中指定的具体下载路径
try { try {
String response = OkHttp.string(getJson()); String response = OkHttp.string(getJson());
@@ -120,56 +112,14 @@ public class Updater implements Download.Callback {
private void doInBackground(Activity activity) { private void doInBackground(Activity activity) {
Logger.d("Updater: Starting update check..."); Logger.d("Updater: Starting update check...");
try { try {
// 优先使用 JSON 方式检测更新(兼容性更好) // 直接使用GitHub Releases API检测最新版本
String response = OkHttp.string(getJson());
JSONObject object = new JSONObject(response);
String name = object.optString("name");
String desc = object.optString("desc");
int code = object.optInt("code");
Logger.d("Updater: JSON Remote version: " + name + ", code: " + code);
Logger.d("Updater: Local version: " + BuildConfig.VERSION_NAME + ", code: " + BuildConfig.VERSION_CODE);
// 使用 JSON 中的版本信息
if (need(code, name)) {
Logger.d("Updater: Update needed (from JSON), showing dialog");
this.latestVersion = name; // 保存最新版本号
// 从 JSON 获取下载链接
JSONObject downloads = object.optJSONObject("downloads");
if (downloads != null) {
String abi = BuildConfig.FLAVOR_abi;
String downloadPath = downloads.optString(abi);
if (!downloadPath.isEmpty()) {
String baseUrl = Github.useCnMirror() ?
"https://gitee.com/ochenoktochen/XMBOX-Release/raw/main" :
"https://raw.githubusercontent.com/Tosencen/XMBOX-Release/main";
this.releaseApkUrl = baseUrl + "/apk/" + (dev ? "dev" : "release") + "/" + downloadPath;
Logger.d("Updater: APK URL from JSON: " + this.releaseApkUrl);
}
}
App.post(() -> show(activity, name, desc));
} else {
Logger.d("Updater: No update needed (from JSON)");
if (forceCheck) {
App.post(() -> Notify.show("已是最新版本 " + name));
}
}
} catch (Exception e) {
Logger.e("Updater: JSON check failed, trying GitHub API: " + e.getMessage());
// JSON 检测失败,尝试使用 GitHub Releases API
checkViaGitHubAPI(activity);
}
}
private void checkViaGitHubAPI(Activity activity) {
try {
String releasesUrl = "https://api.github.com/repos/Tosencen/XMBOX/releases/latest"; String releasesUrl = "https://api.github.com/repos/Tosencen/XMBOX/releases/latest";
Logger.d("Updater: Trying GitHub Releases API: " + releasesUrl); Logger.d("Updater: GitHub Releases API URL: " + releasesUrl);
String response = OkHttp.string(releasesUrl); String response = OkHttp.string(releasesUrl);
Logger.d("Updater: API response length: " + response.length());
// 检查响应是否包含错误信息
if (response.contains("rate limit exceeded")) { if (response.contains("rate limit exceeded")) {
Logger.e("Updater: Rate limit exceeded"); Logger.e("Updater: Rate limit exceeded");
if (forceCheck) { if (forceCheck) {
@@ -181,7 +131,7 @@ public class Updater implements Download.Callback {
if (response.contains("Not Found") || response.contains("404")) { if (response.contains("Not Found") || response.contains("404")) {
Logger.e("Updater: Release not found"); Logger.e("Updater: Release not found");
if (forceCheck) { if (forceCheck) {
App.post(() -> Notify.show("检查更新失败:无法连接到更新服务器")); App.post(() -> Notify.show("检查更新失败:更新服务暂时不可用"));
} }
return; return;
} }
@@ -189,33 +139,29 @@ public class Updater implements Download.Callback {
JSONObject release = new JSONObject(response); JSONObject release = new JSONObject(response);
String tagName = release.optString("tag_name"); String tagName = release.optString("tag_name");
String body = release.optString("body"); String body = release.optString("body");
// 提取版本号(去掉v前缀)
String version = tagName.startsWith("v") ? tagName.substring(1) : tagName; String version = tagName.startsWith("v") ? tagName.substring(1) : tagName;
Logger.d("Updater: GitHub API Remote version: " + version); Logger.d("Updater: Remote version: " + version);
Logger.d("Updater: Local version: " + BuildConfig.VERSION_NAME);
// 从 assets 中查找 APK
JSONArray assets = release.optJSONArray("assets");
if (assets != null) {
String targetApkName = BuildConfig.FLAVOR_mode + "-" + BuildConfig.FLAVOR_abi + "-v" + version + ".apk";
for (int i = 0; i < assets.length(); i++) {
JSONObject asset = assets.getJSONObject(i);
if (targetApkName.equals(asset.optString("name"))) {
this.releaseApkUrl = asset.optString("browser_download_url");
break;
}
}
}
// 比较版本号
if (needUpdate(version)) { if (needUpdate(version)) {
this.latestVersion = version; Logger.d("Updater: Update needed, showing dialog");
this.latestVersion = version; // 保存最新版本号
App.post(() -> show(activity, version, body)); App.post(() -> show(activity, version, body));
} else if (forceCheck) { } else {
Logger.d("Updater: No update needed");
if (forceCheck) {
App.post(() -> Notify.show("已是最新版本 " + version)); App.post(() -> Notify.show("已是最新版本 " + version));
} }
}
} catch (Exception e) { } catch (Exception e) {
Logger.e("Updater: GitHub API check failed: " + e.getMessage()); Logger.e("Updater: Exception during update check: " + e.getMessage());
e.printStackTrace();
if (forceCheck) { if (forceCheck) {
App.post(() -> Notify.show("检查更新失败:无法连接到更新服务器")); App.post(() -> Notify.show("检查更新失败:网络连接异常"));
} }
} }
} }
+1 -1
View File
@@ -25,7 +25,7 @@
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="本项目仅用于学习Android开发,代码改自FongMi/TV项目。" android:text="本项目仅用于学习Android开发,代码改自FongMi/TV (https://github.com/FongMi/TV)。"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="14sp" android:textSize="14sp"
android:layout_marginTop="8dp" /> android:layout_marginTop="8dp" />
+1 -1
View File
@@ -491,7 +491,7 @@ include ':thunder'
include ':tvbus' include ':tvbus'
include ':zlive' include ':zlive'
rootProject.name = "XMBOX" rootProject.name = "TV"
EOF EOF
echo -e "${GREEN}依赖修复完成!${NC}" echo -e "${GREEN}依赖修复完成!${NC}"
+25
View File
@@ -0,0 +1,25 @@
# 配置Java路径,使用Java 17而不是默认的Java 21
org.gradle.java.home=/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home
# 增加构建内存
org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=1024m -XX:+HeapDumpOnOutOfMemoryError
# 启用并行构建
org.gradle.parallel=true
org.gradle.caching=true
# 配置网络设置
systemProp.https.protocols=TLSv1.2,TLSv1.3
systemProp.https.proxyPort=0
systemProp.https.nonProxyHosts=localhost
# Android相关配置
android.useAndroidX=true
android.enableJetifier=true
android.jetifier.ignorelist=bcprov-jdk15on,annotation-experimental-1.4.1.aar,activity-1.8.0.aar,nextlib-media3ext-0.8.4.aar,sardine-android-0.9.aar,bcprov-jdk18on-1.79.jar
# 允许高版本的SDK
android.suppressUnsupportedCompileSdk=35
# 禁用增量编译以解决某些兼容性问题
android.enableBuildIncremental=false
Binary file not shown.
+7
View File
@@ -0,0 +1,7 @@
git clone --mirror https://github.com/FongMi/Release.git
java -jar bfg.jar --delete-files *.apk Release.git
java -jar bfg.jar --delete-files *.json Release.git
cd Release.git
git reflog expire --expire=now --all && git gc --prune=now --aggressive
git push
git gc
+2 -2
View File
@@ -20,6 +20,6 @@ dependencyResolutionManagement {
} }
include ':app' include ':app'
include ':catvod' include ':catvod'
// include ':chaquo' // 已移除Python支持 include ':chaquo'
include ':quickjs' include ':quickjs'
rootProject.name = "XMBOX" rootProject.name = "TV"