Преглед изворни кода

碰一碰分享前期实现

onecold пре 1 година
родитељ
комит
0894941701

+ 153 - 0
entry/src/main/ets/controller/KnockController.ets

@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// [Start knock_controller_create]
+import { harmonyShare, systemShare } from '@kit.ShareKit';
+import { fileUri } from '@kit.CoreFileKit';
+import { BusinessError } from '@kit.BasicServicesKit';
+import { uniformTypeDescriptor } from '@kit.ArkData';
+import { common } from '@kit.AbilityKit';
+// [StartExclude knock_controller_create]
+// import { VIDEO_SOURCES, VideoData } from '../model/VideoData';
+import { window } from '@kit.ArkUI';
+import { VideoItem } from '../viewmodel/VideoItem';
+import Logger from '../common/util/Logger';
+import { LogUtil } from '@pura/harmony-utils';
+
+const TAG = 'KnockController';
+// [EndExclude knock_controller_create]
+export class KnockController {
+  private static controller: KnockController;
+  private context: common.UIAbilityContext | undefined = undefined;
+  // Knock listening status
+  private isKnockListening: boolean = false;
+  private songList: Array<VideoItem>| undefined = [];
+
+  public static getInstance(context: common.UIAbilityContext): KnockController {
+    if (!KnockController.controller) {
+      KnockController.controller = new KnockController(context);
+    }
+    return KnockController.controller;
+  }
+
+  constructor(context: common.UIAbilityContext) {
+    this.context = context;
+  }
+
+  // [Start share_linking]
+  /**
+   * knock listening callback
+   * @param target After the Huawei Share event is triggered,
+   * you can call back the parameters and share them across devices.
+   */
+  public immersiveCallback(target: harmonyShare.SharableTarget) {
+    // [StartExclude knock_controller_create]
+    // share app linking
+    LogUtil.info('onecold KnockController  碰一碰 ');
+    try {
+      let curIndex: number = AppStorage.get('curIndex') as number;
+       this.songList = AppStorage.get('songList');
+      console.info('onecold KnockController  碰一碰 curIndex '+curIndex);
+      console.info('onecold KnockController  碰一碰 this.songList '+this.songList?.length);
+       if(this.songList){
+         let mediaData: VideoItem = this.songList[curIndex];
+         // Video thumbnail image sandbox path
+         let coverUri: string = `${mediaData.pixelMapPath}`;
+         console.info('onecold KnockController  碰一碰 filePath '+coverUri);
+         // Get video thumbnail URI path
+         let shareData: systemShare.SharedData = new systemShare.SharedData({
+           // Set the shared data type to Link
+           utd: uniformTypeDescriptor.UniformDataType.AUDIO,
+           uri:mediaData.filePath,
+           // The shared App Linking link is replaced with the real address here
+           // content: `https://www.xgplayer.com?curIndex=${curIndex}`,
+           thumbnailUri: coverUri,
+           title: mediaData.name,
+           description: mediaData.artist
+         });
+         // Initiate a share
+         target.share(shareData).then(() => {
+           Logger.info(TAG, 'Share link success');
+         }).catch((error: BusinessError) => {
+           Logger.error(TAG, `Share link  error. code: ${error.code}, message: ${error.message}`);
+         });
+       }
+
+
+    } catch (err) {
+      Logger.error(TAG, `Share link exception. code: ${err.code}, message: ${err.message}`);
+    }
+    // [EndExclude knock_controller_create]
+  }
+  // [End share_linking]
+
+  /**
+   *  Add knock listening
+   */
+  public immersiveListening() {
+    if (canIUse('SystemCapability.Collaboration.HarmonyShare') && !this.isKnockListening) {
+      harmonyShare.on('knockShare', (target: harmonyShare.SharableTarget) => {
+        this.immersiveCallback(target);
+      });
+      this.isKnockListening = true;
+    }
+  }
+
+  /**
+   *  remove knock listening
+   */
+  public immersiveDisableListening() {
+    if (canIUse('SystemCapability.Collaboration.HarmonyShare') && this.isKnockListening) {
+      harmonyShare.off('knockShare');
+      this.isKnockListening = false;
+    }
+  }
+
+  /**
+   *  Add knock listening in 2in1 device type.
+   */
+  public immersiveListeningPC() {
+    if (canIUse('SystemCapability.Collaboration.HarmonyShare') && !this.isKnockListening) {
+      window.getLastWindow(this.context).then((data) => {
+        let mainWindowID: number = data.getWindowProperties().id;
+        // harmonyShare.on('knockShare', { windowId:mainWindowID }, (target: harmonyShare.SharableTarget) => {
+        //   this.immersiveCallback(target);
+        // });
+
+        harmonyShare.on('knockShare', (target: harmonyShare.SharableTarget) => {
+          this.immersiveCallback(target);
+        });
+      })
+
+      this.isKnockListening = true;
+    }
+  }
+
+  /**
+   *  Remove knock listening in 2in1 device type.
+   */
+  public immersiveDisableListeningPC() {
+    if (canIUse('SystemCapability.Collaboration.HarmonyShare') && this.isKnockListening) {
+      window.getLastWindow(this.context).then((data) => {
+        let mainWindowID: number = data.getWindowProperties().id;
+        // harmonyShare.off('knockShare', { windowId:mainWindowID });
+        harmonyShare.off('knockShare');
+      })
+
+      this.isKnockListening = false;
+    }
+  }
+}
+// [End knock_controller_create]

