Browse Source

修复卡片更新

chendeben 1 year ago
parent
commit
3cf5a0b0b6

+ 6 - 6
build-profile.json5

@@ -28,13 +28,13 @@
         "name": "default",
         "name": "default",
         "type": "HarmonyOS",
         "type": "HarmonyOS",
         "material": {
         "material": {
-          "storeFile": "/Users/chendeben/Documents/certs/release/qimeng.p12",
-          "storePassword": "0000001890ACF31E3C3B99E5679051FD8A935F2CB5DF21334FF046C76722E88C632739F2F6382841",
-          "keyAlias": "qimeng",
-          "keyPassword": "0000001807A031982A699D8CC5A5B852EE42BD2F314136C7055211EE80D4CA195374FBCD55EF1965",
+          "certpath": "C:\\Users\\Admin\\.ohos\\config\\default_TTMusic-new_gDcMTvfBBEwzdIYOYKAqM86VO4gb0Q1MpV1IYbfPK60=.cer",
+          "keyAlias": "debugKey",
+          "keyPassword": "0000001B535CB6CC1761559F1F1BE7484BC8F8ED913AA276A3382B606D63D7908491C37F3B3D813728713D",
+          "profile": "C:\\Users\\Admin\\.ohos\\config\\default_TTMusic-new_gDcMTvfBBEwzdIYOYKAqM86VO4gb0Q1MpV1IYbfPK60=.p7b",
           "signAlg": "SHA256withECDSA",
           "signAlg": "SHA256withECDSA",
-          "profile": "/Users/chendeben/Documents/certs/release/内部测试Release.p7b",
-          "certpath": "/Users/chendeben/Documents/certs/release/qimeng.cer"
+          "storeFile": "C:\\Users\\Admin\\.ohos\\config\\default_TTMusic-new_gDcMTvfBBEwzdIYOYKAqM86VO4gb0Q1MpV1IYbfPK60=.p12",
+          "storePassword": "0000001BBB2B40CC0DCF997B480478393C697411E4F454E69F1749EE5FB4759F365E31022109A5B4DCA4D5"
         }
         }
       }
       }
     ]
     ]

+ 235 - 6
entry/src/main/ets/common/service/UnifiedPlayerService.ets

@@ -2,13 +2,14 @@ import { VideoItem } from '../../viewmodel/VideoItem';
 import { PlayerManager, IPlayerManager, PlayerStateCallback } from './PlayerManager';
 import { PlayerManager, IPlayerManager, PlayerStateCallback } from './PlayerManager';
 import { PlayerStateModel, PlayerState, PlayerStateListener, PlayMode, PlayerError, PlayerErrorType } from './PlayerStateModel';
 import { PlayerStateModel, PlayerState, PlayerStateListener, PlayMode, PlayerError, PlayerErrorType } from './PlayerStateModel';
 import { PlaylistModel } from './PlaylistModel';
 import { PlaylistModel } from './PlaylistModel';
-import { PlayProgress } from '../widget/WidgetTypes';
+import { PlayProgress, WidgetData, WidgetSize, WidgetTheme } from '../widget/WidgetTypes';
 import { LogUtils } from '@ohos/ijkplayer';
 import { LogUtils } from '@ohos/ijkplayer';
 import { common } from '@kit.AbilityKit';
 import { common } from '@kit.AbilityKit';
 import { PreferencesUtil, StrUtil } from '@pura/harmony-utils';
 import { PreferencesUtil, StrUtil } from '@pura/harmony-utils';
 import { DataPersistenceService, PlaylistSyncService, PlaylistSyncListener, IDataPersistenceService, PlaylistData } from './DataPersistenceService';
 import { DataPersistenceService, PlaylistSyncService, PlaylistSyncListener, IDataPersistenceService, PlaylistData } from './DataPersistenceService';
 import { StateSyncService, IStateSyncService, StateChangeCallback, WidgetControlCallback } from './StateSyncService';
 import { StateSyncService, IStateSyncService, StateChangeCallback, WidgetControlCallback } from './StateSyncService';
 import { ErrorRecoveryStrategy, IErrorRecoveryStrategy, ErrorContext, ErrorRecoveryAction } from './ErrorRecoveryStrategy';
 import { ErrorRecoveryStrategy, IErrorRecoveryStrategy, ErrorContext, ErrorRecoveryAction } from './ErrorRecoveryStrategy';
