From 0d2763e41cdf6d3a25a43d6d165b4f4f0c749d6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=8B=E8=83=BD=5F=E5=BC=A0=E5=BE=B7=E7=9B=9B?= Date: Sat, 30 Aug 2025 16:50:03 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=99=BA=E8=83=BD?= =?UTF-8?q?=E7=A9=BF=E6=88=B4=E9=A6=96=E9=A1=B5=E6=97=A0=E6=B3=95=E6=BB=9A?= =?UTF-8?q?=E5=8A=A8=EF=BC=9B=E4=BF=AE=E5=A4=8D=E7=BC=96=E8=AF=91=E6=8A=A5?= =?UTF-8?q?=E9=94=99=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/ets/utils/BackgroundUtil.ets | 4 +- .../src/main/ets/utils/MediaService.ets | 123 ++++++++++++------ .../src/main/ets/utils/PreferencesUtil.ets | 4 +- .../src/main/ets/utils/SongItemBuilder.ets | 6 +- .../main/ets/components/LyricsComponent.ets | 28 ++-- .../ets/components/MusicControlComponent.ets | 8 +- .../musicList/src/main/ets/lyric/LrcUtils.ets | 13 +- .../main/ets/entryability/EntryAbility.ets | 38 +++--- products/watch/src/main/ets/view/Home.ets | 2 - products/watch/src/main/ets/view/PlayList.ets | 5 +- products/watch/src/main/ets/view/SongList.ets | 2 +- 11 files changed, 154 insertions(+), 79 deletions(-) diff --git a/common/mediaCommon/src/main/ets/utils/BackgroundUtil.ets b/common/mediaCommon/src/main/ets/utils/BackgroundUtil.ets index 7471594..bb85812 100644 --- a/common/mediaCommon/src/main/ets/utils/BackgroundUtil.ets +++ b/common/mediaCommon/src/main/ets/utils/BackgroundUtil.ets @@ -55,7 +55,9 @@ export class BackgroundUtil { Logger.error('this avPlayer: ', `startBackgroundRunning failed. code ${(error as BusinessError).code} message ${(error as BusinessError).message}`); } - }); + }).catch((err: BusinessError) => { + Logger.error(`getWantAgent failed, code: ${JSON.stringify(err.code)}, message: ${JSON.stringify(err.message)}`); + }) } /** diff --git a/common/mediaCommon/src/main/ets/utils/MediaService.ets b/common/mediaCommon/src/main/ets/utils/MediaService.ets index 5b65c2d..a144956 100644 --- a/common/mediaCommon/src/main/ets/utils/MediaService.ets +++ b/common/mediaCommon/src/main/ets/utils/MediaService.ets @@ -211,9 +211,13 @@ export class MediaService { if (!this.context) { return; } - this.session = await avSession.createAVSession(this.context, 'SESSION_NAME', 'audio'); - this.session.activate(); - Logger.info(TAG, `session create done : sessionId : ${this.session.sessionId}`); + try { + this.session = await avSession.createAVSession(this.context, 'SESSION_NAME', 'audio'); + Logger.info(TAG, `session create done : sessionId : ${this.session.sessionId}`); + this.session.activate(); + } catch (error) { + Logger.error(TAG, `${error.code} + ${error.message}`); + } this.setAVMetadata(); let wantAgentInfo: wantAgent.WantAgentInfo = { wants: [ @@ -230,7 +234,10 @@ export class MediaService { if (this.session) { this.session.setLaunchAbility(agent); } - }); + }) + .catch((err: BusinessError) => { + console.error(`getWantAgent failed, code: ${JSON.stringify(err.code)}, message: ${JSON.stringify(err.message)}`); + }); this.setListenerForMesFromController(); } @@ -238,20 +245,28 @@ export class MediaService { if (!this.session) { return; } - this.session.on('play', this.playCall); - this.session.on('pause', this.pauseCall); - this.session.on('playNext', this.playNextCall); - this.session.on('playPrevious', this.playPreviousCall); + try { + this.session.on('play', this.playCall); + this.session.on('pause', this.pauseCall); + this.session.on('playNext', this.playNextCall); + this.session.on('playPrevious', this.playPreviousCall); + } catch (error) { + Logger.error(TAG, `${error.code} + ${error.message}`); + } } async unregisterSessionListener() { if (!this.session) { return; } - this.session.off('play'); - this.session.off('pause'); - this.session.off('playNext'); - this.session.off('playPrevious'); + try { + this.session.off('play'); + this.session.off('pause'); + this.session.off('playNext'); + this.session.off('playPrevious'); + } catch (error) { + Logger.error(TAG, `${error.code} + ${error.message}`); + } } async setAVMetadata() { @@ -401,12 +416,16 @@ export class MediaService { if (!this.isPrepared) { this.start(0); } else if (this.avPlayer) { - this.avPlayer.play().then(() => { - Logger.info(TAG, 'progressTime play() current time:' + this.getCurrentTime()); - this.seek(this.getCurrentTime()); - this.updateIsPlay(true); - this.state = AudioPlayerState.PLAY; - }); + try { + this.avPlayer.play().then(() => { + Logger.info(TAG, 'progressTime play() current time:' + this.getCurrentTime()); + this.seek(this.getCurrentTime()); + this.updateIsPlay(true); + this.state = AudioPlayerState.PLAY; + }); + } catch (error) { + Logger.error(TAG, `${error.code} + ${error.message}`); + } } } @@ -422,7 +441,9 @@ export class MediaService { if (this.context) { BackgroundUtil.stopContinuousTask(this.context); } - }); + }).catch((err: BusinessError) => { + Logger.error(TAG, 'Failed to pause,error message is :' + err.message); + }) } } @@ -438,7 +459,11 @@ export class MediaService { if (isFromControl) { this.playNext(); } else if (this.avPlayer) { - this.avPlayer.play(); + try { + this.avPlayer.play(); + } catch (error) { + Logger.error(TAG, `${error.code} + ${error.message}`); + } } break; case MusicPlayMode.ORDER: @@ -501,11 +526,15 @@ export class MediaService { public async stop() { Logger.info(TAG, 'stop()'); if (this.isPrepared && this.avPlayer) { - await this.avPlayer.stop(); - this.updateIsPlay(false); - this.state = AudioPlayerState.PAUSE; - if (this.context) { - BackgroundUtil.stopContinuousTask(this.context); + try { + await this.avPlayer.stop(); + this.updateIsPlay(false); + this.state = AudioPlayerState.PAUSE; + if (this.context) { + BackgroundUtil.stopContinuousTask(this.context); + } + } catch (error) { + Logger.error(TAG, `${error.code} + ${error.message}`); } } } @@ -514,7 +543,11 @@ export class MediaService { Logger.info(TAG, 'reset()'); await this.songItemBuilder.release(); if (this.avPlayer) { - await this.avPlayer.reset(); + try { + await this.avPlayer.reset(); + } catch (error) { + Logger.error(TAG, `${error.code} + ${error.message}`); + } } this.isPrepared = false; } @@ -524,20 +557,24 @@ export class MediaService { */ public release() { if (this.avPlayer && this.session && this.context) { - this.updateIsPlay(false); - this.stop(); - this.reset(); - this.avPlayer.release(); - this.state = AudioPlayerState.IDLE; - BackgroundUtil.stopContinuousTask(this.context); - this.unregisterSessionListener(); - this.session.destroy((err: BusinessError) => { - if (err) { - Logger.error(TAG, `Failed to destroy session. Code: ${err.code}, message: ${err.message}`); - } else { - Logger.info(TAG, `Destroy : SUCCESS `); - } - }); + try { + this.updateIsPlay(false); + this.stop(); + this.reset(); + this.avPlayer.release(); + this.state = AudioPlayerState.IDLE; + BackgroundUtil.stopContinuousTask(this.context); + this.unregisterSessionListener(); + this.session.destroy((err: BusinessError) => { + if (err) { + Logger.error(TAG, `Failed to destroy session. Code: ${err.code}, message: ${err.message}`); + } else { + Logger.info(TAG, `Destroy : SUCCESS `); + } + }); + } catch (error) { + Logger.error(TAG, `${error.code} + ${error.message}`); + } } } @@ -632,7 +669,11 @@ export class MediaService { }; let formInfo = formBindingData.createFormBindingData(formData); for (let index = 0; index < this.formIds.length; index++) { - await formProvider.updateForm(this.formIds[index], formInfo); + try { + await formProvider.updateForm(this.formIds[index], formInfo); + } catch (error) { + Logger.error(TAG, `${error.code} + ${error.message}`); + } } } } \ No newline at end of file diff --git a/common/mediaCommon/src/main/ets/utils/PreferencesUtil.ets b/common/mediaCommon/src/main/ets/utils/PreferencesUtil.ets index 2dc7dcb..77d67c0 100644 --- a/common/mediaCommon/src/main/ets/utils/PreferencesUtil.ets +++ b/common/mediaCommon/src/main/ets/utils/PreferencesUtil.ets @@ -85,7 +85,9 @@ export class PreferencesUtil { } removePreferencesFromCache(context: Context): void { - preferences.removePreferencesFromCache(context, MY_STORE); + preferences.removePreferencesFromCache(context, MY_STORE).catch((err: BusinessError) => { + console.error("Failed to remove preferences. code =" + err.code + ", message =" + err.message); + }) } async getFormIds(context: Context): Promise> { diff --git a/common/mediaCommon/src/main/ets/utils/SongItemBuilder.ets b/common/mediaCommon/src/main/ets/utils/SongItemBuilder.ets index cd01303..3e31b9e 100644 --- a/common/mediaCommon/src/main/ets/utils/SongItemBuilder.ets +++ b/common/mediaCommon/src/main/ets/utils/SongItemBuilder.ets @@ -49,7 +49,11 @@ export default class SongItemBuilder { public async release(): Promise { if (this.context && this.context !== null && this.songItem !== null) { - this.context.resourceManager.closeRawFd(this.songItem.src); + try { + this.context.resourceManager.closeRawFd(this.songItem.src); + } catch (error) { + Logger.error('Failed to closeRawFd'); + } } this.songItem = null; } diff --git a/features/musicList/src/main/ets/components/LyricsComponent.ets b/features/musicList/src/main/ets/components/LyricsComponent.ets index 9b1ea3d..cac1b40 100644 --- a/features/musicList/src/main/ets/components/LyricsComponent.ets +++ b/features/musicList/src/main/ets/components/LyricsComponent.ets @@ -15,7 +15,7 @@ import { common } from '@kit.AbilityKit'; import { util } from '@kit.ArkTS'; -import { BreakpointType, SongItem } from '@ohos/mediaCommon'; +import { BreakpointType, Logger, SongItem } from '@ohos/mediaCommon'; import { BreakpointConstants, StyleConstants } from '@ohos/constantsCommon'; import { LrcEntry } from '../lyric/LrcEntry'; import { parseKrcLyric, parseLrcLyric } from '../lyric/LrcUtils'; @@ -25,6 +25,8 @@ import { ControlAreaComponent } from './ControlAreaComponent'; import { LyricFile } from '../lyric/LyricConst'; import { PlayerConstants } from '../constants/PlayerConstants'; +const TAG = 'LyricsComponent'; + @Component export struct LyricsComponent { @StorageProp('currentBreakpoint') currentBreakpoint: string = BreakpointConstants.BREAKPOINT_SM; @@ -52,16 +54,20 @@ export struct LyricsComponent { if (!this.context) { return; } - this.context .resourceManager .getRawFileContent(this.songList[this.selectIndex].lyric) - .then((value: Uint8Array) => { - let textDecoder = util.TextDecoder.create(PlayerConstants.ENCODING, { ignoreBOM: true }); - let stringData = textDecoder.decodeToString(value, { stream: false }); - if (this.songList[this.selectIndex].lyric.endsWith(LyricFile.KRC)) { - this.mLrcEntryList = parseKrcLyric(stringData); - } else if (this.songList[this.selectIndex].lyric.endsWith(LyricFile.LRC)) { - this.mLrcEntryList = parseLrcLyric(stringData); - } - }); + try { + this.context.resourceManager.getRawFileContent(this.songList[this.selectIndex].lyric) + .then((value: Uint8Array) => { + let textDecoder = util.TextDecoder.create(PlayerConstants.ENCODING, { ignoreBOM: true }); + let stringData = textDecoder.decodeToString(value, { stream: false }); + if (this.songList[this.selectIndex].lyric.endsWith(LyricFile.KRC)) { + this.mLrcEntryList = parseKrcLyric(stringData); + } else if (this.songList[this.selectIndex].lyric.endsWith(LyricFile.LRC)) { + this.mLrcEntryList = parseLrcLyric(stringData); + } + }); + } catch (error) { + Logger.error(TAG, `${error.code} + ${error.message}`); + } } build() { diff --git a/features/musicList/src/main/ets/components/MusicControlComponent.ets b/features/musicList/src/main/ets/components/MusicControlComponent.ets index aec824a..0c8765e 100644 --- a/features/musicList/src/main/ets/components/MusicControlComponent.ets +++ b/features/musicList/src/main/ets/components/MusicControlComponent.ets @@ -26,6 +26,8 @@ import { ControlAreaComponent } from './ControlAreaComponent'; import { TopAreaComponent } from './TopAreaComponent'; import { PlayerConstants } from '../constants/PlayerConstants'; +const TAG = 'MusicControlComponent'; + @Preview @Component export struct MusicControlComponent { @@ -72,7 +74,11 @@ export struct MusicControlComponent { aboutToDisappear(): void { if (canIUse('SystemCapability.Window.SessionManager')) { - display.off('foldDisplayModeChange', this.callback); + try { + display.off('foldDisplayModeChange', this.callback); + } catch (error) { + Logger.error(TAG, `${error.code} + ${error.message}`); + } } } diff --git a/features/musicList/src/main/ets/lyric/LrcUtils.ets b/features/musicList/src/main/ets/lyric/LrcUtils.ets index 44f47c3..77e97ac 100644 --- a/features/musicList/src/main/ets/lyric/LrcUtils.ets +++ b/features/musicList/src/main/ets/lyric/LrcUtils.ets @@ -33,10 +33,15 @@ const krcWordRegex2 = new RegExp('<(\\d+),(\\d+),(\\d+)>(.*)'); export async function getRawStringData(context: Context, rawFilePath: string): Promise { - let value = await context.resourceManager.getRawFileContent(rawFilePath); - let textDecoder = util.TextDecoder.create('utf-8', { ignoreBOM: true }); - let stringData = textDecoder.decodeToString(value, { stream: false }); - return stringData; + try { + let value = await context.resourceManager.getRawFileContent(rawFilePath); + let textDecoder = util.TextDecoder.create('utf-8', { ignoreBOM: true }); + let stringData = textDecoder.decodeToString(value, { stream: false }); + return stringData; + } catch (error) { + Logger.error('Failed to getRawStringData', `${error.code} + ${error.message}`); + return '' + } } /** diff --git a/products/phone/src/main/ets/entryability/EntryAbility.ets b/products/phone/src/main/ets/entryability/EntryAbility.ets index 0317f56..84e654e 100644 --- a/products/phone/src/main/ets/entryability/EntryAbility.ets +++ b/products/phone/src/main/ets/entryability/EntryAbility.ets @@ -33,13 +33,17 @@ export default class EntryAbility extends UIAbility { // Main window is created, set main page for this ability hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); - windowStage.getMainWindow().then((data: window.Window) => { - this.windowObj = data; - this.updateBreakpoint(this.windowObj.getWindowProperties().windowRect.width); - this.windowObj.on('windowSizeChange', (windowSize: window.Size) => { - this.updateBreakpoint(windowSize.width); + try { + windowStage.getMainWindow().then((data: window.Window) => { + this.windowObj = data; + this.updateBreakpoint(this.windowObj.getWindowProperties().windowRect.width); + this.windowObj.on('windowSizeChange', (windowSize: window.Size) => { + this.updateBreakpoint(windowSize.width); + }); }); - }); + } catch (error) { + hilog.error(0x0000, 'testTag', '%{public}s', 'Failed to getMainWindow'); + } windowStage.loadContent('pages/Index', (err) => { AppStorage.setOrCreate('uiContext', windowStage.getMainWindowSync().getUIContext()); @@ -52,16 +56,20 @@ export default class EntryAbility extends UIAbility { } private updateBreakpoint(windowWidth: number): void{ - let windowWidthVp = windowWidth / display.getDefaultDisplaySync().densityPixels; - let curBp: string = ''; - if (windowWidthVp < BreakpointConstants.BREAKPOINT_VALUE_NUMBER[1]) { - curBp = BreakpointConstants.BREAKPOINT_SM; - } else if (windowWidthVp < BreakpointConstants.BREAKPOINT_VALUE_NUMBER[2]) { - curBp = BreakpointConstants.BREAKPOINT_MD; - } else { - curBp = BreakpointConstants.BREAKPOINT_LG; + try { + let windowWidthVp = windowWidth / display.getDefaultDisplaySync().densityPixels; + let curBp: string = ''; + if (windowWidthVp < BreakpointConstants.BREAKPOINT_VALUE_NUMBER[1]) { + curBp = BreakpointConstants.BREAKPOINT_SM; + } else if (windowWidthVp < BreakpointConstants.BREAKPOINT_VALUE_NUMBER[2]) { + curBp = BreakpointConstants.BREAKPOINT_MD; + } else { + curBp = BreakpointConstants.BREAKPOINT_LG; + } + AppStorage.setOrCreate('currentBreakpoint', curBp); + } catch (error) { + hilog.error(0x0000, 'testTag', 'Failed to updateBreakpoint. Cause: %{public}s', JSON.stringify(error) ?? ''); } - AppStorage.setOrCreate('currentBreakpoint', curBp); } onWindowStageDestroy() { diff --git a/products/watch/src/main/ets/view/Home.ets b/products/watch/src/main/ets/view/Home.ets index f5d4a89..200e7dd 100644 --- a/products/watch/src/main/ets/view/Home.ets +++ b/products/watch/src/main/ets/view/Home.ets @@ -82,8 +82,6 @@ export struct Home { .padding({ left: $r('app.float.list_btn_padding'), right: $r('app.float.list_btn_padding') }) .justifyContent(FlexAlign.SpaceBetween) .borderRadius(StyleConstants.CIRCLE_BORDER_RADIUS) - .focusable(true) - .focusOnTouch(true) .backgroundColor($r('app.color.home_btn_background')) .onClick(() => { if (item.pathName === 'setting') { diff --git a/products/watch/src/main/ets/view/PlayList.ets b/products/watch/src/main/ets/view/PlayList.ets index a643e70..37ba7a5 100644 --- a/products/watch/src/main/ets/view/PlayList.ets +++ b/products/watch/src/main/ets/view/PlayList.ets @@ -58,7 +58,7 @@ export struct PlayList { NavDestination() { Column() { ArcSwiper(this.wearableSwiperController) { - ForEach(this.playList, (item: PlayListSheet, index: number) => { + ForEach(this.playList, (item: PlayListSheet) => { Column({ space: 10 }) { Row() { Text(item.name) @@ -89,6 +89,9 @@ export struct PlayList { } .index(0) .duration(400) + .focusable(true) + .focusOnTouch(true) + .defaultFocus(true) .vertical(true) .indicator(false) .disableSwipe(false) diff --git a/products/watch/src/main/ets/view/SongList.ets b/products/watch/src/main/ets/view/SongList.ets index 3cb4fa5..f4fc1b6 100644 --- a/products/watch/src/main/ets/view/SongList.ets +++ b/products/watch/src/main/ets/view/SongList.ets @@ -38,7 +38,7 @@ struct SongList { NavDestination() { Column() { ArcList({ initialIndex: 0 }) { - ForEach(this.songList, (item: SongItem) => { + ForEach(this.songList, (item: SongItem, index:number) => { ArcListItem() { Row() { Image(item.label) -- Gitee From fb9ce45e8b3c54151964de8b7ac1eb8a4cb8f7e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=8B=E8=83=BD=5F=E5=BC=A0=E5=BE=B7=E7=9B=9B?= Date: Sat, 30 Aug 2025 17:10:07 +0800 Subject: [PATCH 2/2] =?UTF-8?q?README=E5=A2=9E=E5=8A=A0=E5=B7=A5=E7=A8=8B?= =?UTF-8?q?=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.en.md | 43 +++++++++++++++++++++++++++++++++++++++++++ README.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/README.en.md b/README.en.md index 3e1eb6e..9a6a45e 100644 --- a/README.en.md +++ b/README.en.md @@ -21,6 +21,49 @@ The figure shows the effect on the wearable. +## Engineering catalogue +``` +├──commons // Public Competency Layer +│ ├──constantsCommon/src/main/ets // Public Constants +│ │ └──constants +│ └──mediaCommon/src/main/ets // Public media approach +│ └──utils +│ └──viewmodel +├──features // Basic Feature Layer +│ ├──live/src/main/ets // Live Stream Page +│ │ ├──constants +│ │ ├──view +│ │ └──viewmodel +│ ├──live/src/main/resources // Resource file directory +│ ├──musicComment/src/main/ets // Music Review Page +│ │ ├──constants +│ │ ├──view +│ │ └──viewmodel +│ ├──musicComment/src/main/resources // Resource file directory +│ ├──musicList/src/main/ets // Song List Page +│ │ ├──components +│ │ ├──constants +│ │ ├──lyric +│ │ ├──view +│ │ └──viewmodel +│ └──musicList/src/main/resources // Resource file directory +├──products // Product Customization Layer +│ ├──phone/src/main/ets // Supports smartphones, foldable screens, tablets, and PCs/2in1 devices +│ │ ├──common +│ │ ├──entryability +│ │ ├──pages +│ │ ├──phonebackupextability +│ │ └──viewmodel +│ ├──phone/src/main/ets // Resource file directory +│ ├──watch/src/main/resources // Support for smart wearables +│ │ ├──constants +│ │ ├──pages +│ │ ├──view +│ │ ├──watchability +│ │ └──watchbackupability +│ └──watch/src/main/ets // Resource file directory +``` + ## How to Use 1. Install and open an app on a mobile phone, foldable phone, or tablet. The responsive layout and adaptive layout are used to display different effects on the app pages over different devices. diff --git a/README.md b/README.md index c8fa3ff..cfda908 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,48 @@ +## 工程目录 +``` +├──commons // 公共能力层 +│ ├──constantsCommon/src/main/ets // 公共常量 +│ │ └──constants +│ └──mediaCommon/src/main/ets // 公共媒体方法 +│ └──utils +│ └──viewmodel +├──features // 基础特性层 +│ ├──live/src/main/ets // 直播页 +│ │ ├──constants +│ │ ├──view +│ │ └──viewmodel +│ ├──live/src/main/resources // 资源文件目录 +│ ├──musicComment/src/main/ets // 音乐评论页 +│ │ ├──constants +│ │ ├──view +│ │ └──viewmodel +│ ├──musicComment/src/main/resources // 资源文件目录 +│ ├──musicList/src/main/ets // 歌曲列表页 +│ │ ├──components +│ │ ├──constants +│ │ ├──lyric +│ │ ├──view +│ │ └──viewmodel +│ └──musicList/src/main/resources // 资源文件目录 +├──products // 产品定制层 +│ ├──phone/src/main/ets // 支持手机、折叠屏、平板、PC/2in1 +│ │ ├──common +│ │ ├──entryability +│ │ ├──pages +│ │ ├──phonebackupextability +│ │ └──viewmodel +│ ├──phone/src/main/ets // 资源文件目录 +│ ├──watch/src/main/resources // 支持智能穿戴 +│ │ ├──constants +│ │ ├──pages +│ │ ├──view +│ │ ├──watchability +│ │ └──watchbackupability +│ └──watch/src/main/ets // 资源文件目录 +``` ## 使用说明 -- Gitee