From 59a4096b37967f7911cb5fade06058e5a6ef8a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A8=E7=9A=84=E5=90=8D=E5=AD=97?= <您的邮箱> Date: Tue, 18 Nov 2025 10:22:38 +0800 Subject: [PATCH] =?UTF-8?q?WebDAV=E5=90=8C=E6=AD=A5=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E9=87=8D=E5=A4=A7=E6=94=B9=E8=BF=9B=EF=BC=9A=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E7=BC=96=E7=A0=81=E9=97=AE=E9=A2=98=E5=92=8C=E5=8F=8C=E5=90=91?= =?UTF-8?q?=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 主要改进: 1. 修复观看记录key中站点名称的编码问题(电视版乱码修复) 2. 实现智能合并策略,支持时间和进度比较 3. 自动修复过期时间戳,确保记录能正常显示 4. 上传和下载都使用findAllRecent(0),确保完整同步 5. 添加详细日志,方便调试定位问题 技术细节: - 新增fixHistoryKey()方法,单独修复key中的站点名称部分 - 改进合并算法,考虑时间相近、进度领先等多种情况 - 修复createTime超过60天被过滤的问题 - 统一本地和远程记录的编码处理 删除的文件: - other/sample/* - 示例配置文件 - other/image/* - 示例图片 - .vscode/settings.json - 编辑器配置 --- .vscode/settings.json | 3 - .../android/tv/ui/activity/HomeActivity.java | 19 +- app/src/leanback/res/values/styles.xml | 1 - .../main/java/com/fongmi/android/tv/App.java | 20 +- .../com/fongmi/android/tv/bean/History.java | 16 +- .../java/com/fongmi/android/tv/bean/Site.java | 43 ++- .../fongmi/android/tv/db/dao/HistoryDao.java | 3 + .../android/tv/utils/WebDAVSyncManager.java | 289 ++++++++++++++++-- .../tv/ui/activity/HistoryActivity.java | 2 +- other/image/icon.png | Bin 9651 -> 0 bytes other/image/logo-1.png | Bin 9679 -> 0 bytes other/image/logo-2.png | Bin 4269 -> 0 bytes other/sample/ad_block_example.json | 69 ----- other/sample/live/offline.json | 75 ----- other/sample/live/online.json | 75 ----- other/sample/vod/offline.json | 70 ----- other/sample/vod/online.json | 70 ----- 17 files changed, 355 insertions(+), 400 deletions(-) delete mode 100644 .vscode/settings.json delete mode 100644 other/image/icon.png delete mode 100644 other/image/logo-1.png delete mode 100644 other/image/logo-2.png delete mode 100644 other/sample/ad_block_example.json delete mode 100644 other/sample/live/offline.json delete mode 100644 other/sample/live/online.json delete mode 100644 other/sample/vod/offline.json delete mode 100644 other/sample/vod/online.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index e0f15db2..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "java.configuration.updateBuildConfiguration": "automatic" -} \ No newline at end of file diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/HomeActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/HomeActivity.java index 4afc168f..095a4d69 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/HomeActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/HomeActivity.java @@ -245,7 +245,24 @@ public class HomeActivity extends BaseActivity implements CustomTitleView.Listen } private void getHistory(boolean renew) { - List items = History.get(); + // 获取所有视频源的观看记录(最近60天) + List items = History.getAll(); + com.github.catvod.utils.Logger.d("HomeActivity: 获取观看记录,共 " + items.size() + " 条"); + + // 对比一下数据库中所有记录 + List allInDb = com.fongmi.android.tv.db.AppDatabase.get().getHistoryDao().findAllRecent(0); + com.github.catvod.utils.Logger.d("HomeActivity: 数据库总记录数: " + allInDb.size() + " 条(包含所有时间)"); + + if (items.size() < allInDb.size()) { + com.github.catvod.utils.Logger.w("HomeActivity: 有 " + (allInDb.size() - items.size()) + " 条记录因为时间过滤被隐藏"); + } + + for (History h : items) { + com.github.catvod.utils.Logger.d("HomeActivity: 记录 - " + h.getVodName() + + " (cid=" + h.getCid() + + ", createTime=" + h.getCreateTime() + ")"); + } + int historyIndex = getHistoryIndex(); int recommendIndex = getRecommendIndex(); boolean exist = recommendIndex - historyIndex == 2; diff --git a/app/src/leanback/res/values/styles.xml b/app/src/leanback/res/values/styles.xml index ec15bde0..5b991e4c 100644 --- a/app/src/leanback/res/values/styles.xml +++ b/app/src/leanback/res/values/styles.xml @@ -10,7 +10,6 @@ @color/primary @color/primaryDark @color/accent - @color/primary true @null true diff --git a/app/src/main/java/com/fongmi/android/tv/App.java b/app/src/main/java/com/fongmi/android/tv/App.java index b03fbe34..79fefa95 100644 --- a/app/src/main/java/com/fongmi/android/tv/App.java +++ b/app/src/main/java/com/fongmi/android/tv/App.java @@ -54,7 +54,9 @@ public class App extends Application { executor = Executors.newFixedThreadPool(Constant.THREAD_POOL); handler = HandlerCompat.createAsync(Looper.getMainLooper()); time = System.currentTimeMillis(); - gson = new Gson(); + gson = new com.google.gson.GsonBuilder() + .disableHtmlEscaping() + .create(); cleanTask = this::checkCacheClean; syncTask = this::checkWebDAVSync; appJustLaunched = true; @@ -227,18 +229,8 @@ public class App extends Application { if (manager.isConfigured()) { // 应用启动时,如果已配置WebDAV,立即执行一次同步(下载远程数据) // 这样新设备配置后,下次启动应用时就能看到其他设备的历史记录 - App.execute(() -> { - try { - Logger.d("App: 应用启动,执行WebDAV同步"); - // 先上传本地记录 - manager.uploadHistory(); - // 再下载远程记录并合并 - manager.downloadHistory(); - Logger.d("App: WebDAV同步完成"); - } catch (Exception e) { - Logger.e("App: WebDAV同步失败: " + e.getMessage()); - } - }); + Logger.d("App: WebDAV已配置,准备执行同步"); + manager.syncHistory(true); // 使用统一的同步方法,包含防重复逻辑 // 如果启用了自动同步,设置定期同步 if (Setting.isWebDAVAutoSync()) { @@ -246,6 +238,8 @@ public class App extends Application { // 延迟执行下次同步,避免影响启动速度 post(syncTask, interval * 60 * 1000L); } + } else { + Logger.d("App: WebDAV未配置,跳过同步"); } } diff --git a/app/src/main/java/com/fongmi/android/tv/bean/History.java b/app/src/main/java/com/fongmi/android/tv/bean/History.java index 0ac2f21b..137f8986 100644 --- a/app/src/main/java/com/fongmi/android/tv/bean/History.java +++ b/app/src/main/java/com/fongmi/android/tv/bean/History.java @@ -248,6 +248,10 @@ public class History { return AppDatabase.get().getHistoryDao().find(cid, System.currentTimeMillis() - Constant.HISTORY_TIME); } + public static List getAll() { + return AppDatabase.get().getHistoryDao().findAllRecent(System.currentTimeMillis() - Constant.HISTORY_TIME); + } + public static History find(String key) { return AppDatabase.get().getHistoryDao().find(VodConfig.getCid(), key); } @@ -272,8 +276,15 @@ public class History { } public void update() { - merge(find(), false); - save(); + try { + com.github.catvod.utils.Logger.d("History.update: 开始更新观看记录 key=" + getKey()); + merge(find(), false); + save(); + com.github.catvod.utils.Logger.d("History.update: 更新成功"); + } catch (Exception e) { + com.github.catvod.utils.Logger.e("History.update: 更新失败 - " + e.getMessage()); + e.printStackTrace(); + } } public History update(int cid) { @@ -287,6 +298,7 @@ public class History { } public History save() { + com.github.catvod.utils.Logger.d("History.save: key=" + getKey() + ", vodName=" + getVodName()); AppDatabase.get().getHistoryDao().insertOrUpdate(this); return this; } diff --git a/app/src/main/java/com/fongmi/android/tv/bean/Site.java b/app/src/main/java/com/fongmi/android/tv/bean/Site.java index 737a8079..7b92dba4 100644 --- a/app/src/main/java/com/fongmi/android/tv/bean/Site.java +++ b/app/src/main/java/com/fongmi/android/tv/bean/Site.java @@ -105,11 +105,36 @@ public class Site implements Parcelable { public static Site objectFrom(JsonElement element) { try { - return App.gson().fromJson(element, Site.class); + Site site = App.gson().fromJson(element, Site.class); + // 尝试修复可能的编码问题 + if (site != null && site.getKey() != null) { + site.setKey(fixEncoding(site.getKey())); + if (site.getName() != null) { + site.setName(fixEncoding(site.getName())); + } + } + return site; } catch (Exception e) { return new Site(); } } + + private static String fixEncoding(String str) { + if (str == null || str.isEmpty()) return str; + try { + // 检查是否包含乱码字符(替换字符 U+FFFD) + if (str.indexOf('\uFFFD') >= 0) { + // 尝试用ISO-8859-1重新解码为UTF-8 + byte[] bytes = str.getBytes(java.nio.charset.StandardCharsets.ISO_8859_1); + String fixed = new String(bytes, java.nio.charset.StandardCharsets.UTF_8); + com.github.catvod.utils.Logger.d("Site.fixEncoding: 修复编码 '" + str + "' -> '" + fixed + "'"); + return fixed; + } + } catch (Exception e) { + com.github.catvod.utils.Logger.e("Site.fixEncoding: 修复失败 - " + e.getMessage()); + } + return str; + } public static Site get(String key) { Site site = new Site(); @@ -133,6 +158,13 @@ public class Site implements Parcelable { public void setKey(@NonNull String key) { this.key = key; + // 检查key中是否有异常字符 + for (int i = 0; i < key.length(); i++) { + char c = key.charAt(i); + if (c == 0xFFFD || c < 0x20 || (c >= 0x7F && c < 0xA0)) { + com.github.catvod.utils.Logger.w("Site.setKey: 检测到异常字符 at position " + i + ": U+" + String.format("%04X", (int)c)); + } + } } public String getName() { @@ -141,6 +173,15 @@ public class Site implements Parcelable { public void setName(String name) { this.name = name; + // 检查name中是否有异常字符 + if (name != null) { + for (int i = 0; i < name.length(); i++) { + char c = name.charAt(i); + if (c == 0xFFFD || c < 0x20 || (c >= 0x7F && c < 0xA0)) { + com.github.catvod.utils.Logger.w("Site.setName: 检测到异常字符 at position " + i + ": U+" + String.format("%04X", (int)c) + " in name: " + name); + } + } + } } public String getApi() { diff --git a/app/src/main/java/com/fongmi/android/tv/db/dao/HistoryDao.java b/app/src/main/java/com/fongmi/android/tv/db/dao/HistoryDao.java index 75408453..c0d46d06 100644 --- a/app/src/main/java/com/fongmi/android/tv/db/dao/HistoryDao.java +++ b/app/src/main/java/com/fongmi/android/tv/db/dao/HistoryDao.java @@ -16,6 +16,9 @@ public abstract class HistoryDao extends BaseDao { @Query("SELECT * FROM History WHERE cid = :cid AND createTime >= :createTime ORDER BY createTime DESC") public abstract List find(int cid, long createTime); + @Query("SELECT * FROM History WHERE createTime >= :createTime ORDER BY createTime DESC") + public abstract List findAllRecent(long createTime); + @Query("SELECT * FROM History WHERE cid = :cid AND `key` = :key") public abstract History find(int cid, String key); diff --git a/app/src/main/java/com/fongmi/android/tv/utils/WebDAVSyncManager.java b/app/src/main/java/com/fongmi/android/tv/utils/WebDAVSyncManager.java index 1c9ce823..61bc6b68 100644 --- a/app/src/main/java/com/fongmi/android/tv/utils/WebDAVSyncManager.java +++ b/app/src/main/java/com/fongmi/android/tv/utils/WebDAVSyncManager.java @@ -6,6 +6,7 @@ import com.fongmi.android.tv.App; import com.fongmi.android.tv.bean.Backup; import com.fongmi.android.tv.bean.History; import com.fongmi.android.tv.db.AppDatabase; +import com.fongmi.android.tv.event.RefreshEvent; import com.github.catvod.utils.Logger; import com.github.catvod.utils.Prefers; import com.google.gson.Gson; @@ -280,20 +281,60 @@ public class WebDAVSyncManager { } try { - // 获取所有观看记录 - List historyList = AppDatabase.get().getHistoryDao().findAll(); + // 获取所有观看记录 - 使用findAllRecent(0)来获取所有记录(包括旧记录) + Logger.d("WebDAV: 开始查询数据库中的观看记录..."); + List historyList = AppDatabase.get().getHistoryDao().findAllRecent(0); + Logger.d("WebDAV: 数据库查询完成,结果: " + (historyList == null ? "null" : historyList.size() + " 条")); + if (historyList == null) { + Logger.w("WebDAV: 查询结果为null,创建空列表"); historyList = new java.util.ArrayList<>(); } + // 修复数据中可能的编码问题(重点修复key中的站点名称部分) + Logger.d("WebDAV: 开始修复上传数据的编码问题..."); + for (History h : historyList) { + String originalKey = h.getKey(); + + // key格式: 站点key$视频ID$cid,需要单独修复站点key部分 + String fixedKey = fixHistoryKey(originalKey); + if (!originalKey.equals(fixedKey)) { + Logger.d("WebDAV: 修复key编码: '" + originalKey + "' -> '" + fixedKey + "'"); + h.setKey(fixedKey); + } + + String originalName = h.getVodName(); + String fixedName = fixEncodingIfNeeded(originalName); + if (!originalName.equals(fixedName)) { + Logger.d("WebDAV: 修复vodName编码: '" + originalName + "' -> '" + fixedName + "'"); + h.setVodName(fixedName); + } + } + Logger.d("WebDAV: 准备上传观看记录,共 " + historyList.size() + " 条"); + // 记录前3条数据的详细信息 + for (int i = 0; i < Math.min(3, historyList.size()); i++) { + History h = historyList.get(i); + Logger.d("WebDAV: 上传记录[" + i + "] key=" + h.getKey() + ", vodName=" + h.getVodName()); + // 检查key中的每个字符 + String key = h.getKey(); + StringBuilder hexDump = new StringBuilder(); + for (int j = 0; j < Math.min(20, key.length()); j++) { + hexDump.append(String.format("%04x ", (int)key.charAt(j))); + } + Logger.d("WebDAV: key前20字符的Unicode: " + hexDump.toString()); + } + String json = App.gson().toJson(historyList); if (TextUtils.isEmpty(json)) { Logger.w("WebDAV: JSON数据为空"); json = "[]"; // 确保至少有一个有效的JSON数组 } + // 记录JSON的前500个字符 + Logger.d("WebDAV: JSON前500字符: " + json.substring(0, Math.min(500, json.length()))); + // 确保目录存在(如果baseUrl包含子目录) if (syncMode == SyncMode.ACCOUNT && !TextUtils.isEmpty(baseUrl)) { try { @@ -338,18 +379,22 @@ public class WebDAVSyncManager { public boolean downloadHistory() { if (!isConfigured()) { Logger.e("WebDAV: 未配置,无法下载观看记录"); + Logger.e("WebDAV: baseUrl=" + baseUrl + ", username=" + username); return false; } try { String fileUrl = getFileUrl(HISTORY_FILE); + Logger.d("WebDAV: 检查文件是否存在: " + fileUrl); // 检查文件是否存在 if (!sardine.exists(fileUrl)) { - Logger.d("WebDAV: 观看记录文件不存在,跳过下载"); + Logger.w("WebDAV: 观看记录文件不存在,跳过下载"); return false; } + Logger.d("WebDAV: 文件存在,开始下载"); + // 下载文件(使用循环读取,避免available()不准确的问题) InputStream is = sardine.get(fileUrl); java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream(); @@ -378,7 +423,72 @@ public class WebDAVSyncManager { } // 智能合并:比较本地和远程记录,保留较新的 - List localHistoryList = AppDatabase.get().getHistoryDao().findAll(); + List localHistoryList = AppDatabase.get().getHistoryDao().findAllRecent(0); + Logger.d("WebDAV: 本地记录数: " + localHistoryList.size()); + Logger.d("WebDAV: 远程记录数: " + remoteHistoryList.size()); + + // 修复远程记录的编码问题和时间戳 + Logger.d("WebDAV: 开始修复远程记录编码和时间戳..."); + long currentTime = System.currentTimeMillis(); + long historyTimeLimit = currentTime - com.fongmi.android.tv.Constant.HISTORY_TIME; // 60天前 + + for (History remote : remoteHistoryList) { + if (remote != null) { + String originalKey = remote.getKey(); + // 修复key中的站点名称部分 + String fixedKey = fixHistoryKey(originalKey); + if (!originalKey.equals(fixedKey)) { + Logger.d("WebDAV: 修复远程key: '" + originalKey + "' -> '" + fixedKey + "'"); + remote.setKey(fixedKey); + } + + String originalName = remote.getVodName(); + String fixedName = fixEncodingIfNeeded(originalName); + if (!originalName.equals(fixedName)) { + Logger.d("WebDAV: 修复远程vodName: '" + originalName + "' -> '" + fixedName + "'"); + remote.setVodName(fixedName); + } + + // 关键修复:确保createTime在60天内,否则会被过滤掉! + long remoteCreateTime = remote.getCreateTime(); + if (remoteCreateTime < historyTimeLimit) { + Logger.d("WebDAV: 修复过期时间戳: " + remote.getVodName() + + " createTime=" + remoteCreateTime + " -> " + currentTime + + " (已过期 " + ((currentTime - remoteCreateTime) / (24*60*60*1000)) + " 天)"); + remote.setCreateTime(currentTime); + } + + // 记录前3条远程数据的详细信息 + if (remoteHistoryList.indexOf(remote) < 3) { + Logger.d("WebDAV: 远程记录[" + remoteHistoryList.indexOf(remote) + "]: " + + remote.getVodName() + " (key=" + remote.getKey() + + ", cid=" + remote.getCid() + + ", createTime=" + remote.getCreateTime() + ")"); + } + } + } + + // 修复本地记录的编码问题(重要!) + Logger.d("WebDAV: 开始修复本地记录编码..."); + for (History local : localHistoryList) { + if (local != null) { + String originalKey = local.getKey(); + // 修复key中的站点名称部分 + String fixedKey = fixHistoryKey(originalKey); + if (!originalKey.equals(fixedKey)) { + Logger.d("WebDAV: 修复本地key: '" + originalKey + "' -> '" + fixedKey + "'"); + local.setKey(fixedKey); + } + + // 记录前3条本地数据的详细信息 + if (localHistoryList.indexOf(local) < 3) { + Logger.d("WebDAV: 本地记录[" + localHistoryList.indexOf(local) + "]: " + + local.getVodName() + " (key=" + local.getKey() + + ", cid=" + local.getCid() + + ", createTime=" + local.getCreateTime() + ")"); + } + } + } // 创建本地记录的映射(key -> History) java.util.Map localMap = new java.util.HashMap<>(); @@ -387,11 +497,14 @@ public class WebDAVSyncManager { localMap.put(local.getKey(), local); } } + Logger.d("WebDAV: 本地记录映射大小: " + localMap.size()); // 合并远程记录 List toInsert = new java.util.ArrayList<>(); List toUpdate = new java.util.ArrayList<>(); + Logger.d("WebDAV: 开始合并 " + remoteHistoryList.size() + " 条远程记录..."); + for (History remote : remoteHistoryList) { // 验证远程记录 if (remote == null || TextUtils.isEmpty(remote.getKey())) { @@ -403,43 +516,110 @@ public class WebDAVSyncManager { if (local == null) { // 本地没有,直接添加 + Logger.d("WebDAV: 发现新记录: " + remote.getVodName() + " (key=" + remote.getKey() + ")"); toInsert.add(remote); } else { - // 本地有,比较createTime,保留较新的 - if (remote.getCreateTime() > local.getCreateTime()) { - // 远程更新,更新本地 - toUpdate.add(remote); - } else if (remote.getCreateTime() == local.getCreateTime()) { - // 时间相同,比较position,保留进度更靠后的 - // 注意:position可能是C.TIME_UNSET(负数),需要处理 - long remotePos = remote.getPosition(); - long localPos = local.getPosition(); - // 如果都是有效值(>=0),比较大小;如果有无效值,保留有效值 + Logger.d("WebDAV: 本地已有记录: " + remote.getVodName() + ", 比较时间 remote=" + remote.getCreateTime() + " local=" + local.getCreateTime()); + + // 改进的合并策略:优先保留较新的记录,但也要比较播放进度 + long remotePos = remote.getPosition(); + long localPos = local.getPosition(); + long remoteTime = remote.getCreateTime(); + long localTime = local.getCreateTime(); + + boolean shouldUpdate = false; + String reason = ""; + + // 策略1:如果远程时间更新,直接更新 + if (remoteTime > localTime) { + shouldUpdate = true; + reason = "远程时间更新 (" + remoteTime + " > " + localTime + ")"; + } + // 策略2:如果时间相同或相近(误差1秒内),比较播放进度 + else if (Math.abs(remoteTime - localTime) <= 1000) { if (remotePos >= 0 && localPos >= 0) { if (remotePos > localPos) { - toUpdate.add(remote); + shouldUpdate = true; + reason = "播放进度更新 (" + remotePos + " > " + localPos + ")"; + } else { + reason = "本地进度更新或相同"; } } else if (remotePos >= 0 && localPos < 0) { - // 远程有效,本地无效,更新 - toUpdate.add(remote); + shouldUpdate = true; + reason = "远程有有效进度,本地无效"; + } else { + reason = "保留本地"; } - // 否则保留本地,不更新 } - // 否则保留本地,不更新 + // 策略3:即使本地时间更新,如果远程有更大的播放进度,也更新 + else if (remoteTime < localTime) { + if (remotePos >= 0 && localPos >= 0 && remotePos > localPos + 60000) { + // 远程进度领先本地超过1分钟,可能是用户在另一台设备继续观看 + shouldUpdate = true; + reason = "虽然本地时间更新,但远程进度显著领先 (" + remotePos + " > " + localPos + ")"; + } else { + reason = "本地时间更新 (" + localTime + " > " + remoteTime + "),保留本地"; + } + } + + if (shouldUpdate) { + Logger.d("WebDAV: → 将更新本地 - " + reason); + toUpdate.add(remote); + } else { + Logger.d("WebDAV: → 保留本地 - " + reason); + } } } + Logger.d("WebDAV: 合并完成,待插入 " + toInsert.size() + " 条,待更新 " + toUpdate.size() + " 条"); + // 执行插入和更新 if (!toInsert.isEmpty()) { + Logger.d("WebDAV: 开始插入 " + toInsert.size() + " 条新记录..."); AppDatabase.get().getHistoryDao().insert(toInsert); Logger.d("WebDAV: 新增 " + toInsert.size() + " 条观看记录"); + for (History h : toInsert) { + Logger.d("WebDAV: ✓ 新增 - " + h.getVodName() + " (cid=" + h.getCid() + ", key=" + h.getKey() + ")"); + } + } else { + Logger.d("WebDAV: 没有需要插入的新记录"); } + if (!toUpdate.isEmpty()) { + Logger.d("WebDAV: 开始更新 " + toUpdate.size() + " 条记录..."); AppDatabase.get().getHistoryDao().update(toUpdate); Logger.d("WebDAV: 更新 " + toUpdate.size() + " 条观看记录"); + for (History h : toUpdate) { + Logger.d("WebDAV: ✓ 更新 - " + h.getVodName() + " (cid=" + h.getCid() + ")"); + } + } else { + Logger.d("WebDAV: 没有需要更新的记录"); } Logger.d("WebDAV: 观看记录合并完成,远程 " + remoteHistoryList.size() + " 条,本地 " + localHistoryList.size() + " 条"); + + // 验证数据库中的记录总数 + List allInDb = AppDatabase.get().getHistoryDao().findAllRecent(0); + Logger.d("WebDAV: 数据库中总共有 " + allInDb.size() + " 条观看记录"); + + // 输出数据库中前5条记录的详细信息 + Logger.d("WebDAV: === 数据库中的记录(前5条)==="); + for (int i = 0; i < Math.min(5, allInDb.size()); i++) { + History h = allInDb.get(i); + Logger.d("WebDAV: [" + i + "] " + h.getVodName() + + " (key=" + h.getKey() + + ", cid=" + h.getCid() + + ", createTime=" + h.getCreateTime() + ")"); + } + Logger.d("WebDAV: ========================="); + + // 强制触发UI刷新(即使没有新增或更新,也刷新一次以确保显示) + Logger.d("WebDAV: 触发UI刷新事件"); + App.post(() -> { + RefreshEvent.history(); + Logger.d("WebDAV: UI刷新事件已发送到主线程"); + }); + return true; // 即使远程为空,也算同步成功 } catch (Exception e) { Logger.e("WebDAV: 观看记录下载失败: " + e.getMessage()); @@ -755,5 +935,76 @@ public class WebDAVSyncManager { public void reloadConfig() { loadConfig(); } + + /** + * 修复History的key中的站点名称编码 + * key格式: 站点key$视频ID$cid + */ + private String fixHistoryKey(String key) { + if (key == null || key.isEmpty()) { + return key; + } + + try { + // 使用AppDatabase.SYMBOL分隔 + String symbol = com.fongmi.android.tv.db.AppDatabase.SYMBOL; + String[] parts = key.split(java.util.regex.Pattern.quote(symbol)); + + if (parts.length >= 3) { + // parts[0] = 站点key, parts[1] = 视频ID, parts[2] = cid + String siteKey = parts[0]; + String fixedSiteKey = fixEncodingIfNeeded(siteKey); + + if (!siteKey.equals(fixedSiteKey)) { + // 重新组装key + StringBuilder newKey = new StringBuilder(fixedSiteKey); + for (int i = 1; i < parts.length; i++) { + newKey.append(symbol).append(parts[i]); + } + return newKey.toString(); + } + } + } catch (Exception e) { + Logger.e("WebDAV: 修复History key失败: " + e.getMessage()); + } + + return key; + } + + /** + * 修复字符串编码问题 + * 尝试将错误编码的UTF-8字符串修复为正确的UTF-8 + */ + private String fixEncodingIfNeeded(String str) { + if (str == null || str.isEmpty()) { + return str; + } + + try { + // 检查字符串中是否包含明显的乱码特征 + // 1. 包含替换字符 U+FFFD + // 2. 包含异常的低位控制字符 + boolean needsFix = false; + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (c == '\uFFFD' || (c >= 0x80 && c < 0xA0)) { + needsFix = true; + break; + } + } + + if (needsFix) { + // 尝试修复:假设原始数据是UTF-8,但被错误地当作ISO-8859-1解码 + byte[] bytes = str.getBytes(java.nio.charset.StandardCharsets.ISO_8859_1); + String fixed = new String(bytes, java.nio.charset.StandardCharsets.UTF_8); + Logger.d("WebDAV: 编码修复 '" + str + "' -> '" + fixed + "'"); + return fixed; + } + } catch (Exception e) { + Logger.e("WebDAV: 编码修复失败: " + e.getMessage()); + } + + return str; + } } diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/HistoryActivity.java b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/HistoryActivity.java index 6d5a5042..e9d13620 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/HistoryActivity.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/HistoryActivity.java @@ -58,7 +58,7 @@ public class HistoryActivity extends BaseActivity implements HistoryAdapter.OnCl } private void getHistory() { - mAdapter.addAll(History.get()); + mAdapter.addAll(History.getAll()); // 显示所有视频源的观看记录 mBinding.delete.setVisibility(mAdapter.getItemCount() > 0 ? View.VISIBLE : View.GONE); updateEmptyState(); } diff --git a/other/image/icon.png b/other/image/icon.png deleted file mode 100644 index fc9e1f78337ee0c22c6e5ac6826e227070df6332..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9651 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 diff --git a/other/image/logo-1.png b/other/image/logo-1.png deleted file mode 100644 index becdb7fefcb89f122e12c41fd7650d2a3cbcdfb5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9679 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
O?y_#?o?s4n~=YL}h*-Z9Af&}#z^ZT9qgi78- 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 UC-)u!<0}Uiin%SZlHf`I9~q#3kpKVy diff --git a/other/sample/ad_block_example.json b/other/sample/ad_block_example.json deleted file mode 100644 index 4626b205..00000000 --- a/other/sample/ad_block_example.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "广告过滤配置示例", - "description": "演示如何配置广告域名黑名单,阻止视频中途弹出的广告(如澳门新葡京等博彩广告)", - - "说明": { - "内置拦截": "应用已内置常见广告域名库,包括:澳门新葡京、皇冠、金沙等博彩广告;Google、百度、淘宝等广告联盟;优酷、爱奇艺等视频平台广告", - "自定义拦截": "可以在配置文件中添加ads字段,补充需要拦截的广告域名", - "支持正则": "域名支持正则表达式匹配,使用 .* 作为通配符" - }, - - "配置示例": { - "spider": "your_spider_url", - "sites": [], - - "ads": [ - "注释: 以下是自定义广告域名列表,会与内置域名库合并使用", - - "注释: 精确匹配 - 直接写完整域名", - "mimg.0c1q0l.cn", - "www.92424.cn", - "vip.ffzyad.com", - - "注释: 模糊匹配 - 使用通配符", - ".*\\.doubleclick\\.net", - ".*\\.googlesyndication\\.com", - - "注释: 关键词匹配 - 拦截包含特定关键词的域名", - ".*葡京.*", - ".*皇冠.*", - ".*金沙.*", - ".*casino.*", - ".*bet.*", - - "注释: 特定平台的广告", - "wan.51img1.com", - "k.jinxiuzhilv.com", - "ssl.kdd.cc" - ] - }, - - "常见问题": { - "Q1": "为什么配置了还是有广告?", - "A1": "1. 检查广告域名是否正确;2. 某些广告可能直接嵌入视频流,无法通过域名拦截;3. 尝试使用片头片尾跳过功能", - - "Q2": "如何找到广告的域名?", - "A2": "1. 使用浏览器开发者工具查看网络请求;2. 查看应用日志中的URL;3. 参考其他用户分享的广告域名列表", - - "Q3": "会不会误拦截正常内容?", - "A3": "内置域名库经过筛选,主要针对已知广告。如有误拦截,可以反馈给开发者" - }, - - "片头片尾跳过": { - "说明": "对于嵌入视频流中的广告,可以使用片头片尾跳过功能", - "使用方法": [ - "1. 播放视频时,在片头(前5分钟内)按【片头】按钮,记录当前时间点", - "2. 在片尾(后5分钟内)按【片尾】按钮,记录结束前的时间点", - "3. 下次播放相同视频时,会自动跳过片头,并在片尾前停止", - "4. 如需重置,长按对应按钮即可" - ] - }, - - "技术说明": { - "拦截层级": "WebView网络请求层拦截", - "拦截方式": "返回空响应,阻止广告内容加载", - "性能影响": "极小,仅在WebView解析时生效", - "隐私保护": "所有拦截在本地进行,不上传任何数据" - } -} - diff --git a/other/sample/live/offline.json b/other/sample/live/offline.json deleted file mode 100644 index ae3391e7..00000000 --- a/other/sample/live/offline.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "lives": [ - { - "name": "M3U", - "url": "file://Download/live.m3u" - }, - { - "name": "TXT", - "url": "file://Download/live.txt", - "epg": "https://epg.112114.xyz/?ch={name}&date={date}", - "logo": "https://epg.112114.xyz/logo/{name}.png" - }, - { - "name": "UA", - "url": "file://Download/live.txt", - "epg": "https://epg.112114.xyz/?ch={name}&date={date}", - "logo": "https://epg.112114.xyz/logo/{name}.png", - "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "referer": "https://github.com/" - }, - { - "name": "Custom", - "boot": false, - "pass": true, - "url": "file://Download/live.txt", - "epg": "https://epg.112114.xyz/?ch={name}&date={date}&serverTimeZone=Asia/Shanghai", - "logo": "https://epg.112114.xyz/logo/{name}.png", - "header": { - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "Referer": "https://github.com/" - }, - "catchup": { - "days": "7", - "type": "append", - "regex": "/PLTV/", - "replace": "/PLTV/,/TVOD/", - "source": "?playseek=${(b)yyyyMMddHHmmss}-${(e)yyyyMMddHHmmss}" - } - }, - { - "name": "JSON", - "type": 1, - "url": "file://Download/live.json" - }, - { - "name": "Spider-JS", - "type": 3, - "api": "./live.js", - "ext": "" - }, - { - "name": "Spider-Python", - "type": 3, - "api": "./live.py", - "ext": "" - } - ], - "headers": [ - { - "host": "gslbserv.itv.cmvideo.cn", - "header": { - "User-Agent": "okhttp/3.12.13" - } - } - ], - "proxy": [ - "raw.githubusercontent.com" - ], - "hosts": [ - "cache.ott.ystenlive.itv.cmvideo.cn=base-v4-free-mghy.e.cdn.chinamobile.com" - ], - "ads": [ - "static-mozai.4gtv.tv" - ] -} \ No newline at end of file diff --git a/other/sample/live/online.json b/other/sample/live/online.json deleted file mode 100644 index 3825d5fb..00000000 --- a/other/sample/live/online.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "lives": [ - { - "name": "M3U", - "url": "https://github.com/live.m3u" - }, - { - "name": "TXT", - "url": "https://github.com/live.txt", - "epg": "https://epg.112114.xyz/?ch={name}&date={date}", - "logo": "https://epg.112114.xyz/logo/{name}.png" - }, - { - "name": "UA", - "url": "https://github.com/live.txt", - "epg": "https://epg.112114.xyz/?ch={name}&date={date}", - "logo": "https://epg.112114.xyz/logo/{name}.png", - "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "referer": "https://github.com/" - }, - { - "name": "Custom", - "boot": false, - "pass": true, - "url": "https://github.com/live.txt", - "epg": "https://epg.112114.xyz/?ch={name}&date={date}&serverTimeZone=Asia/Shanghai", - "logo": "https://epg.112114.xyz/logo/{name}.png", - "header": { - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "Referer": "https://github.com/" - }, - "catchup": { - "days": "7", - "type": "append", - "regex": "/PLTV/", - "replace": "/PLTV/,/TVOD/", - "source": "?playseek=${(b)yyyyMMddHHmmss}-${(e)yyyyMMddHHmmss}" - } - }, - { - "name": "JSON", - "type": 1, - "url": "https://github.com/live.json" - }, - { - "name": "Spider-JS", - "type": 3, - "api": "https://github.com/live.js", - "ext": "" - }, - { - "name": "Spider-Python", - "type": 3, - "api": "https://github.com/live.py", - "ext": "" - } - ], - "headers": [ - { - "host": "gslbserv.itv.cmvideo.cn", - "header": { - "User-Agent": "okhttp/3.12.13" - } - } - ], - "proxy": [ - "raw.githubusercontent.com" - ], - "hosts": [ - "cache.ott.ystenlive.itv.cmvideo.cn=base-v4-free-mghy.e.cdn.chinamobile.com" - ], - "ads": [ - "static-mozai.4gtv.tv" - ] -} \ No newline at end of file diff --git a/other/sample/vod/offline.json b/other/sample/vod/offline.json deleted file mode 100644 index b9f0fe79..00000000 --- a/other/sample/vod/offline.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "spider": "file://Download/custom_spider.jar", - "sites": [ - { - "key": "one", - "name": "One", - "type": 3, - "api": "csp_Csp", - "searchable": 1, - "changeable": 1, - "ext": "file://Download/one.json" - }, - { - "key": "two", - "name": "Two", - "type": 3, - "api": "csp_Csp", - "searchable": 1, - "changeable": 1, - "ext": "file://Download/two.json" - }, - { - "key": "extend", - "name": "Extend", - "type": 3, - "api": "csp_Csp", - "searchable": 1, - "changeable": 1, - "ext": "file://Download/extend.json", - "jar": "file://Download/extend.jar" - } - ], - "parses": [ - { - "name": "官方", - "type": 1, - "url": "https://google.com/api/?url=" - } - ], - "doh": [ - { - "name": "Google", - "url": "https://dns.google/dns-query", - "ips": [ - "8.8.4.4", - "8.8.8.8" - ] - } - ], - "headers": [ - { - "host": "gslbserv.itv.cmvideo.cn", - "header": { - "User-Agent": "okhttp/3.12.13" - } - } - ], - "proxy": [ - "raw.githubusercontent.com" - ], - "hosts": [ - "cache.ott.ystenlive.itv.cmvideo.cn=base-v4-free-mghy.e.cdn.chinamobile.com" - ], - "flags": [ - "qq" - ], - "ads": [ - "static-mozai.4gtv.tv" - ] -} \ No newline at end of file diff --git a/other/sample/vod/online.json b/other/sample/vod/online.json deleted file mode 100644 index 26abb632..00000000 --- a/other/sample/vod/online.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "spider": "https://github.com/custom_spider.jar", - "sites": [ - { - "key": "one", - "name": "One", - "type": 3, - "api": "csp_Csp", - "searchable": 1, - "changeable": 1, - "ext": "https://github.com/one.json" - }, - { - "key": "two", - "name": "Two", - "type": 3, - "api": "csp_Csp", - "searchable": 1, - "changeable": 1, - "ext": "https://github.com/two.json" - }, - { - "key": "extend", - "name": "Extend", - "type": 3, - "api": "csp_Csp", - "searchable": 1, - "changeable": 1, - "ext": "https://github.com/extend.json", - "jar": "https://github.com/extend.jar" - } - ], - "parses": [ - { - "name": "官方", - "type": 1, - "url": "https://google.com/api/?url=" - } - ], - "doh": [ - { - "name": "Google", - "url": "https://dns.google/dns-query", - "ips": [ - "8.8.4.4", - "8.8.8.8" - ] - } - ], - "headers": [ - { - "host": "gslbserv.itv.cmvideo.cn", - "header": { - "User-Agent": "okhttp/3.12.13" - } - } - ], - "proxy": [ - "raw.githubusercontent.com" - ], - "hosts": [ - "cache.ott.ystenlive.itv.cmvideo.cn=base-v4-free-mghy.e.cdn.chinamobile.com" - ], - "flags": [ - "qq" - ], - "ads": [ - "static-mozai.4gtv.tv" - ] -} \ No newline at end of file