+import { EnhancedFormUpdateService, UpdateStats } from '../widget/EnhancedFormUpdateService';
 import json from '@ohos.util.json';
 import json from '@ohos.util.json';
 
 
 /**
 /**
@@ -68,6 +69,7 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
   private playlistSync: PlaylistSyncService;
   private playlistSync: PlaylistSyncService;
   private stateSync: IStateSyncService;
   private stateSync: IStateSyncService;
   private errorRecovery: IErrorRecoveryStrategy;
   private errorRecovery: IErrorRecoveryStrategy;
+  private widgetUpdateService: EnhancedFormUpdateService;
   private context: common.UIAbilityContext | null = null;
   private context: common.UIAbilityContext | null = null;
   private progressTimer: number = -1;
   private progressTimer: number = -1;
   private isInitialized: boolean = false;
   private isInitialized: boolean = false;
@@ -81,6 +83,7 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
     this.playlistSync = PlaylistSyncService.getInstance();
     this.playlistSync = PlaylistSyncService.getInstance();
     this.stateSync = StateSyncService.getInstance();
     this.stateSync = StateSyncService.getInstance();
     this.errorRecovery = ErrorRecoveryStrategy.getInstance();
     this.errorRecovery = ErrorRecoveryStrategy.getInstance();
+    this.widgetUpdateService = EnhancedFormUpdateService.getInstance();
     
     
     LogUtils.getInstance().LOGI('UnifiedPlayerService: Instance created');
     LogUtils.getInstance().LOGI('UnifiedPlayerService: Instance created');
   }
   }
@@ -113,6 +116,10 @@ async initialize(context: common.UIAbilityContext): Promise<void> {
       await this.playlistSync.initialize(context);
       await this.playlistSync.initialize(context);
       await this.stateSync.initialize(context);
       await this.stateSync.initialize(context);
       
       
+      // 初始化卡片更新服务
+      this.widgetUpdateService.setAppContext(context);
+      LogUtils.getInstance().LOGI('UnifiedPlayerService: Widget update service initialized');
+      
       // 设置同步监听器
       // 设置同步监听器
       this.playlistSync.addSyncListener(this);
       this.playlistSync.addSyncListener(this);
       this.stateSync.subscribeToStateChanges(this);
       this.stateSync.subscribeToStateChanges(this);
@@ -121,25 +128,35 @@ async initialize(context: common.UIAbilityContext): Promise<void> {
       // 设置状态模型监听器,自动广播状态变化
       // 设置状态模型监听器,自动广播状态变化
       class StateListenerImpl implements PlayerStateListener {
       class StateListenerImpl implements PlayerStateListener {
         private stateSync: IStateSyncService;
         private stateSync: IStateSyncService;
+        private widgetService: EnhancedFormUpdateService;
+        private unifiedService: UnifiedPlayerService;
         
         
-        constructor(stateSync: IStateSyncService) {
+        constructor(stateSync: IStateSyncService, widgetService: EnhancedFormUpdateService, unifiedService: UnifiedPlayerService) {
           this.stateSync = stateSync;
           this.stateSync = stateSync;
+          this.widgetService = widgetService;
+          this.unifiedService = unifiedService;
         }
         }
         
         
         onStateChanged(state: PlayerState): void {
         onStateChanged(state: PlayerState): void {
-          this.stateSync.broadcastState(state)
+          this.stateSync.broadcastState(state);
+          // 状态变化时更新卡片
+          this.unifiedService.updateWidgetsForStateChange(state);
         }
         }
         onSongChanged(song: VideoItem): void {
         onSongChanged(song: VideoItem): void {
-          this.stateSync.broadcastSongChange(song)
+          this.stateSync.broadcastSongChange(song);
+          // 歌曲变化时更新卡片
+          this.unifiedService.updateWidgetsForSongChange(song);
         }
         }
         onProgressChanged(progress: PlayProgress): void {
         onProgressChanged(progress: PlayProgress): void {
-          this.stateSync.broadcastProgress(progress)
+          this.stateSync.broadcastProgress(progress);
+          // 进度变化时更新卡片(防抖处理)
+          this.unifiedService.updateWidgetsForProgressChange(progress);
         }
         }
         onError(error: PlayerError): void {
         onError(error: PlayerError): void {
           LogUtils.getInstance().LOGI(`Player error: ${error.message}`);
           LogUtils.getInstance().LOGI(`Player error: ${error.message}`);
         }
         }
       }
       }
-      const stateListener = new StateListenerImpl(this.stateSync);
+      const stateListener = new StateListenerImpl(this.stateSync, this.widgetUpdateService, this);
       this.stateModel.addStateListener(stateListener);
       this.stateModel.addStateListener(stateListener);
       
       
       // 恢复保存的状态
       // 恢复保存的状态
@@ -213,6 +230,10 @@ async initialize(context: common.UIAbilityContext): Promise<void> {
         
         
         // 保存播放状态变化
         // 保存播放状态变化
         this.saveCurrentState();
         this.saveCurrentState();
+        
+        // 更新卡片显示播放状态
+        await this.updateWidgetsForPlayStateChange(true);
+        
         return;
         return;
       }
       }
 
 
@@ -270,6 +291,9 @@ async initialize(context: common.UIAbilityContext): Promise<void> {
       // 保存播放状态变化
       // 保存播放状态变化
       this.saveCurrentState();
       this.saveCurrentState();
       
       
+      // 更新卡片显示暂停状态
+      await this.updateWidgetsForPlayStateChange(false);
+      
       LogUtils.getInstance().LOGI('UnifiedPlayerService: Playback paused');
       LogUtils.getInstance().LOGI('UnifiedPlayerService: Playback paused');
     } catch (error) {
     } catch (error) {
       LogUtils.getInstance().LOGI(`UnifiedPlayerService pause error: ${error}`);
       LogUtils.getInstance().LOGI(`UnifiedPlayerService pause error: ${error}`);
@@ -341,6 +365,8 @@ async initialize(context: common.UIAbilityContext): Promise<void> {
       const currentSong = this.playlistModel.getCurrentSong();
       const currentSong = this.playlistModel.getCurrentSong();
       if (currentSong) {
       if (currentSong) {
         this.stateModel.updateCurrentSong(currentSong);
         this.stateModel.updateCurrentSong(currentSong);
+        // 强制更新卡片显示新歌曲(重要事件)
+        await this.updateWidgetsForSongChange(currentSong, true);
       }
       }
       
       
       LogUtils.getInstance().LOGI('UnifiedPlayerService: Moved to next song');
       LogUtils.getInstance().LOGI('UnifiedPlayerService: Moved to next song');
@@ -378,6 +404,8 @@ async initialize(context: common.UIAbilityContext): Promise<void> {
       const currentSong = this.playlistModel.getCurrentSong();
       const currentSong = this.playlistModel.getCurrentSong();
       if (currentSong) {
       if (currentSong) {
         this.stateModel.updateCurrentSong(currentSong);
         this.stateModel.updateCurrentSong(currentSong);
+        // 强制更新卡片显示新歌曲(重要事件)
+        await this.updateWidgetsForSongChange(currentSong, true);
       }
       }
       
       
       LogUtils.getInstance().LOGI('UnifiedPlayerService: Moved to previous song');
       LogUtils.getInstance().LOGI('UnifiedPlayerService: Moved to previous song');
@@ -472,6 +500,9 @@ async initialize(context: common.UIAbilityContext): Promise<void> {
     // 同步到持久化存储
     // 同步到持久化存储
     this.syncPlaylistToStorage();
     this.syncPlaylistToStorage();
     
     
+    // 更新卡片显示播放列表变化
+    this.updateWidgetsForPlaylistChange();
+    
     LogUtils.getInstance().LOGI(`UnifiedPlayerService: Playlist set with ${songs.length} songs`);
     LogUtils.getInstance().LOGI(`UnifiedPlayerService: Playlist set with ${songs.length} songs`);
   }
   }
 
 
@@ -484,6 +515,9 @@ async initialize(context: common.UIAbilityContext): Promise<void> {
     // 同步到持久化存储
     // 同步到持久化存储
     this.syncPlaylistToStorage();
     this.syncPlaylistToStorage();
     
     
+    // 更新卡片显示播放列表变化
+    this.updateWidgetsForPlaylistChange();
+    
     LogUtils.getInstance().LOGI(`UnifiedPlayerService: Song added to playlist`);
     LogUtils.getInstance().LOGI(`UnifiedPlayerService: Song added to playlist`);
   }
   }
 
 
@@ -502,6 +536,9 @@ async initialize(context: common.UIAbilityContext): Promise<void> {
       // 同步到持久化存储
       // 同步到持久化存储
       this.syncPlaylistToStorage();
       this.syncPlaylistToStorage();
       
       
+      // 更新卡片显示播放列表变化
+      this.updateWidgetsForPlaylistChange();
+      
       LogUtils.getInstance().LOGI(`UnifiedPlayerService: Song removed from playlist at index ${index}`);
       LogUtils.getInstance().LOGI(`UnifiedPlayerService: Song removed from playlist at index ${index}`);
     }
     }
     return removedSong;
     return removedSong;
@@ -1207,6 +1244,8 @@ async initialize(context: common.UIAbilityContext): Promise<void> {
   onPrepared(): void {
   onPrepared(): void {
     LogUtils.getInstance().LOGI('UnifiedPlayerService: Player prepared');
     LogUtils.getInstance().LOGI('UnifiedPlayerService: Player prepared');
     this.stateModel.updateLoadingState(false);
     this.stateModel.updateLoadingState(false);
+    // 播放器准备完成时更新卡片(移除加载状态)
+    this.updateWidgetsForStateChange(this.stateModel.getState());
   }
   }
 
 
   onPlaybackStarted(): void {
   onPlaybackStarted(): void {
@@ -1216,6 +1255,9 @@ async initialize(context: common.UIAbilityContext): Promise<void> {
     
     
     // 保存播放状态变化
     // 保存播放状态变化
     this.saveCurrentState();
     this.saveCurrentState();
+    
+    // 播放开始时更新卡片显示播放状态
+    this.updateWidgetsForPlayStateChange(true);
   }
   }
 
 
   onPlaybackCompleted(): void {
   onPlaybackCompleted(): void {
@@ -1226,6 +1268,9 @@ async initialize(context: common.UIAbilityContext): Promise<void> {
     // 保存播放状态变化
     // 保存播放状态变化
     this.saveCurrentState();
     this.saveCurrentState();
     
     
+    // 更新卡片显示播放完成状态
+    this.updateWidgetsForPlayStateChange(false);
+    
     // 自动播放下一首(如果有的话)
     // 自动播放下一首(如果有的话)
     const currentPlayMode = this.stateModel.getState().playMode;
     const currentPlayMode = this.stateModel.getState().playMode;
     if (this.playlistModel.hasNext(currentPlayMode)) {
     if (this.playlistModel.hasNext(currentPlayMode)) {
@@ -1270,4 +1315,188 @@ async initialize(context: common.UIAbilityContext): Promise<void> {
       LogUtils.getInstance().LOGI(`UnifiedPlayerService: Error recovery failed: ${recoveryError}`);
       LogUtils.getInstance().LOGI(`UnifiedPlayerService: Error recovery failed: ${recoveryError}`);
     });
     });
   }
   }
+
+  // ========== 卡片更新相关方法 ==========
+
+  /**
+   * 创建当前的卡片数据
+   */
+  private createWidgetData(): WidgetData {
+    const currentState = this.stateModel.getState();
+    const currentSong = this.playlistModel.getCurrentSong();
+    const currentIndex = this.playlistModel.getCurrentIndex();
+    const totalCount = this.playlistModel.getTotalCount();
+    const playMode = currentState.playMode;
+
+    return {
+      playState: {
+        isPlaying: currentState.isPlaying,
+        isPaused: currentState.isPaused,
+        isLoading: currentState.isLoading
+      },
+      currentSong: {
+        id: currentSong?.id || '',
+        title: currentSong?.name || '暂无播放',
+        artist: currentSong?.artist || '未知艺术家',
+        album: currentSong?.album || '未知专辑',
+        coverImagePath: currentSong?.pixelMapPath || '',
+        duration: this.parseDuration(currentSong?.duration || '0')
+      },
+      progress: {
+        currentPosition: currentState.currentPosition,
+        duration: currentState.duration,
+        percentage: currentState.duration > 0 ? (currentState.currentPosition / currentState.duration) * 100 : 0,
+        currentTimeText: this.formatTime(currentState.currentPosition),
+        totalTimeText: this.formatTime(currentState.duration)
+      },
+      playlist: {
+        hasNext: this.playlistModel.hasNext(playMode),
+        hasPrevious: this.playlistModel.hasPrevious(playMode),
+        currentIndex: currentIndex,
+        totalCount: totalCount
+      },
+      config: {
+        size: WidgetSize.MEDIUM, // 默认尺寸,实际会根据卡片尺寸适配
+        theme: WidgetTheme.AUTO,
+        showProgress: true,
+        showCover: true
+      }
+    };
+  }
+
+  /**
+   * 播放状态变化时更新卡片
+   */
+  private async updateWidgetsForPlayStateChange(isPlaying: boolean): Promise<void> {
+    try {
+      const widgetData = this.createWidgetData();
+      await this.widgetUpdateService.updateAllForms(widgetData);
+      LogUtils.getInstance().LOGI(`UnifiedPlayerService: Widgets updated for play state change (isPlaying: ${isPlaying})`);
+    } catch (error) {
+      LogUtils.getInstance().LOGI(`UnifiedPlayerService: Failed to update widgets for play state change: ${error}`);
+    }
+  }
+
+  /**
+   * 歌曲变化时更新卡片
+   */
+  private async updateWidgetsForSongChange(song: VideoItem, forceUpdate: boolean = false): Promise<void> {
+    try {
+      const widgetData = this.createWidgetData();
+      
+      if (forceUpdate) {
+        // 强制更新(忽略防抖),用于重要事件如歌曲切换
+        await this.widgetUpdateService.forceUpdateAllForms(widgetData);
+        LogUtils.getInstance().LOGI(`UnifiedPlayerService: Widgets force updated for song change: ${song.name}`);
+      } else {
+        await this.widgetUpdateService.updateAllForms(widgetData);
+        LogUtils.getInstance().LOGI(`UnifiedPlayerService: Widgets updated for song change: ${song.name}`);
+      }
+    } catch (error) {
+      LogUtils.getInstance().LOGI(`UnifiedPlayerService: Failed to update widgets for song change: ${error}`);
+    }
+  }
+
+  /**
+   * 进度变化时更新卡片(防抖处理)
+   */
+  private async updateWidgetsForProgressChange(progress: PlayProgress): Promise<void> {
+    try {
+      // 进度更新很频繁,让防抖机制发挥作用
+      const widgetData = this.createWidgetData();
+      await this.widgetUpdateService.updateAllForms(widgetData);
+      // 不记录日志,避免过多输出
+    } catch (error) {
+      // 进度更新失败不影响播放,只记录错误
+      LogUtils.getInstance().LOGI(`UnifiedPlayerService: Failed to update widgets for progress change: ${error}`);
+    }
+  }
+
+  /**
+   * 状态变化时更新卡片
+   */
+  public async updateWidgetsForStateChange(state: PlayerState): Promise<void> {
+    try {
+      const widgetData = this.createWidgetData();
+      await this.widgetUpdateService.updateAllForms(widgetData);
+      LogUtils.getInstance().LOGI(`UnifiedPlayerService: Widgets updated for state change`);
+    } catch (error) {
+      LogUtils.getInstance().LOGI(`UnifiedPlayerService: Failed to update widgets for state change: ${error}`);
+    }
+  }
+
+  /**
+   * 播放列表变化时更新卡片
+   */
+  private async updateWidgetsForPlaylistChange(): Promise<void> {
+    try {
+      const widgetData = this.createWidgetData();
+      await this.widgetUpdateService.updateAllForms(widgetData);
+      LogUtils.getInstance().LOGI(`UnifiedPlayerService: Widgets updated for playlist change`);
+    } catch (error) {
+      LogUtils.getInstance().LOGI(`UnifiedPlayerService: Failed to update widgets for playlist change: ${error}`);
+    }
+  }
+
+  /**
+   * 应用启动时初始化卡片显示
+   */
+  public async initializeWidgetDisplay(): Promise<void> {
+    try {
+      const widgetData = this.createWidgetData();
+      await this.widgetUpdateService.forceUpdateAllForms(widgetData);
+      LogUtils.getInstance().LOGI('UnifiedPlayerService: Widget display initialized');
+    } catch (error) {
+      LogUtils.getInstance().LOGI(`UnifiedPlayerService: Failed to initialize widget display: ${error}`);
+    }
+  }
+
+  /**
+   * 获取卡片更新统计信息
+   */
+  public getWidgetUpdateStats(): UpdateStats {
+    return this.widgetUpdateService.getUpdateStats();
+  }
+
+  /**
+   * 重置卡片更新统计
+   */
+  public resetWidgetUpdateStats(): void {
+    this.widgetUpdateService.resetStats();
+  }
+
+  /**
+   * 格式化时间为 MM:SS 格式
+   */
+  private formatTime(timeInMs: number): string {
+    const totalSeconds = Math.floor(timeInMs / 1000);
+    const minutes = Math.floor(totalSeconds / 60);
+    const seconds = totalSeconds % 60;
+    return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
+  }
+
+  /**
+   * 解析时长字符串为毫秒数
+   */
+  private parseDuration(durationStr: string): number {
+    if (!durationStr || durationStr === '0') {
+      return 0;
+    }
+    
+    // 如果已经是数字,直接返回
+    const numValue = Number(durationStr);
+    if (!isNaN(numValue)) {
+      return numValue;
+    }
+    
+    // 解析 MM:SS 格式
+    const parts = durationStr.split(':');
+    if (parts.length === 2) {
+      const minutes = parseInt(parts[0]) || 0;
+      const seconds = parseInt(parts[1]) || 0;
+      return (minutes * 60 + seconds) * 1000;
+    }
+    
+    return 0;
+  }
 }
 }