+ 43 - 8
entry/src/main/ets/entryability/EntryAbility.ets

@@ -25,6 +25,7 @@ import statusBarManager from '@hms.pcService.statusBarManager';
 import StatusBarViewExtensionAbility from '@hms.pcService.StatusBarViewExtensionAbility';
 import { SpiderMan } from '@simplepeng/spider-man';
 import { smartMobilityCommon } from '@kit.CarKit';
+import { url } from '@kit.ArkTS';
 
 /**
  * 主Ability类,继承自UIAbility
@@ -36,7 +37,21 @@ import { smartMobilityCommon } from '@kit.CarKit';
 export default class EntryAbility extends UIAbility {
     // UI上下文对象,用于获取窗口信息
     private uiContext?: UIContext;
+    private mKnockItem: string = '';//碰一碰分享接收索引
     private awareness: smartMobilityCommon.SmartMobilityAwareness = smartMobilityCommon.getSmartMobilityAwareness();
+
+    private getKnockPath(want: Want): string {
+        let uri = want?.uri;
+        let knockItem: string = '';
+        // Parse the parameters to obtain the app linking
+        if (uri) {
+            let urlObject = url.URL.parseURL(want?.uri);
+            LogUtil.info('onecold urlObject= '+urlObject.toJSON());
+            knockItem = urlObject.params.get('videoIndex') as string;
+            LogUtil.info('onecold getKnockPath= '+knockItem);
+        }
+        return knockItem;
+    }
     /**
      * 窗口尺寸变化回调函数
      * @param windowSize 新的窗口尺寸对象
@@ -54,8 +69,8 @@ export default class EntryAbility extends UIAbility {
         let heightBp: HeightBreakpoint = this.uiContext!.getWindowHeightBreakpoint();
         AppStorage.setOrCreate('currentHeightBreakpoint', heightBp);
         // 记录尺寸变化日志
-        LogUtil.info('pura onWindowSizeChange currentHeightBreakpoint= '+heightBp);
-        LogUtil.info( 'pura onWindowSizeChange currentWidthBreakpoint= '+widthBp);
+        // LogUtil.info('pura onWindowSizeChange currentHeightBreakpoint= '+heightBp);
+        // LogUtil.info( 'pura onWindowSizeChange currentWidthBreakpoint= '+widthBp);
         AppStorage.setOrCreate('windowWidth', windowSize.width);
         AppStorage.setOrCreate('windowHeight', windowSize.height);
         if(windowSize.width > windowSize.height){
@@ -63,8 +78,8 @@ export default class EntryAbility extends UIAbility {
         }else{
             AppStorage.setOrCreate('isLandscape', false);
         }
-        LogUtil.info('hicar onWindowSizeChange width= '+windowSize.width);
-        LogUtil.info( 'hicar onWindowSizeChange height= '+windowSize.height);
+        // LogUtil.info('hicar onWindowSizeChange width= '+windowSize.width);
+        // LogUtil.info( 'hicar onWindowSizeChange height= '+windowSize.height);
 
     };
 
@@ -87,7 +102,7 @@ export default class EntryAbility extends UIAbility {
         setTimeout(async ()=>{
             this.loadDoWant(want)
             await this.handleParam(want)
-        },1000)
+        },2000)
 
         this.handleWeChatCallIfNeed(want)
 
@@ -110,8 +125,17 @@ export default class EntryAbility extends UIAbility {
 
     //处理其他app点击其他应用打开播放器播放视频或者音频
     loadDoWant(want: Want){
-
+        console.info('onecold KnockController  碰一碰 want ='+JSON.stringify(want));
         let uri = want.uri;
+        // console.info('onecold KnockController  碰一碰 want.type ='+want.type);
+        // console.info('onecold KnockController  碰一碰 want.uri ='+want.uri);
+        // console.info('onecold KnockController  碰一碰 want.action ='+want.action);
+        // console.info('onecold KnockController  碰一碰 want.parameters ='+want.parameters);
+        // console.info('onecold KnockController  碰一碰 want.entities ='+want.entities);
+        // console.info('onecold KnockController  碰一碰 want.fds ='+want.fds);
+        // console.info('onecold KnockController  碰一碰 want.bundleName ='+want.bundleName);
+        // console.info('onecold KnockController  碰一碰 want.abilityName ='+want.abilityName);
+        // console.info('onecold KnockController  碰一碰 want.deviceId ='+want.deviceId);
         if (uri == null || uri == undefined|| StrUtil.isEmpty(uri)) {
             console.info('uri is invalid');
             return;
@@ -205,6 +229,12 @@ export default class EntryAbility extends UIAbility {
             windowClass.on('avoidAreaChange', this.onAvoidAreaChange)
         })
 
+        //碰一碰分享的跳转
+        let pageUrl: string = 'pages/Index';
+        if (this.mKnockItem && this.mKnockItem !== '') {
+            AppStorage.setOrCreate('videoIndex', Number.parseInt(this.mKnockItem));
+            // pageUrl = 'pages/VideoPlay';
+        }
 
         AppStorage.setOrCreate('windowStage',windowStage);
 
@@ -229,8 +259,13 @@ export default class EntryAbility extends UIAbility {
 
                 AppStorage.setOrCreate('windowWidth', data.getWindowProperties().windowRect.width);
                 AppStorage.setOrCreate('windowHeight', data.getWindowProperties().windowRect.height);
-                LogUtil.info('hicar getMainWindow width= '+data.getWindowProperties().windowRect.width);
-                LogUtil.info( 'hicar getMainWindow height= '+data.getWindowProperties().windowRect.height);
+                if(data.getWindowProperties().windowRect.width > data.getWindowProperties().windowRect.height){
+                    AppStorage.setOrCreate('isLandscape', true);
+                }else{
+                    AppStorage.setOrCreate('isLandscape', false);
+                }
+                // LogUtil.info('hicar getMainWindow width= '+data.getWindowProperties().windowRect.width);
+                // LogUtil.info( 'hicar getMainWindow height= '+data.getWindowProperties().windowRect.height);
             }).catch((err: BusinessError) => {
                 console.error(`Failed to obtain the main window. Cause code: ${err.code}, message: ${err.message}`);
             });

+ 2 - 2
entry/src/main/ets/pages/AboutPage.ets

@@ -117,8 +117,8 @@ export struct AboutPage{
           // 左右按钮
           Row() {
             Image($r('app.media.menu'))
-              .width(24)
-              .height(24)
+              .width(26)
+              .height(26)
               .margin({ left: 12, right: 8 })
               .onClick(() => {
                 animateTo({ duration: 555 }, () => {

+ 2 - 2
entry/src/main/ets/pages/SettingPage.ets

@@ -535,8 +535,8 @@ export struct SettingPage {
         // 左侧返回按钮
         Row() {
           Image($r('app.media.menu'))
-            .width(29)
-            .height(29)
+            .width(26)
+            .height(26)
             .margin({ left: 12, right: 8 })
             .onClick(() => {
               animateTo({ duration: 555 }, () => {

+ 2 - 2
entry/src/main/ets/pages/UserCenter.ets

@@ -412,8 +412,8 @@ export struct UserCenter {
           // 左右按钮
           Row() {
             Image($r('app.media.menu'))
-              .width(32)
-              .height(32)
+              .width(26)
+              .height(26)
               .margin({ left: 12, right: 8 })
               .onClick(() => {
                 animateTo({ duration: 555 }, () => {

+ 25 - 4
entry/src/main/ets/view/LocalMusic.ets

@@ -76,6 +76,7 @@ import app from '@system.app';
 import { TextNodeController } from './PipLyricTextBuilder';
 import { IndexerView } from './IndexerView';
 import { KeyCode } from '@kit.InputKit';
+import { KnockController } from '../controller/KnockController';
 // import { FFmpeg, FFProgressMessageParser } from '@sj/ffmpeg';
 const TAG = 'LocalMusic';
 
@@ -288,6 +289,7 @@ export struct LocalMusic {
   @Consume isFavMusic: boolean
   @State isClickedPLayAll: boolean = false;
   private scrollerForlist: ListScroller = new ListScroller();
+  private knockController: KnockController | undefined = undefined;
   imagesF: ImageFrameInfo[] = [
     { src: $r("app.media.app_loading0") },
     { src: $r("app.media.app_loading1") },
@@ -361,13 +363,13 @@ export struct LocalMusic {
   @State appName: string = ''
   @State isHasDir: boolean = false
   @State packName: string = ''
-  context = getContext(this);
+  context =  this.getUIContext().getHostContext() as common.UIAbilityContext
   @State titleBarModel: TitleBar.Model = new TitleBar.Model()
     .setTitleTextStyle(FontStyle.Normal)
     .setTitleBarStyle(TitleBar.BarStyle.TRANSPARENT)
     .setLeftIcon($r('app.media.menu'))
-    .setLeftIconWidth(25)
-    .setLeftIconHeight(25)
+    .setLeftIconWidth(26)
+    .setLeftIconHeight(26)
     .setTitleName('首页')
     .setTitleFontSize(18)
     .setTitleFontColor(Color.White)
@@ -670,6 +672,7 @@ export struct LocalMusic {
   }
 
   onPageShow() {
+    this.knockController?.immersiveListening();
     app.setImageCacheCount(100);
     // 设置解码前图片数据内存缓存上限为100MB (100MB=100*1024*1024B=104857600B)
     app.setImageRawDataCacheSize(104857600);
@@ -747,8 +750,21 @@ export struct LocalMusic {
 
     }
 
+    // let context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
+    //碰一碰分享的监听
+    this.knockController = KnockController.getInstance(this.context);
+    this.knockController?.immersiveListening();
+
+  }
+
+
+
+  onPageHide(): void {
+    this.knockController?.immersiveDisableListening();
   }
 
+
+
   @State isFirstStartPlay: boolean = false
 
   //获取download_path
@@ -797,7 +813,8 @@ export struct LocalMusic {
         this.videoUrl = this.currentSong.filePath
         this.name = this.currentSong.name
         this.cover = this.currentSong.pixelMapPath
-
+        AppStorage.setOrCreate('songList',this.songList) ;
+        AppStorage.setOrCreate('curIndex',this.curIndex) ;
 
       } else {
         this.name = '空空如也'
@@ -836,6 +853,8 @@ export struct LocalMusic {
   // 组件消失生命周期
   aboutToDisappear() {
     console.info('LifeCycleComponent aboutToDisappear');
+    this.knockController?.immersiveDisableListening();
+    this.curIndex = 0
     emitter.off(2);
     emitter.off(101);
     emitter.off(888);
@@ -4462,6 +4481,8 @@ export struct LocalMusic {
           let globalVideoList = Utility.getGlobalList(this.videoLocalList, CommonConstants.TYPE_LOCAL) as VideoItem[];
           this.curIndex = Utility.getCurIndexFromGlobalList(globalVideoList, item.filePath)
           this.songList = globalVideoList
+          AppStorage.setOrCreate('songList',this.songList) ;
+          AppStorage.setOrCreate('curIndex',this.curIndex) ;
           this.sonDataSource.pushArrayData(this.songList)
           this.currentSong = globalVideoList[this.curIndex]
         }

+ 12 - 2
entry/src/main/module.json5

@@ -49,7 +49,7 @@
           {
             "actions": [
               "action.system.home",
-              "ohos.want.action.viewData",
+              "ohos.want.action.viewData",//碰一碰分享增加
               "ohos.want.action.sendData"
             ],
             "uris": [
@@ -76,10 +76,20 @@
                 "type": "video/*",
                 "linkFeature": "FileOpen",
                 "maxFileSupported": 1
+              },
+              //碰一碰分享增加
+              {
+                // The scheme must be configured as https
+                "scheme": "https",
+                // The host must be configured as the associated domain name
+                "host": "https://www.xgplayer.com",
+                "path": ""
               }
             ],
+            "domainVerify": true,//碰一碰分享增加
             "entities": [
-              "entity.system.home"
+              "entity.system.home",
+              "entity.system.browsable"//碰一碰分享增加
             ],
 
           }