+ 0 - 211
entry/src/main/ets/common/widget/DirectFormUpdateService.ets

@@ -241,217 +241,6 @@ export class DirectFormUpdateService {
     }
     }
   }
   }
 
 
-  /**
-   * 获取当前注册的卡片数量
-   */
-  public async getRegisteredFormCount(): Promise<number> {
-    try {
-      if (!this.appContext) {
-        return 0;
-      }
 
 
-      const prefs = await this.preferencesUtil.getPreferences(this.appContext);
-      const formIds = await this.preferencesUtil.getFormIds(prefs);
-      return formIds.length;
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to get registered form count: ${error}`);
-      return 0;
-    }
-  }
 
 
-  /**
-   * 获取所有注册的 Form ID
-   */
-  public async getRegisteredFormIds(): Promise<string[]> {
-    try {
-      if (!this.appContext) {
-        return [];
-      }
-
-      const prefs = await this.preferencesUtil.getPreferences(this.appContext);
-      return await this.preferencesUtil.getFormIds(prefs);
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to get registered form IDs: ${error}`);
-      return [];
-    }
-  }
-
-  /**
-   * 调试方法:强制刷新所有卡片
-   */
-  public async debugRefreshAllForms(): Promise<void> {
-    try {
-      hilog.info(0x0000, TAG, '🔧 DEBUG: Starting manual refresh of all forms...');
-      
-      if (!this.appContext) {
-        hilog.error(0x0000, TAG, '🔧 DEBUG: App context not available');
-        return;
-      }
-
-      const formIds = await this.getRegisteredFormIds();
-      hilog.info(0x0000, TAG, `🔧 DEBUG: Found ${formIds.length} registered forms: [${formIds.join(', ')}]`);
-
-      if (formIds.length === 0) {
-        hilog.warn(0x0000, TAG, '🔧 DEBUG: No forms to refresh');
-        return;
-      }
-
-      // 创建模拟数据进行测试
-      const testData: WidgetData = {
-        playState: {
-          isPlaying: true,
-          isPaused: false,
-          isLoading: false
-        },
-        currentSong: {
-          id: 'debug-song',
-          title: '调试测试歌曲',
-          artist: '调试艺术家',
-          album: '调试专辑',
-          coverImagePath: '',
-          duration: 180000
-        },
-        progress: {
-          currentPosition: 60000,
-          duration: 180000,
-          percentage: 33.33,
-          currentTimeText: '01:00',
-          totalTimeText: '03:00'
-        },
-        playlist: {
-          hasNext: true,
-          hasPrevious: true,
-          currentIndex: 1,
-          totalCount: 5
-        },
-        config: {
-          size: 'medium',
-          theme: 'auto',
-          showProgress: true,
-          showCover: true
-        }
-      };
-
-      await this.updateAllForms(testData);
-      hilog.info(0x0000, TAG, '🔧 DEBUG: Manual refresh completed');
-
-    } catch (error) {
-      hilog.error(0x0000, TAG, `🔧 DEBUG: Manual refresh failed: ${error}`);
-    }
-  }
-
-  /**
-   * 验证和清理所有无效的 Form ID
-   */
-  public async validateAndCleanupForms(): Promise<void> {
-    try {
-      hilog.info(0x0000, TAG, '🔍 Starting Form ID validation...');
-      
-      if (!this.appContext) {
-        hilog.error(0x0000, TAG, '❌ App context not available for validation');
-        return;
-      }
-
-      const prefs = await this.preferencesUtil.getPreferences(this.appContext);
-      const formIds = await this.preferencesUtil.getFormIds(prefs);
-      
-      hilog.info(0x0000, TAG, `🔍 Validating ${formIds.length} Form IDs: [${formIds.join(', ')}]`);
-
-      if (formIds.length === 0) {
-        hilog.info(0x0000, TAG, '✅ No Form IDs to validate');
-        return;
-      }
-
-      // 尝试获取每个 Form 的信息来验证其有效性
-      const validationPromises = formIds.map(async (formId): Promise<FormValidationResult> => {
-        try {
-          // 尝试创建一个简单的数据来测试 Form 是否存在
-          const testFormData: TestFormData = { test: 'validation' };
-          const testData = formBindingData.createFormBindingData(testFormData);
-          await formProvider.updateForm(formId, testData);
-          hilog.info(0x0000, TAG, `✅ Form ${formId} is valid`);
-          
-          const result: FormValidationResult = { formId, isValid: true, error: null };
-          return result;
-        } catch (error) {
-          hilog.warn(0x0000, TAG, `❌ Form ${formId} validation failed: ${JSON.stringify(error)}`);
-          
-          const result: FormValidationResult = { formId, isValid: false, error: error as Error };
-          return result;
-        }
-      });
-
-      const validationResults = await Promise.allSettled(validationPromises);
-      const invalidFormIds: string[] = [];
-
-      validationResults.forEach((result, index) => {
-        if (result.status === 'fulfilled') {
-          if (!result.value.isValid) {
-            const error = result.value.error?.message as string;
-            if (error.includes('16501001')) {
-              hilog.info(0x0000, TAG, `🗑️ Form ${result.value.formId} is invalid (error code: 16501001), marking for removal`);
-              invalidFormIds.push(result.value.formId);
-            }
-          }
-        } else {
-          hilog.error(0x0000, TAG, `⚠️ Validation promise failed for form ${formIds[index]}: ${result.reason}`);
-        }
-      });
-
-      // 清理无效的 Form ID
-      if (invalidFormIds.length > 0) {
-        hilog.info(0x0000, TAG, `🧹 Cleaning up ${invalidFormIds.length} invalid Form IDs: [${invalidFormIds.join(', ')}]`);
-        
-        for (const invalidFormId of invalidFormIds) {
-          await this.preferencesUtil.removeFormId(prefs, invalidFormId);
-        }
-        
-        const remainingFormIds = await this.preferencesUtil.getFormIds(prefs);
-        hilog.info(0x0000, TAG, `✅ Cleanup completed. Remaining valid forms: ${remainingFormIds.length} [${remainingFormIds.join(', ')}]`);
-      } else {
-        hilog.info(0x0000, TAG, '✅ All Form IDs are valid');
-      }
-
-    } catch (error) {
-      hilog.error(0x0000, TAG, `❌ Form validation failed: ${error}`);
-    }
-  }
-
-  /**
-   * 调试方法:显示当前持久化存储状态
-   */
-  public async debugShowPersistenceStatus(): Promise<void> {
-    try {
-      hilog.info(0x0000, TAG, '🔧 DEBUG: Checking persistence status...');
-      
-      if (!this.appContext) {
-        hilog.error(0x0000, TAG, '🔧 DEBUG: App context not available');
-        return;
-      }
-
-      const prefs = await this.preferencesUtil.getPreferences(this.appContext);
-      const formIds = await this.preferencesUtil.getFormIds(prefs);
-      
-      hilog.info(0x0000, TAG, `🔧 DEBUG: Current Form IDs in storage: ${formIds.length}`);
-      
-      if (formIds.length > 0) {
-        hilog.info(0x0000, TAG, `🔧 DEBUG: Form IDs: [${formIds.join(', ')}]`);
-        
-        // 检查每个 Form ID 的状态
-        for (const formId of formIds) {
-          const formState = await this.preferencesUtil.getFormState(prefs, formId);
-          hilog.info(0x0000, TAG, `🔧 DEBUG: Form ${formId} state: ${JSON.stringify(formState)}`);
-        }
-      } else {
-        hilog.warn(0x0000, TAG, '🔧 DEBUG: No Form IDs found in storage!');
-        hilog.info(0x0000, TAG, '🔧 DEBUG: This means either:');
-        hilog.info(0x0000, TAG, '🔧 DEBUG: 1. No widgets have been added');
-        hilog.info(0x0000, TAG, '🔧 DEBUG: 2. Widget addition failed to save Form IDs');
-        hilog.info(0x0000, TAG, '🔧 DEBUG: 3. All Form IDs were cleaned up due to invalid widgets');
-      }
-
-    } catch (error) {
-      hilog.error(0x0000, TAG, `🔧 DEBUG: Persistence status check failed: ${error}`);
-    }
-  }
 }
 }

+ 673 - 0
entry/src/main/ets/common/widget/EnhancedFormUpdateService.ets

@@ -0,0 +1,673 @@
+import { hilog } from '@kit.PerformanceAnalysisKit';
+import { formProvider, formBindingData } from '@kit.FormKit';
+import { preferences } from '@kit.ArkData';
+import { Context } from '@kit.AbilityKit';
+import { WidgetData, FormattedWidgetData, WidgetSize } from './WidgetTypes';
+import { FormLayoutManager } from './FormLayoutManager';
+import { PreferencesUtil } from '../utils/PreferencesUtil';
+import { GlobalWidgetManager } from './GlobalWidgetManager';
+import { fileIo } from '@kit.CoreFileKit';
+import { http } from '@kit.NetworkKit';
+
+const TAG = 'EnhancedFormUpdateService';
+
+/**
+ * 表单状态数据接口
+ */
+interface FormStateData extends Record<string, string | number | boolean | Uint8Array> {
+  size: string;
+  lastUpdate: number;
+  lastSongId: string;
+  updateCount: number;
+  lastImageUrl: string;
+}
+
+/**
+ * 更新结果接口
+ */
+interface UpdateResult {
+  formId: string;
+  success: boolean;
+  error?: Error;
+  updateTime: number;
+  retryCount: number;
+}
+
+/**
+ * 批量更新统计
+ */
+interface BatchUpdateStats {
+  total: number;
+  success: number;
+  failed: number;
+  duration: number;
+  averageUpdateTime: number;
+}
+
+/**
+ * 网络图片缓存项
+ */
+interface ImageCacheItem {
+  fileName: string;
+  downloadTime: number;
+  expiry: number;
+  fileSize: number;
+}
+
+/**
+ * 更新统计接口
+ */
+export interface UpdateStats {
+  totalUpdates: number;
+  successfulUpdates: number;
+  failedUpdates: number;
+  averageUpdateTime: number;
+  lastBatchStats?: BatchUpdateStats;
+}
+
+/**
+ * 增强版卡片更新服务
+ * 在原有DirectFormUpdateService基础上添加了以下功能:
+ * 1. 智能重试机制
+ * 2. 网络图片缓存
+ * 3. 批量更新统计
+ * 4. 性能监控
+ * 5. 错误恢复
+ */
+export class EnhancedFormUpdateService {
+  private static instance: EnhancedFormUpdateService | null = null;
+  private layoutManager: FormLayoutManager = FormLayoutManager.getInstance();
+  private preferencesUtil: PreferencesUtil = PreferencesUtil.getInstance();
+  private globalWidgetManager: GlobalWidgetManager = GlobalWidgetManager.getInstance();
+  private appContext: Context | null = null;
+
+  // 防抖和节流
+  private lastUpdateTime: number = 0;
+  private updateDebounceDelay: number = 100; // 100ms防抖延迟
+  private isUpdating: boolean = false;
+
+  // 重试配置
+  private readonly maxRetryCount: number = 3;
+  private readonly retryDelays: number[] = [500, 1000, 2000]; // 递增重试延迟
+
+  // 网络图片缓存
+  private imageCache: Map<string, ImageCacheItem> = new Map();
+  private downloadingImages: Map<string, Promise<string | null>> = new Map();
+  private readonly imageCacheExpiry: number = 24 * 60 * 60 * 1000; // 24小时
+  private readonly maxCacheSize: number = 50; // 最多缓存50张图片
+
+  // 性能统计
+  private updateStats: UpdateStats = {
+    totalUpdates: 0,
+    successfulUpdates: 0,
+    failedUpdates: 0,
+    averageUpdateTime: 0
+  };
+
+  private constructor() {}
+
+  public static getInstance(): EnhancedFormUpdateService {
+    if (!EnhancedFormUpdateService.instance) {
+      EnhancedFormUpdateService.instance = new EnhancedFormUpdateService();
+    }
+    return EnhancedFormUpdateService.instance;
+  }
+
+  /**
+   * 设置应用上下文
+   */
+  public setAppContext(context: Context): void {
+    this.appContext = context;
+    hilog.info(0x0000, TAG, '🎯 App context set for EnhancedFormUpdateService');
+    this.initializeImageCache();
+  }
+
+  /**
+   * 主要的更新所有卡片方法 - 参考原DirectFormUpdateService.updateAllForms()
+   */
+  public async updateAllForms(data: WidgetData): Promise<BatchUpdateStats> {
+    const batchStartTime = Date.now();
+    
+    try {
+      if (!this.appContext) {
+        hilog.error(0x0000, TAG, '❌ App context not set, cannot update forms');
+        throw new Error('App context not set');
+      }
+
+      // 防抖检查
+      const now = Date.now();
+      if (now - this.lastUpdateTime < this.updateDebounceDelay) {
+        hilog.info(0x0000, TAG, `⏭️ Update debounced, skipping (${now - this.lastUpdateTime}ms since last update)`);
+        return this.createEmptyStats();
+      }
+
+      // 防止并发更新
+      if (this.isUpdating) {
+        hilog.warn(0x0000, TAG, '⚠️ Update already in progress, skipping this request');
+        return this.createEmptyStats();
+      }
+
+      this.isUpdating = true;
+      this.lastUpdateTime = now;
+
+      hilog.info(0x0000, TAG, `🚀 Starting enhanced batch form update: isPlaying=${data.playState.isPlaying}, title="${data.currentSong.title}"`);
+
+      // 获取所有持久化的 Form ID(使用原有方法)
+      const prefs = await this.preferencesUtil.getPreferences(this.appContext);
+      const formIds = await this.preferencesUtil.getFormIds(prefs);
+
+      if (formIds.length === 0) {
+        hilog.info(0x0000, TAG, '📋 No forms found in persistence, skipping update');
+        return this.createEmptyStats();
+      }
+
+      hilog.info(0x0000, TAG, `📋 Found ${formIds.length} forms to update: [${formIds.join(', ')}]`);
+
+      // 验证活跃卡片与持久化卡片的一致性
+      await this.validateActiveWidgets(formIds, prefs);
+
+      // 并行更新所有卡片
+      const updatePromises = formIds.map((formId, index) => {
+        hilog.info(0x0000, TAG, `🎯 Creating update task ${index + 1}/${formIds.length} for form: ${formId}`);
+        return this.updateSingleFormWithRetry(formId, data, prefs);
+      });
+
+      hilog.info(0x0000, TAG, `⏳ Executing ${updatePromises.length} parallel update tasks...`);
+
+      // 等待所有更新完成
+      const results = await Promise.allSettled(updatePromises);
+
+      // 处理结果并生成统计信息
+      const batchStats = this.processBatchResults(formIds, results, batchStartTime);
+
+      // 清理无效的 Form ID
+      if (batchStats.failed > 0) {
+        await this.cleanupInvalidForms(prefs, formIds, results);
+      }
+
+      // 更新统计信息
+      this.updateStats.lastBatchStats = batchStats;
+      this.updateStats.totalUpdates += batchStats.total;
+      this.updateStats.successfulUpdates += batchStats.success;
+      this.updateStats.failedUpdates += batchStats.failed;
+
+      // 重新计算平均更新时间
+      if (this.updateStats.totalUpdates > 0) {
+        this.updateStats.averageUpdateTime = 
+          (this.updateStats.averageUpdateTime * (this.updateStats.totalUpdates - batchStats.total) + batchStats.averageUpdateTime * batchStats.total) / this.updateStats.totalUpdates;
+      }
+
+      hilog.info(0x0000, TAG, `✅ Batch update completed: ${batchStats.success}/${batchStats.total} successful in ${batchStats.duration}ms (avg: ${batchStats.averageUpdateTime.toFixed(1)}ms per form)`);
+
+      return batchStats;
+
+    } catch (error) {
+      hilog.error(0x0000, TAG, `❌ Failed to update forms: ${error}`);
+      throw new Error(`Failed to update forms: ${error}`);
+    } finally {
+      this.isUpdating = false;
+    }
+  }
+
+  /**
+   * 带重试机制的单个卡片更新
+   */
+  private async updateSingleFormWithRetry(formId: string, data: WidgetData, prefs: preferences.Preferences): Promise<UpdateResult> {
+    const startTime = Date.now();
+    let lastError: Error | null = null;
+
+    for (let attempt = 0; attempt <= this.maxRetryCount; attempt++) {
+      try {
+        if (attempt > 0) {
+          const delay = this.retryDelays[Math.min(attempt - 1, this.retryDelays.length - 1)];
+          hilog.info(0x0000, TAG, `🔄 [${formId}] Retry attempt ${attempt}/${this.maxRetryCount} after ${delay}ms delay`);
+          await this.sleep(delay);
+        }
+
+        await this.updateSingleForm(formId, data, prefs);
+        
+        const updateTime = Date.now() - startTime;
+        hilog.info(0x0000, TAG, `✅ [${formId}] Update successful on attempt ${attempt + 1} (${updateTime}ms)`);
+        
+        return {
+          formId,
+          success: true,
+          updateTime,
+          retryCount: attempt
+        };
+
+      } catch (error) {
+        lastError = error as Error;
+        hilog.warn(0x0000, TAG, `⚠️ [${formId}] Update attempt ${attempt + 1} failed: ${lastError.message}`);
+      }
+    }
+
+    const updateTime = Date.now() - startTime;
+    hilog.error(0x0000, TAG, `❌ [${formId}] All ${this.maxRetryCount + 1} attempts failed (${updateTime}ms total)`);
+    
+    return {
+      formId,
+      success: false,
+      error: lastError || new Error('Unknown error'),
+      updateTime,
+      retryCount: this.maxRetryCount
+    };
+  }
+
+  /**
+   * 更新单个卡片(增强版,参考原有方法)
+   */
+  private async updateSingleForm(formId: string, data: WidgetData, prefs: preferences.Preferences): Promise<void> {
+    try {
+      hilog.info(0x0000, TAG, `🎯 [${formId}] Starting enhanced form update...`);
+
+      // 获取卡片的当前状态
+      const formState = await this.preferencesUtil.getFormState(prefs, formId);
+      const widgetSizeStr = (formState?.size as string) || 'medium';
+      const widgetSize: WidgetSize = widgetSizeStr as WidgetSize;
+
+      hilog.info(0x0000, TAG, `🎯 [${formId}] Widget size: ${widgetSizeStr}`);
+
+      // 适配数据到卡片尺寸
+      const adaptedData = this.layoutManager.adaptDataForSize(data, widgetSize);
+
+      // 处理网络图片
+      await this.handleNetworkImage(adaptedData);
+
+      // 转换为 FormattedWidgetData
+      const formattedData: FormattedWidgetData = {
+        isPlaying: adaptedData.isPlaying,
+        isPaused: adaptedData.isPaused,
+        isLoading: adaptedData.isLoading,
+        songTitle: adaptedData.songTitle,
+        songArtist: adaptedData.songArtist,
+        songAlbum: adaptedData.songAlbum,
+        coverImage: adaptedData.coverImage,
+        currentTime: adaptedData.currentTime,
+        totalTime: adaptedData.totalTime,
+        progressPercentage: adaptedData.progressPercentage,
+        hasNext: adaptedData.hasNext,
+        hasPrevious: adaptedData.hasPrevious,
+        showProgress: adaptedData.showProgress,
+        showCover: adaptedData.showCover,
+        widgetSize: adaptedData.widgetSize,
+        timestamp: Date.now(),
+        imgName: adaptedData.imgName || ''
+      };
+
+      hilog.info(0x0000, TAG, `🎯 [${formId}] Formatted data prepared: isPlaying=${formattedData.isPlaying}, title="${formattedData.songTitle}"`);
+
+      // 创建 FormBindingData 并更新卡片
+      const formData = formBindingData.createFormBindingData(formattedData);
+      await formProvider.updateForm(formId, formData);
+      
+      hilog.info(0x0000, TAG, `✅ [${formId}] Form updated successfully`);
+
+      // 保存增强状态信息
+      await this.saveEnhancedFormState(prefs, formId, widgetSizeStr, data);
+
+    } catch (error) {
+      hilog.error(0x0000, TAG, `❌ [${formId}] Failed to update form: ${error}`);
+      throw new Error(`Failed to update form ${formId}: ${error}`);
+    }
+  }
+
+  /**
+   * 处理网络图片(缓存 + 下载)
+   */
+  private async handleNetworkImage(adaptedData: FormattedWidgetData): Promise<void> {
+    if (!adaptedData.coverImage || !this.isNetworkUrl(adaptedData.coverImage)) {
+      return;
+    }
+
+    try {
+      const imageUrl = adaptedData.coverImage;
+      hilog.info(0x0000, TAG, `🖼️ Processing network image: ${imageUrl}`);
+
+      // 检查缓存
+      const cachedItem = this.imageCache.get(imageUrl);
+      if (cachedItem && cachedItem.expiry > Date.now()) {
+        hilog.info(0x0000, TAG, `📸 Using cached image: ${cachedItem.fileName}`);
+        adaptedData.coverImage = `memory://${cachedItem.fileName}`;
+        adaptedData.imgName = cachedItem.fileName;
+        return;
+      }
+
+      // 下载图片
+      const fileName = await this.downloadAndCacheImage(imageUrl);
+      if (fileName) {
+        adaptedData.coverImage = `memory://${fileName}`;
+        adaptedData.imgName = fileName;
+        hilog.info(0x0000, TAG, `📸 Network image processed: ${fileName}`);
+      } else {
+        // 下载失败,清除图片
+        adaptedData.coverImage = '';
+        adaptedData.imgName = '';
+        hilog.warn(0x0000, TAG, `⚠️ Failed to download image, using default`);
+      }
+
+    } catch (error) {
+      hilog.error(0x0000, TAG, `❌ Error processing network image: ${error}`);
+      adaptedData.coverImage = '';
+      adaptedData.imgName = '';
+    }
+  }
+
+  /**
+   * 下载并缓存网络图片
+   */
+  private async downloadAndCacheImage(imageUrl: string): Promise<string | null> {
+    // 检查是否正在下载
+    if (this.downloadingImages.has(imageUrl)) {
+      hilog.info(0x0000, TAG, `⏳ Image already downloading: ${imageUrl}`);
+      return await this.downloadingImages.get(imageUrl)!;
+    }
+
+    // 创建下载Promise
+    const downloadPromise = this.performImageDownload(imageUrl);
+    this.downloadingImages.set(imageUrl, downloadPromise);
+
+    try {
+      const result = await downloadPromise;
+      return result;
+    } finally {
+      this.downloadingImages.delete(imageUrl);
+    }
+  }
+
+  /**
+   * 执行图片下载
+   */
+  private async performImageDownload(imageUrl: string): Promise<string | null> {
+    try {
+      hilog.info(0x0000, TAG, `📥 Downloading image: ${imageUrl}`);
+      
+      const httpRequest = http.createHttp();
+      const response = await httpRequest.request(imageUrl, {
+        method: http.RequestMethod.GET,
+        connectTimeout: 10000,
+        readTimeout: 10000
+      });
+
+      if (response.responseCode !== 200) {
+        throw new Error(`HTTP ${response.responseCode}`);
+      }
+
+      // 生成文件名
+      const fileName = `widget_cover_${Date.now()}_${Math.random().toString(36).substr(2, 9)}.jpg`;
+      
+      // 保存到缓存目录
+      const filePath = `${this.appContext!.cacheDir}/${fileName}`;
+      const file = fileIo.openSync(filePath, fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE_ONLY);
+      
+      const buffer = response.result as ArrayBuffer;
+      fileIo.writeSync(file.fd, new Uint8Array(buffer));
+      fileIo.closeSync(file);
+
+      // 添加到缓存
+      const cacheItem: ImageCacheItem = {
+        fileName,
+        downloadTime: Date.now(),
+        expiry: Date.now() + this.imageCacheExpiry,
+        fileSize: buffer.byteLength
+      };
+      
+      this.imageCache.set(imageUrl, cacheItem);
+      this.cleanupImageCache();
+
+      hilog.info(0x0000, TAG, `✅ Image downloaded and cached: ${fileName} (${buffer.byteLength} bytes)`);
+      
+      httpRequest.destroy();
+      return fileName;
+
+    } catch (error) {
+      hilog.error(0x0000, TAG, `❌ Failed to download image: ${error}`);
+      return null;
+    }
+  }
+
+  /**
+   * 清理图片缓存
+   */
+  private cleanupImageCache(): void {
+    if (this.imageCache.size <= this.maxCacheSize) {
+      return;
+    }
+
+    // 按下载时间排序,删除最旧的
+    const sortedItems = Array.from(this.imageCache.entries())
+      .sort((a, b) => a[1].downloadTime - b[1].downloadTime);
+
+    const itemsToDelete = sortedItems.slice(0, this.imageCache.size - this.maxCacheSize);
+    
+    for (let i = 0; i < itemsToDelete.length; i++) {
+      try {
+        const entry = itemsToDelete[i];
+        const url = entry[0];
+        const item = entry[1];
+        const filePath = `${this.appContext!.cacheDir}/${item.fileName}`;
+        if (fileIo.accessSync(filePath)) {
+          fileIo.unlinkSync(filePath);
+        }
+        this.imageCache.delete(url);
+        hilog.info(0x0000, TAG, `🗑️ Cleaned up cached image: ${item.fileName}`);
+      } catch (error) {
+        hilog.warn(0x0000, TAG, `⚠️ Failed to cleanup image: ${error}`);
+      }
+    }
+  }
+
+  /**
+   * 初始化图片缓存
+   */
+  private initializeImageCache(): void {
+    // 清理过期的缓存文件
+    try {
+      const cacheDir = this.appContext!.cacheDir;
+      const files = fileIo.listFileSync(cacheDir);
+      
+      for (const file of files) {
+        if (file.startsWith('widget_cover_')) {
+          const filePath = `${cacheDir}/${file}`;
+          const stat = fileIo.statSync(filePath);
+          
+          // 删除超过24小时的文件
+          if (Date.now() - stat.mtime > this.imageCacheExpiry) {
+            fileIo.unlinkSync(filePath);
+            hilog.info(0x0000, TAG, `🗑️ Cleaned up expired cache file: ${file}`);
+          }
+        }
+      }
+    } catch (error) {
+      hilog.warn(0x0000, TAG, `⚠️ Failed to cleanup cache directory: ${error}`);
+    }
+  }
+
+  /**
+   * 验证活跃卡片与持久化卡片的一致性
+   */
+  private async validateActiveWidgets(formIds: string[], prefs: preferences.Preferences): Promise<void> {
+    const activeWidgets = this.globalWidgetManager.getActiveWidgets();
+    const activeFormIds = Array.from(activeWidgets.keys());
+
+    hilog.info(0x0000, TAG, `🔍 Validating widgets - Persistent: [${formIds.join(', ')}], Active: [${activeFormIds.join(', ')}]`);
+
+    // 检查持久化但不活跃的卡片
+    const persistentOnlyIds = formIds.filter(id => !activeWidgets.has(id));
+    if (persistentOnlyIds.length > 0) {
+      hilog.warn(0x0000, TAG, `⚠️ Found ${persistentOnlyIds.length} persistent but inactive widgets: [${persistentOnlyIds.join(', ')}]`);
+    }
+
+    // 检查活跃但未持久化的卡片
+    const activeOnlyIds = activeFormIds.filter(id => !formIds.includes(id));
+    if (activeOnlyIds.length > 0) {
+      hilog.warn(0x0000, TAG, `⚠️ Found ${activeOnlyIds.length} active but not persistent widgets: [${activeOnlyIds.join(', ')}]`);
+      
+      // 将活跃的卡片添加到持久化存储
+      for (const formId of activeOnlyIds) {
+        await this.preferencesUtil.addFormId(prefs, formId);
+        hilog.info(0x0000, TAG, `➕ Added missing form ID to persistence: ${formId}`);
+      }
+    }
+  }
+
+  /**
+   * 保存增强的表单状态
+   */
+  private async saveEnhancedFormState(prefs: preferences.Preferences, formId: string, widgetSize: string, data: WidgetData): Promise<void> {
+    try {
+      const existingState = await this.preferencesUtil.getFormState(prefs, formId) as FormStateData | null;
+      const updateCount = (existingState?.updateCount as number || 0) + 1;
+
+      const stateData: FormStateData = {
+        size: widgetSize,
+        lastUpdate: Date.now(),
+        lastSongId: data.currentSong.id,
+        updateCount: updateCount,
+        lastImageUrl: data.currentSong.coverImagePath || ''
+      };
+
+      await this.preferencesUtil.saveFormState(prefs, formId, stateData);
+      hilog.info(0x0000, TAG, `💾 [${formId}] Enhanced form state saved (update #${updateCount})`);
+    } catch (error) {
+      hilog.warn(0x0000, TAG, `⚠️ [${formId}] Failed to save enhanced form state: ${error}`);
+    }
+  }
+
+  /**
+   * 处理批量更新结果
+   */
+  private processBatchResults(formIds: string[], results: PromiseSettledResult<UpdateResult>[], startTime: number): BatchUpdateStats {
+    const duration = Date.now() - startTime;
+    let successCount = 0;
+    let failedCount = 0;
+    let totalUpdateTime = 0;
+
+    results.forEach((result, index) => {
+      const formId = formIds[index];
+      
+      if (result.status === 'fulfilled') {
+        const updateResult = result.value;
+        if (updateResult.success) {
+          successCount++;
+          totalUpdateTime += updateResult.updateTime;
+          hilog.info(0x0000, TAG, `✅ Form ${index + 1}/${formIds.length} (${formId}) updated successfully in ${updateResult.updateTime}ms (${updateResult.retryCount} retries)`);
+        } else {
+          failedCount++;
+          hilog.error(0x0000, TAG, `❌ Form ${index + 1}/${formIds.length} (${formId}) failed: ${updateResult.error?.message}`);
+        }
+      } else {
+        failedCount++;
+        hilog.error(0x0000, TAG, `❌ Form ${index + 1}/${formIds.length} (${formId}) promise rejected: ${result.reason}`);
+      }
+    });
+
+    const averageUpdateTime = successCount > 0 ? totalUpdateTime / successCount : 0;
+
+    return {
+      total: formIds.length,
+      success: successCount,
+      failed: failedCount,
+      duration,
+      averageUpdateTime
+    };
+  }
+
+  /**
+   * 清理无效的 Form ID(参考原有方法)
+   */
+  private async cleanupInvalidForms(prefs: preferences.Preferences, formIds: string[], results: PromiseSettledResult<UpdateResult>[]): Promise<void> {
+    try {
+      const invalidFormIds: string[] = [];
+
+      results.forEach((result: PromiseSettledResult<UpdateResult>, index: number) => {
+        if (result.status === 'fulfilled' && !result.value.success) {
+          const error = result.value.error!;
+          const errorStr = error.toString();
+          const formId = formIds[index];
+          
+          hilog.warn(0x0000, TAG, `🔍 Analyzing error for form ${formId}: ${errorStr}`);
+          
+          if (errorStr.includes('form not exist') || 
+              errorStr.includes('16501001') ||
+              errorStr.includes('FormProvider') ||
+              errorStr.includes('invalid form')) {
+            hilog.warn(0x0000, TAG, `🗑️ Form ${formId} appears to be invalid, marking for cleanup`);
+            invalidFormIds.push(formId);
+          }
+        }
+      });
+
+      if (invalidFormIds.length > 0) {
+        hilog.info(0x0000, TAG, `🧹 Cleaning up ${invalidFormIds.length} invalid forms: [${invalidFormIds.join(', ')}]`);
+        
+        for (const invalidFormId of invalidFormIds) {
+          await this.preferencesUtil.removeFormId(prefs, invalidFormId);
+          this.globalWidgetManager.unregisterWidget(invalidFormId);
+          hilog.info(0x0000, TAG, `🗑️ Removed invalid form ID: ${invalidFormId}`);
+        }
+        
+        hilog.info(0x0000, TAG, `✅ Invalid forms cleaned up successfully`);
+      }
+    } catch (error) {
+      hilog.error(0x0000, TAG, `❌ Failed to cleanup invalid forms: ${error}`);
+    }
+  }
+
+  /**
+   * 获取更新统计信息
+   */
+  public getUpdateStats(): UpdateStats {
+    const stats: UpdateStats = {
+      totalUpdates: this.updateStats.totalUpdates,
+      successfulUpdates: this.updateStats.successfulUpdates,
+      failedUpdates: this.updateStats.failedUpdates,
+      averageUpdateTime: this.updateStats.averageUpdateTime,
+      lastBatchStats: this.updateStats.lastBatchStats
+    };
+    return stats;
+  }
+
+  /**
+   * 重置统计信息
+   */
+  public resetStats(): void {
+    this.updateStats = {
+      totalUpdates: 0,
+      successfulUpdates: 0,
+      failedUpdates: 0,
+      averageUpdateTime: 0
+    };
+    hilog.info(0x0000, TAG, '📊 Update statistics reset');
+  }
+
+  /**
+   * 强制刷新所有卡片(忽略防抖)
+   */
+  public async forceUpdateAllForms(data: WidgetData): Promise<BatchUpdateStats> {
+    this.lastUpdateTime = 0; // 重置防抖时间
+    return await this.updateAllForms(data);
+  }
+
+  /**
+   * 工具方法
+   */
+  private isNetworkUrl(url: string): boolean {
+    return url.startsWith('http://') || url.startsWith('https://');
+  }
+
+  private sleep(ms: number): Promise<void> {
+    return new Promise(resolve => setTimeout(resolve, ms));
+  }
+
+  private createEmptyStats(): BatchUpdateStats {
+    const emptyStats: BatchUpdateStats = {
+      total: 0,
+      success: 0,
+      failed: 0,
+      duration: 0,
+      averageUpdateTime: 0
+    };
+    return emptyStats;
+  }
+}

+ 0 - 6
entry/src/main/ets/entryability/DemoConstants.ets

@@ -1,6 +0,0 @@
-import { window } from '@kit.ArkUI'
-
-export class DemoConstants {
-
-  static windowStage: window.WindowStage
-}

+ 37 - 48
entry/src/main/ets/entryability/EntryAbility.ets

@@ -13,7 +13,6 @@ import window from '@ohos.window';
 import { AbilityConstant, Want } from '@kit.AbilityKit';
 import { AbilityConstant, Want } from '@kit.AbilityKit';
 import { BusinessError, emitter } from '@kit.BasicServicesKit';
 import { BusinessError, emitter } from '@kit.BasicServicesKit';
 import { AppUtil, ArrayUtil, GlobalContext, LogUtil, StrUtil } from '@pura/harmony-utils';
 import { AppUtil, ArrayUtil, GlobalContext, LogUtil, StrUtil } from '@pura/harmony-utils';
-import { DemoConstants } from './DemoConstants';
 import { rpc } from '@kit.IPCKit';
 import { rpc } from '@kit.IPCKit';
 
 
 import { Utility } from '../common/util/Utility';
 import { Utility } from '../common/util/Utility';
@@ -21,16 +20,8 @@ import { WXApi, WXEventHandler } from '../common/util/WXApiWrap';
 import { UnifiedPlayerService } from '../common/service/UnifiedPlayerService';
 import { UnifiedPlayerService } from '../common/service/UnifiedPlayerService';
 
 
 import { systemShare } from '@kit.ShareKit';
 import { systemShare } from '@kit.ShareKit';
-import Logger from '../common/util/Logger';
-import statusBarManager from '@hms.pcService.statusBarManager';
-import StatusBarViewExtensionAbility from '@hms.pcService.StatusBarViewExtensionAbility';
 import { SpiderMan } from '@simplepeng/spider-man';
 import { SpiderMan } from '@simplepeng/spider-man';
 import { smartMobilityCommon } from '@kit.CarKit';
 import { smartMobilityCommon } from '@kit.CarKit';
-import { url } from '@kit.ArkTS';
-import commonEventManager from '@ohos.commonEventManager';
-import { WIDGET_CONTROL_EVENT } from '../common/widget/WidgetEventConstants';
-import { EventData, WidgetControlParams } from '../common/widget/WidgetTypes';
-import { VideoItem } from '../viewmodel/VideoItem';
 
 
 
 
 /**
 /**
@@ -114,7 +105,7 @@ export default class EntryAbility extends UIAbility {
     async onCreate(want:Want, launchParam:AbilityConstant.LaunchParam) {
     async onCreate(want:Want, launchParam:AbilityConstant.LaunchParam) {
         AppUtil.init(this.context);
         AppUtil.init(this.context);
         AppStorage.setOrCreate('context', this.context);
         AppStorage.setOrCreate('context', this.context);
-        hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
+        hilog.info(0x0000, 'Heanup2', '%{public}s', 'Ability onCreate');
         
         
         // 注册卡片call事件监听器
         // 注册卡片call事件监听器
         this.registerWidgetCallListeners();
         this.registerWidgetCallListeners();
@@ -122,9 +113,9 @@ export default class EntryAbility extends UIAbility {
         // 初始化统一播放器服务(与主应用共享)
         // 初始化统一播放器服务(与主应用共享)
         try {
         try {
             await UnifiedPlayerService.getInstance().initialize(this.context);
             await UnifiedPlayerService.getInstance().initialize(this.context);
-            hilog.info(0x0000, 'testTag', '✅ UnifiedPlayerService initialized successfully');
+            hilog.info(0x0000, 'Heanup2', '✅ UnifiedPlayerService initialized successfully');
         } catch (error) {
         } catch (error) {
-            hilog.error(0x0000, 'testTag', `❌ Failed to initialize UnifiedPlayerService: ${error}`);
+            hilog.error(0x0000, 'Heanup2', `❌ Failed to initialize UnifiedPlayerService: ${error}`);
         }
         }
 
 
         setTimeout(async ()=>{
         setTimeout(async ()=>{
@@ -139,7 +130,7 @@ export default class EntryAbility extends UIAbility {
     }
     }
 
 
     async onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {
     async onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {
-        hilog.info(0x0000, 'testTag', `onNewWant, want=${JSON.stringify(want)}`);
+        hilog.info(0x0000, 'Heanup2', `onNewWant, want=${JSON.stringify(want)}`);
         super.onNewWant(want, launchParam);
         super.onNewWant(want, launchParam);
         this.loadDoWant(want)
         this.loadDoWant(want)
         await this.handleParam(want)
         await this.handleParam(want)
@@ -159,7 +150,7 @@ export default class EntryAbility extends UIAbility {
             console.info('uri is invalid');
             console.info('uri is invalid');
             return;
             return;
         }
         }
-        hilog.info(0x0000, 'testTag', `onCreate or onNewWant, uri=${uri}`);
+        hilog.info(0x0000, 'Heanup2', `onCreate or onNewWant, uri=${uri}`);
 
 
         this.doSendEmit(uri)
         this.doSendEmit(uri)
     }
     }
@@ -202,7 +193,7 @@ export default class EntryAbility extends UIAbility {
     }
     }
 
 
     onDestroy() {
     onDestroy() {
-        hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
+        hilog.info(0x0000, 'Heanup2', '%{public}s', 'Ability onDestroy');
         
         
         // 注销卡片call事件监听器
         // 注销卡片call事件监听器
         this.unregisterWidgetCallListeners();
         this.unregisterWidgetCallListeners();
@@ -218,7 +209,7 @@ export default class EntryAbility extends UIAbility {
 
 
     onWindowStageCreate(windowStage: window.WindowStage) {
     onWindowStageCreate(windowStage: window.WindowStage) {
         // Main window is created, set main page for this ability
         // Main window is created, set main page for this ability
-        hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
+        hilog.info(0x0000, 'Heanup2', '%{public}s', 'Ability onWindowStageCreate');
         SpiderMan.init();
         SpiderMan.init();
         AppUtil.init(this.context);
         AppUtil.init(this.context);
         
         
@@ -227,12 +218,12 @@ export default class EntryAbility extends UIAbility {
             import('../common/widget/DirectFormUpdateService').then((module) => {
             import('../common/widget/DirectFormUpdateService').then((module) => {
                 const directFormService = module.DirectFormUpdateService.getInstance();
                 const directFormService = module.DirectFormUpdateService.getInstance();
                 directFormService.setAppContext(this.context);
                 directFormService.setAppContext(this.context);
-                hilog.info(0x0000, 'testTag', 'DirectFormUpdateService context initialized');
+                hilog.info(0x0000, 'Heanup2', 'DirectFormUpdateService context initialized');
             }).catch((error: Error) => {
             }).catch((error: Error) => {
-                hilog.error(0x0000, 'testTag', `Failed to initialize DirectFormUpdateService: ${error.message}`);
+                hilog.error(0x0000, 'Heanup2', `Failed to initialize DirectFormUpdateService: ${error.message}`);
             });
             });
         } catch (error) {
         } catch (error) {
-            hilog.error(0x0000, 'testTag', `Error initializing DirectFormUpdateService: ${error}`);
+            hilog.error(0x0000, 'Heanup2', `Error initializing DirectFormUpdateService: ${error}`);
         }
         }
         
         
         //1.获取应用主窗口。
         //1.获取应用主窗口。
@@ -269,11 +260,11 @@ export default class EntryAbility extends UIAbility {
 
 
         AppStorage.setOrCreate('windowStage',windowStage);
         AppStorage.setOrCreate('windowStage',windowStage);
 
 
-        hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
+        hilog.info(0x0000, 'Heanup2', '%{public}s', 'Ability onWindowStageCreate');
 
 
         windowStage.loadContent('pages/SplashIndex', (err, data) => {
         windowStage.loadContent('pages/SplashIndex', (err, data) => {
             if (err.code) {
             if (err.code) {
-                hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
+                hilog.error(0x0000, 'Heanup2', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
                 return;
                 return;
             }
             }
             //一多断点开发
             //一多断点开发
@@ -300,25 +291,23 @@ export default class EntryAbility extends UIAbility {
                 console.error(`Failed to obtain the main window. Cause code: ${err.code}, message: ${err.message}`);
                 console.error(`Failed to obtain the main window. Cause code: ${err.code}, message: ${err.message}`);
             });
             });
 
 
-            hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
+            hilog.info(0x0000, 'Heanup2', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
         });
         });
-
-        DemoConstants.windowStage = windowStage
     }
     }
 
 
     onWindowStageDestroy() {
     onWindowStageDestroy() {
         // Main window is destroyed, release UI related resources
         // Main window is destroyed, release UI related resources
-        hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
+        hilog.info(0x0000, 'Heanup2', '%{public}s', 'Ability onWindowStageDestroy');
     }
     }
 
 
     onForeground() {
     onForeground() {
         // Ability has brought to foreground
         // Ability has brought to foreground
-        hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
+        hilog.info(0x0000, 'Heanup2', '%{public}s', 'Ability onForeground');
     }
     }
 
 
     onBackground() {
     onBackground() {
         // Ability has back to background
         // Ability has back to background
-        hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
+        hilog.info(0x0000, 'Heanup2', '%{public}s', 'Ability onBackground');
     }
     }
 
 
 
 
@@ -367,9 +356,9 @@ export default class EntryAbility extends UIAbility {
         try {
         try {
             // 监听播放/暂停事件
             // 监听播放/暂停事件
             this.callee.on('playPause', (data: rpc.MessageSequence) => {
             this.callee.on('playPause', (data: rpc.MessageSequence) => {
-                hilog.info(0x0000, 'testTag', `Widget call: playPause received`);
+                hilog.info(0x0000, 'Heanup2', `Widget call: playPause received`);
                 const params: Record<string, Object> = JSON.parse(data.readString()) as Record<string, Object>;
                 const params: Record<string, Object> = JSON.parse(data.readString()) as Record<string, Object>;
-                hilog.info(0x0000, 'testTag', `Widget playPause params: ${JSON.stringify(params)}`);
+                hilog.info(0x0000, 'Heanup2', `Widget playPause params: ${JSON.stringify(params)}`);
                 
                 
                 // 发送播放/暂停事件到主应用
                 // 发送播放/暂停事件到主应用
                 this.sendWidgetControlEvent('PLAY_PAUSE', params);
                 this.sendWidgetControlEvent('PLAY_PAUSE', params);
@@ -379,9 +368,9 @@ export default class EntryAbility extends UIAbility {
 
 
             // 监听下一首事件
             // 监听下一首事件
             this.callee.on('nextSong', (data: rpc.MessageSequence) => {
             this.callee.on('nextSong', (data: rpc.MessageSequence) => {
-                hilog.info(0x0000, 'testTag', `Widget call: nextSong received`);
+                hilog.info(0x0000, 'Heanup2', `Widget call: nextSong received`);
                 const params: Record<string, Object> = JSON.parse(data.readString()) as Record<string, Object>;
                 const params: Record<string, Object> = JSON.parse(data.readString()) as Record<string, Object>;
-                hilog.info(0x0000, 'testTag', `Widget nextSong params: ${JSON.stringify(params)}`);
+                hilog.info(0x0000, 'Heanup2', `Widget nextSong params: ${JSON.stringify(params)}`);
                 
                 
                 // 发送下一首事件到主应用
                 // 发送下一首事件到主应用
                 this.sendWidgetControlEvent('NEXT_SONG', params);
                 this.sendWidgetControlEvent('NEXT_SONG', params);
@@ -391,9 +380,9 @@ export default class EntryAbility extends UIAbility {
 
 
             // 监听上一首事件
             // 监听上一首事件
             this.callee.on('prevSong', (data: rpc.MessageSequence) => {
             this.callee.on('prevSong', (data: rpc.MessageSequence) => {
-                hilog.info(0x0000, 'testTag', `Widget call: prevSong received`);
+                hilog.info(0x0000, 'Heanup2', `Widget call: prevSong received`);
                 const params: Record<string, Object> = JSON.parse(data.readString()) as Record<string, Object>;
                 const params: Record<string, Object> = JSON.parse(data.readString()) as Record<string, Object>;
-                hilog.info(0x0000, 'testTag', `Widget prevSong params: ${JSON.stringify(params)}`);
+                hilog.info(0x0000, 'Heanup2', `Widget prevSong params: ${JSON.stringify(params)}`);
                 
                 
                 // 发送上一首事件到主应用
                 // 发送上一首事件到主应用
                 this.sendWidgetControlEvent('PREV_SONG', params);
                 this.sendWidgetControlEvent('PREV_SONG', params);
@@ -403,9 +392,9 @@ export default class EntryAbility extends UIAbility {
 
 
             // 监听打开应用事件
             // 监听打开应用事件
             this.callee.on('openApp', (data: rpc.MessageSequence) => {
             this.callee.on('openApp', (data: rpc.MessageSequence) => {
-                hilog.info(0x0000, 'testTag', `Widget call: openApp received`);
+                hilog.info(0x0000, 'Heanup2', `Widget call: openApp received`);
                 const params: Record<string, Object> = JSON.parse(data.readString()) as Record<string, Object>;
                 const params: Record<string, Object> = JSON.parse(data.readString()) as Record<string, Object>;
-                hilog.info(0x0000, 'testTag', `Widget openApp params: ${JSON.stringify(params)}`);
+                hilog.info(0x0000, 'Heanup2', `Widget openApp params: ${JSON.stringify(params)}`);
                 
                 
                 // 发送打开应用事件到主应用
                 // 发送打开应用事件到主应用
                 this.sendWidgetControlEvent('OPEN_APP', params);
                 this.sendWidgetControlEvent('OPEN_APP', params);
@@ -413,9 +402,9 @@ export default class EntryAbility extends UIAbility {
                 return new MyParcelable(4, 'openApp_success');
                 return new MyParcelable(4, 'openApp_success');
             });
             });
 
 
-            hilog.info(0x0000, 'testTag', 'Widget call listeners registered successfully');
+            hilog.info(0x0000, 'Heanup2', 'Widget call listeners registered successfully');
         } catch (err) {
         } catch (err) {
-            hilog.error(0x0000, 'testTag', `Failed to register widget call listeners: ${JSON.stringify(err as BusinessError)}`);
+            hilog.error(0x0000, 'Heanup2', `Failed to register widget call listeners: ${JSON.stringify(err as BusinessError)}`);
         }
         }
     }
     }
 
 
@@ -430,10 +419,10 @@ export default class EntryAbility extends UIAbility {
             // this.callee.off('openApp');
             // this.callee.off('openApp');
             // this.callee.off('playByAction');
             // this.callee.off('playByAction');
             // this.callee.off('collectAction');
             // this.callee.off('collectAction');
-            this.callee.off('requestUpdatePlayCard');
-            hilog.info(0x0000, 'testTag', 'Widget call listeners unregistered successfully');
+            // this.callee.off('requestUpdatePlayCard');
+            hilog.info(0x0000, 'Heanup2', 'Widget call listeners unregistered successfully');
         } catch (err) {
         } catch (err) {
-            hilog.error(0x0000, 'testTag', `Failed to unregister widget call listeners: ${JSON.stringify(err as BusinessError)}`);
+            hilog.error(0x0000, 'Heanup2', `Failed to unregister widget call listeners: ${JSON.stringify(err as BusinessError)}`);
         }
         }
     }
     }
 
 
@@ -443,14 +432,14 @@ export default class EntryAbility extends UIAbility {
      */
      */
     private async sendWidgetControlEvent(command: string, params: Record<string, Object>): Promise<void> {
     private async sendWidgetControlEvent(command: string, params: Record<string, Object>): Promise<void> {
         try {
         try {
-            hilog.info(0x0000, 'testTag', `🎵 Processing widget control command: ${command}`);
+            hilog.info(0x0000, 'Heanup2', `🎵 Processing widget control command: ${command}`);
             
             
             // 获取UnifiedPlayerService实例
             // 获取UnifiedPlayerService实例
             const unifiedService = UnifiedPlayerService.getInstance();
             const unifiedService = UnifiedPlayerService.getInstance();
             
             
             // 确保服务已经初始化
             // 确保服务已经初始化
             if (!unifiedService) {
             if (!unifiedService) {
-                hilog.error(0x0000, 'testTag', '❌ UnifiedPlayerService not available');
+                hilog.error(0x0000, 'Heanup2', '❌ UnifiedPlayerService not available');
                 return;
                 return;
             }
             }
             
             
@@ -480,27 +469,27 @@ export default class EntryAbility extends UIAbility {
                     
                     
                 case 'NEXT_SONG':
                 case 'NEXT_SONG':
                     await unifiedService.playNext();
                     await unifiedService.playNext();
-                    hilog.info(0x0000, 'testTag', '✅ Widget command: Next song');
+                    hilog.info(0x0000, 'Heanup2', '✅ Widget command: Next song');
                     break;
                     break;
                     
                     
                 case 'PREV_SONG':
                 case 'PREV_SONG':
                     await unifiedService.playPrevious();
                     await unifiedService.playPrevious();
-                    hilog.info(0x0000, 'testTag', '✅ Widget command: Previous song');
+                    hilog.info(0x0000, 'Heanup2', '✅ Widget command: Previous song');
                     break;
                     break;
                     
                     
                 case 'OPEN_APP':
                 case 'OPEN_APP':
-                    hilog.info(0x0000, 'testTag', '✅ Widget command: Open app (handled by UI)');
+                    hilog.info(0x0000, 'Heanup2', '✅ Widget command: Open app (handled by UI)');
                     break;
                     break;
                     
                     
                 default:
                 default:
-                    hilog.warn(0x0000, 'testTag', `❓ Unknown widget command: ${command}`);
+                    hilog.warn(0x0000, 'Heanup2', `❓ Unknown widget command: ${command}`);
                     break;
                     break;
             }
             }
             
             
-            hilog.info(0x0000, 'testTag', `✅ Widget control command processed: ${command}`);
+            hilog.info(0x0000, 'Heanup2', `✅ Widget control command processed: ${command}`);
             
             
         } catch (error) {
         } catch (error) {
-            hilog.error(0x0000, 'testTag', `❌ Failed to process widget control command: ${error}`);
+            hilog.error(0x0000, 'Heanup2', `❌ Failed to process widget control command: ${error}`);
         }
         }
     }
     }
 }
 }

+ 0 - 1
entry/src/main/ets/pages/SplashIndex.ets

@@ -13,7 +13,6 @@ import { ConfigManager } from '../common/util/ConfigManager'
 //   CSJSplashAdLoadParam,} from '@csj/openadsdk'
 //   CSJSplashAdLoadParam,} from '@csj/openadsdk'
 import { UIUtil } from '../common/util/UIUtil'
 import { UIUtil } from '../common/util/UIUtil'
 import { PrintBiddingTokenUtils } from '../common/util/PrintBiddintTokenUtils'
 import { PrintBiddingTokenUtils } from '../common/util/PrintBiddintTokenUtils'
-import { DemoConstants } from '../entryability/DemoConstants'
 import { AppUtil, Base64Util, FileUtil, LogUtil, StrUtil, ToastUtil } from '@pura/harmony-utils'
 import { AppUtil, Base64Util, FileUtil, LogUtil, StrUtil, ToastUtil } from '@pura/harmony-utils'
 import { Utility } from '../common/util/Utility'
 import { Utility } from '../common/util/Utility'
 import { VideoItem } from '../viewmodel/VideoItem'
 import { VideoItem } from '../viewmodel/VideoItem'

+ 0 - 1
entry/src/main/ets/view/LocalMusic.ets

@@ -66,7 +66,6 @@ import { PlayStatus } from '../common/PlayStatus';
 import fs from '@ohos.file.fs';
 import fs from '@ohos.file.fs';
 import { image } from '@kit.ImageKit';
 import { image } from '@kit.ImageKit';
 import { AVCastPicker, AVCastPickerState, AVCastPickerStyle, avSession } from '@kit.AVSessionKit';
 import { AVCastPicker, AVCastPickerState, AVCastPickerStyle, avSession } from '@kit.AVSessionKit';
-import * as chardet from '@changwei/chardet';
 import { UniversalDetector } from '@ohos/juniversalchardet';
 import { UniversalDetector } from '@ohos/juniversalchardet';
 import { SettingPage } from '../pages/SettingPage';
 import { SettingPage } from '../pages/SettingPage';
 import { secondToTime } from '../common/util/CommUtils';
 import { secondToTime } from '../common/util/CommUtils';