HarmonyOS6 接入快手 SDK 指南

介绍

目前快手开放了 授权、发布单图、发布单视频的鸿蒙能力,开发者如果有需要接入,可以按照以下流程操作。

效果一览

环境准备

开发者需要在快手开放平台完成注册 ,新建一个应用 ,并获取应用标识 appId ,详细参考申请注册流程,官网地址:open.kuaishou.com/platform

环境要求

  • 快手版本 >= 13.0.10
  • 鸿蒙SDK版本 >= 12

接入步骤

  1. 在模块中引入 SDK依赖,如 Entry模块
perl 复制代码
  "dependencies": {    "@kwai_open_platform/opensdk": "^1.0.1"
  }
  1. 在 entry 模块下的 module.json5 文件中添加querySchemes配置。

在鸿蒙应用的module.json5文件中配置querySchemes的作用是声明应用支持的URL协议(URL Scheme) ,允许其他应用或网页通过特定格式的URL调起当前应用。具体解析如下:

  1. 核心功能实现 示例中配置的"kwai""ksnebula"表示该应用可以响应以下两种格式的URL请求:
  • kwai://...

  • ksnebula://...当其他应用或系统触发这类链接时,鸿蒙系统会尝试启动当前应用并传递参数。

  1. 典型应用场景
  • 跨应用跳转:其他应用通过startAbility发送包含对应Scheme的Want对象调起本应用
  • 网页跳转:在浏览器中点击<a href="kwai://detail?id=123">类链接触发应用打开
  • 广告引流:通过短信、二维码等方式引导用户通过特定Scheme打开应用指定页面
json 复制代码
{
  "module": {
    "querySchemes": [
      "kwai",
      "ksnebula"
    ]
  }
}
  1. 同时还需求申请网络权限
json 复制代码
    "requestPermissions": [
      {
        "name" : "ohos.permission.INTERNET"
      }
    ]
  1. 在接受回调的 UIAbility 的 onCreate 和 onNewWant 方法中,调用 kwaiOpenSdk.handleCallback 方法处理回调数据。

onCreate 表示应用首次启动

onNewWant 表示应用已经启动的,然后被重新拉起

php 复制代码
import { kwaiOpenSdk } from '@kwai_open_platform/opensdk/src/main/ets/KwaiOpensdk';

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    kwaiOpenSdk.handleCallback(want)
  }

  onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    kwaiOpenSdk.handleCallback(want)
  }
}
  1. 初始化SDK,如在 Index.ets的aboutToAppear中初始化
csharp 复制代码
  aboutToAppear(): void {
    // 初始化快手SDK
    kwaiOpenSdk.init(this.context);
  }

相关功能

目前SDK提供有 授权 和 发布单图和发单视频能力,开发者可以根据需求引入使用

初始化代码数据

定义快手应用ID APPID

定义鸿蒙应用ID harmonyAppID

定义媒体选择通用方法 selectMedia

typescript 复制代码
// 导入快手开放平台SDK
import { kwaiOpenSdk } from '@kwai_open_platform/opensdk/src/main/ets/KwaiOpensdk';
// 导入AbilityKit相关组件
import { common } from '@kit.AbilityKit';
// 导入授权请求模型
import { AuthRequest } from '@kwai_open_platform/opensdk/src/main/ets/model/request/AuthRequest';
// 导入授权响应模型
import { AuthResponse } from '@kwai_open_platform/opensdk/src/main/ets/model/response/AuthResponse';
// 导入日志工具
import { Logger } from '@kwai_open_platform/opensdk/src/main/ets/utils/Logger';
// 导入分享请求模型创建函数
import {
  createSingleImagePublish,
  createSingleVideoPublish
} from '@kwai_open_platform/opensdk/src/main/ets/model/request/ShareRequest';
// 导入ArkTS集合框架
import { ArrayList } from '@kit.ArkTS';
// 导入媒体库访问助手
import { photoAccessHelper } from '@kit.MediaLibraryKit';
// 导入文件操作相关工具
import { fileIo, fileUri } from '@kit.CoreFileKit';

// 定义快手应用ID
const APPID = "ks669910448092164647"

// 定义鸿蒙应用ID
const harmonyAppID: string = "6917560710208292268";

@Entry
@Component
struct Index {
  // 获取UIAbility上下文
  context = this.getUIContext().getHostContext() as common.UIAbilityContext;
  // 回调结果状态
  @State callbackResult: boolean = false;
  // 授权码
  @State authCode: string = "";
  // 错误信息
  @State errMsg: string = "";
  // 错误码
  @State errCode: number = -1;

  aboutToAppear(): void {
    // 初始化快手SDK
    kwaiOpenSdk.init(this.context);
  }


  // 媒体选择通用方法
  private selectMedia<T>(
    callback: (t: T) => void,
    type: photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE | photoAccessHelper.PhotoViewMIMETypes.VIDEO_TYPE,
    num: number = 1
  ) {
    // 创建照片选择选项
    let photoOptions = new photoAccessHelper.PhotoSelectOptions();
    // 设置MIME类型(图片或视频)
    photoOptions.MIMEType = type;
    // 设置最大选择数量
    photoOptions.maxSelectNumber = num;

    // 创建照片选择器
    let picker = new photoAccessHelper.PhotoViewPicker();
    // 调用选择方法
    picker.select(photoOptions).then((photoSelectResult: photoAccessHelper.PhotoSelectResult) => {
      // 获取选中的URI列表
      let uris: Array<string> = photoSelectResult.photoUris;
      if (uris.length > 0) {
        // 获取第一个URI
        let str = uris[0];
        // 提取文件名
        let fileName = str.substring(str.lastIndexOf('/'));
        // 构建目标文件路径
        let desFilePath = this.context.getApplicationContext().tempDir + fileName;
        // 打开源文件(只读)
        let srcFile = fileIo.openSync(str, fileIo.OpenMode.READ_ONLY);
        // 打开目标文件(写,如不存在则创建)
        let desFile = fileIo.openSync(desFilePath, fileIo.OpenMode.WRITE_ONLY | fileIo.OpenMode.CREATE);
        // 复制文件内容
        fileIo.copyFileSync(srcFile.fd, desFile.fd)
        // 回调处理,传递文件URI
        callback?.(fileUri.getUriFromPath(desFilePath) as T);
      } else {
        // 未选择资源时显示提示
        this.getUIContext().getPromptAction().showToast({
          message: '没有选择资源'
        })
      }
    }).catch((error: BusinessError) => {
      // 选择出错时显示提示
      this.getUIContext().getPromptAction().showToast({
        message: '选择资源error'
      })
    })
  }
}

接入快手授权能力

参数说明:

参数

说明

是否必填

requiredScopes

申请获取用户的那些授权信息,如果需要多个scope,用 "," 分割。比如:user_info,user_phone

optional0Scopes

可选scope,授权页可以取消勾选,默非认勾选态

optional1Scopes

可选scope,授权页可以取消勾选,默认勾选态

callbackLocalEntry

回调的UIAbility名称,需要在module.json中声明

abilityContext

如果没有安装快手,会跳转到应用市场安装。不传则不会跳转到应用市场

javascript 复制代码
  // 授权功能实现
  fn1 = () => {
    {
      // 创建授权请求对象
      let request = new AuthRequest(APPID);
      // 设置必需的权限范围
      request.requiredScopes = "user_phone,user_info";
      // 设置可选权限范围0
      request.optional0Scopes = "user_base,share_media,following,share_message"
      // 设置可选权限范围1
      request.optional1Scopes = "user_growth_distribution,message,live,relation"
      // 设置回调入口
      request.callbackLocalEntry = "EntryAbility";
      // 设置Ability上下文
      request.abilityContext = this.context;
      // 重要提示,这行代码不要复制
      request.harmonyAppId = harmonyAppID
      // 调用SDK授权接口
      kwaiOpenSdk.createApi().authorize(this.context, request, {
        // 授权成功回调
        onSuccess: (res) => {
          Logger.i("authCallback", "success.......");
          // 保存授权码
          this.authCode = (res as AuthResponse).code;
          // 设置回调结果为成功
          this.callbackResult = true;
        },
        // 授权失败回调
        onError: (errorCode, msg) => {
          Logger.i("authCallback", `failed, code: ${errorCode}, msg: ${msg}`);
          // 保存错误信息
          this.errMsg = msg
          this.errCode = errorCode
          // 设置回调结果为失败
          this.callbackResult = false;
        }
      })
    }
  }

授权-错误码

错误码

描述

999

成功

1000

appId is empty

1001

request is error

1002

request is empty

1003

request bundle id is empty

1004

request harmony app id is empty

1005

not install kuaishou app

2000

auth request requiredScopes is empty

2002

无效的授权内容

2101

提交授权信息失败,缺少授权参数

100200100

请求缺少参数或参数类型错误

100200101

无效的client,无效的 app 或 developer,可能是验证参数不正确(回调地址等信息)

100200102

请求被拒绝,可能是无效的 token 等

100200103

请求的 responseType 错误

100200104

请求的 grantType 不支持

100200105

请求的 code 错误

100200106

请求的 scope 错误

100200107

无效的 openid

100200108

access_token过期

100200109

用户取消该 app 授权

100200110

用户授权过期

100200111

用户未授权过

100200112

bundleToken不合法

100200113

refresh_token过期

100200500

服务内部错误

接入发布单图能力

  1. 分享请求构建
  2. 使用createSingleImagePublish(APPID)创建单图分享请求对象
  3. 初始化ArrayList存储媒体URI列表,并添加选中图片的URI
  4. 设置callbackLocalEntry指定回调入口为EntryAbility
  5. 关键参数配置
  6. 显式设置harmonyAppId参数(注释提示该行代码具有重要性)
  7. 通过上下文this.context保持与当前页面的关联
  8. SDK调用与结果处理

调用kwaiOpenSdk.createApi().share()方法执行实际分享操作

typescript 复制代码
  fn2 = () => {
    // 调用媒体选择方法,指定图片类型
    this.selectMedia<string>((url: string) => {
      // 创建单图分享请求对象
      let shareRequest = createSingleImagePublish(APPID);
      // 创建媒体URI列表
      let list: ArrayList<string> = new ArrayList();
      // 添加选中的图片URI
      list.add(url);
      // 设置媒体URI列表
      shareRequest.mediaUri = list;
      // 设置回调入口
      shareRequest.callbackLocalEntry = "EntryAbility";
      // 重要提示,这行代码不要复制
      shareRequest.harmonyAppId = harmonyAppID

      // 调用SDK分享接口
      kwaiOpenSdk.createApi().share(this.context, shareRequest, {
        // 分享成功回调
        onSuccess: (res) => {
          // 设置回调结果为成功
          this.callbackResult = true;
          Logger.i("shareCallback", "success.......");
        },
        // 分享失败回调
        onError: (errorCode, msg) => {
          // 设置回调结果为失败
          this.callbackResult = false;
          // 保存错误信息
          this.errMsg = msg
          this.errCode = errorCode
          Logger.i("shareCallback", `failed, code: ${errorCode}, msg: ${msg}`);
        }
      })
    }, photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE);
  }

接入发布单视频能力

  1. 视频分享请求构建
  • 初始化ArrayList容器
  • 将视频URI添加到容器
  • 设置请求的mediaUri属性为容器对象
  1. 对象创建:createSingleVideoPublish(APPID)生成视频分享请求对象(区别于图片接口)
  2. 媒体列表管理:
  3. 关键参数配置
  4. callbackLocalEntry指定回调入口为"EntryAbility"(需与实际Ability名称一致)
  5. harmonyAppId显式赋值(通过独立变量harmonyAppID注入,需确保配置有效性)
  6. SDK调用与响应处理

通过kwaiOpenSdk.createApi().share()发起分享请求,传入上下文对象和配置参

typescript 复制代码
  // 发布单视频功能实现
  fn3 = () => {
    // 调用媒体选择方法,指定视频类型
    this.selectMedia<string>((url: string) => {
      // 创建单视频分享请求对象
      let shareRequest = createSingleVideoPublish(APPID);
      // 创建媒体URI列表
      let list: ArrayList<string> = new ArrayList();
      // 添加选中的视频URI
      list.add(url);
      // 设置媒体URI列表
      shareRequest.mediaUri = list;
      // 设置回调入口
      shareRequest.callbackLocalEntry = "EntryAbility";
      // 重要提示,这行代码不要复制
      shareRequest.harmonyAppId = harmonyAppID
      // 调用SDK分享接口
      kwaiOpenSdk.createApi().share(this.context, shareRequest, {
        // 分享成功回调
        onSuccess: (res) => {
          // 设置回调结果为成功
          this.callbackResult = true;
          Logger.i("shareCallback", "success.......");
        },
        // 分享失败回调
        onError: (errorCode, msg) => {
          // 设置回调结果为失败
          this.callbackResult = false;
          // 保存错误信息
          this.errMsg = msg
          this.errCode = errorCode
          Logger.i("shareCallback", `failed, code: ${errorCode}, msg: ${msg}`);
        }
      })
    }, photoAccessHelper.PhotoViewMIMETypes.VIDEO_TYPE);
  }

发布单图-发布单视频的错误码

错误码

描述

999

成功

1000

appId is empty

1001

request is error

1002

request is empty

1003

request bundle id is empty

1004

request harmony app id is empty

1005

not install kuaishou app

3000

用户取消

3001

框架出错,请反馈客服

3002

参数错误,包含shareType、appId、harmonyId、mediaUri等相关参数

3003

打开发布页失败

3004

网络错误

3005

发布请求过于频繁(3s内重复调用)

3006

视频size超过最大大小

3007

图片size超过最大大小

3008

拒绝当次分享动作;如果是发布视频:请检查视频长度

3009

鉴权失败

完整 Index.ets 代码

typescript 复制代码
// 导入快手开放平台SDK
import { kwaiOpenSdk } from '@kwai_open_platform/opensdk/src/main/ets/KwaiOpensdk';
// 导入AbilityKit相关组件
import { common } from '@kit.AbilityKit';
// 导入授权请求模型
import { AuthRequest } from '@kwai_open_platform/opensdk/src/main/ets/model/request/AuthRequest';
// 导入授权响应模型
import { AuthResponse } from '@kwai_open_platform/opensdk/src/main/ets/model/response/AuthResponse';
// 导入日志工具
import { Logger } from '@kwai_open_platform/opensdk/src/main/ets/utils/Logger';
// 导入分享请求模型创建函数
import {
  createSingleImagePublish,
  createSingleVideoPublish
} from '@kwai_open_platform/opensdk/src/main/ets/model/request/ShareRequest';
// 导入ArkTS集合框架
import { ArrayList } from '@kit.ArkTS';
// 导入媒体库访问助手
import { photoAccessHelper } from '@kit.MediaLibraryKit';
// 导入文件操作相关工具
import { fileIo, fileUri } from '@kit.CoreFileKit';

// 定义快手应用ID
const APPID = "ks669910448092164647"

// 定义鸿蒙应用ID
const harmonyAppID: string = "6917560710208292268";

@Entry
@Component
struct Index {
  // 获取UIAbility上下文
  context = this.getUIContext().getHostContext() as common.UIAbilityContext;
  // 回调结果状态
  @State callbackResult: boolean = false;
  // 授权码
  @State authCode: string = "";
  // 错误信息
  @State errMsg: string = "";
  // 错误码
  @State errCode: number = -1;

  aboutToAppear(): void {
    // 初始化快手SDK
    kwaiOpenSdk.init(this.context);
  }

  // 授权功能实现
  fn1 = () => {
    {
      // 创建授权请求对象
      let request = new AuthRequest(APPID);
      // 设置必需的权限范围
      request.requiredScopes = "user_phone,user_info";
      // 设置可选权限范围0
      request.optional0Scopes = "user_base,share_media,following,share_message"
      // 设置可选权限范围1
      request.optional1Scopes = "user_growth_distribution,message,live,relation"
      // 设置回调入口
      request.callbackLocalEntry = "EntryAbility";
      // 设置Ability上下文
      request.abilityContext = this.context;
      // 重要提示,这行代码不要复制
      request.harmonyAppId = harmonyAppID
      // 调用SDK授权接口
      kwaiOpenSdk.createApi().authorize(this.context, request, {
        // 授权成功回调
        onSuccess: (res) => {
          Logger.i("authCallback", "success.......");
          // 保存授权码
          this.authCode = (res as AuthResponse).code;
          // 设置回调结果为成功
          this.callbackResult = true;
        },
        // 授权失败回调
        onError: (errorCode, msg) => {
          Logger.i("authCallback", `failed, code: ${errorCode}, msg: ${msg}`);
          // 保存错误信息
          this.errMsg = msg
          this.errCode = errorCode
          // 设置回调结果为失败
          this.callbackResult = false;
        }
      })
    }
  }
  // 发布单图功能实现
  fn2 = () => {
    // 调用媒体选择方法,指定图片类型
    this.selectMedia<string>((url: string) => {
      // 创建单图分享请求对象
      let shareRequest = createSingleImagePublish(APPID);
      // 创建媒体URI列表
      let list: ArrayList<string> = new ArrayList();
      // 添加选中的图片URI
      list.add(url);
      // 设置媒体URI列表
      shareRequest.mediaUri = list;
      // 设置回调入口
      shareRequest.callbackLocalEntry = "EntryAbility";
      // 重要提示,这行代码不要复制
      shareRequest.harmonyAppId = harmonyAppID

      // 调用SDK分享接口
      kwaiOpenSdk.createApi().share(this.context, shareRequest, {
        // 分享成功回调
        onSuccess: (res) => {
          // 设置回调结果为成功
          this.callbackResult = true;
          Logger.i("shareCallback", "success.......");
        },
        // 分享失败回调
        onError: (errorCode, msg) => {
          // 设置回调结果为失败
          this.callbackResult = false;
          // 保存错误信息
          this.errMsg = msg
          this.errCode = errorCode
          Logger.i("shareCallback", `failed, code: ${errorCode}, msg: ${msg}`);
        }
      })
    }, photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE);
  }
  // 发布单视频功能实现
  fn3 = () => {
    // 调用媒体选择方法,指定视频类型
    this.selectMedia<string>((url: string) => {
      // 创建单视频分享请求对象
      let shareRequest = createSingleVideoPublish(APPID);
      // 创建媒体URI列表
      let list: ArrayList<string> = new ArrayList();
      // 添加选中的视频URI
      list.add(url);
      // 设置媒体URI列表
      shareRequest.mediaUri = list;
      // 设置回调入口
      shareRequest.callbackLocalEntry = "EntryAbility";
      // 重要提示,这行代码不要复制
      shareRequest.harmonyAppId = harmonyAppID
      // 调用SDK分享接口
      kwaiOpenSdk.createApi().share(this.context, shareRequest, {
        // 分享成功回调
        onSuccess: (res) => {
          // 设置回调结果为成功
          this.callbackResult = true;
          Logger.i("shareCallback", "success.......");
        },
        // 分享失败回调
        onError: (errorCode, msg) => {
          // 设置回调结果为失败
          this.callbackResult = false;
          // 保存错误信息
          this.errMsg = msg
          this.errCode = errorCode
          Logger.i("shareCallback", `failed, code: ${errorCode}, msg: ${msg}`);
        }
      })
    }, photoAccessHelper.PhotoViewMIMETypes.VIDEO_TYPE);
  }

  build() {
    Column({ space: 10 }) {
      Button("授权")
        .onClick(this.fn1)
      Button("发布单图")
        .onClick(this.fn2)
      Button("发布单视频")
        .onClick(this.fn3)
    }
    .height('100%')
    .width('100%')
  }

  // 媒体选择通用方法
  private selectMedia<T>(
    callback: (t: T) => void,
    type: photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE | photoAccessHelper.PhotoViewMIMETypes.VIDEO_TYPE,
    num: number = 1
  ) {
    // 创建照片选择选项
    let photoOptions = new photoAccessHelper.PhotoSelectOptions();
    // 设置MIME类型(图片或视频)
    photoOptions.MIMEType = type;
    // 设置最大选择数量
    photoOptions.maxSelectNumber = num;

    // 创建照片选择器
    let picker = new photoAccessHelper.PhotoViewPicker();
    // 调用选择方法
    picker.select(photoOptions).then((photoSelectResult: photoAccessHelper.PhotoSelectResult) => {
      // 获取选中的URI列表
      let uris: Array<string> = photoSelectResult.photoUris;
      if (uris.length > 0) {
        // 获取第一个URI
        let str = uris[0];
        // 提取文件名
        let fileName = str.substring(str.lastIndexOf('/'));
        // 构建目标文件路径
        let desFilePath = this.context.getApplicationContext().tempDir + fileName;
        // 打开源文件(只读)
        let srcFile = fileIo.openSync(str, fileIo.OpenMode.READ_ONLY);
        // 打开目标文件(写,如不存在则创建)
        let desFile = fileIo.openSync(desFilePath, fileIo.OpenMode.WRITE_ONLY | fileIo.OpenMode.CREATE);
        // 复制文件内容
        fileIo.copyFileSync(srcFile.fd, desFile.fd)
        // 回调处理,传递文件URI
        callback?.(fileUri.getUriFromPath(desFilePath) as T);
      } else {
        // 未选择资源时显示提示
        this.getUIContext().getPromptAction().showToast({
          message: '没有选择资源'
        })
      }
    }).catch((error: BusinessError) => {
      // 选择出错时显示提示
      this.getUIContext().getPromptAction().showToast({
        message: '选择资源error'
      })
    })
  }
}

参考文档

  1. @kwai_open_platform/opensdk(V1.0.1)

open.kuaishou.com/platformDoc...

  1. 快手接入鸿蒙应用指南

ohpm.openharmony.cn/#/cn/detail...

相关推荐
phltxy14 分钟前
Vue3入门指南:从环境搭建到数据响应式,开启高效前端开发之旅
前端·javascript·vue.js
小飞大王66615 分钟前
CSS基础知识
前端·css
Charlie_lll17 分钟前
学习Three.js–风车星系
前端·three.js
代码游侠18 分钟前
学习笔记——Linux内核与嵌入式开发1
linux·运维·前端·arm开发·单片机·嵌入式硬件·学习
一起养小猫34 分钟前
Flutter for OpenHarmony 实战:电子英汉词典完整开发指南
flutter·harmonyos
玩电脑的辣条哥35 分钟前
幽灵回复AI已回复但前端不显示的排查与修复
前端·人工智能
石去皿1 小时前
轻量级 Web 应用 —— 把一堆图片按指定频率直接拼成视频,零特效、零依赖、零命令行
前端·音视频
星夜落月1 小时前
Web-Check部署全攻略:打造个人网站监控与分析中心
运维·前端·网络
冰暮流星2 小时前
javascript之双重循环
开发语言·前端·javascript
爱敲点代码的小哥2 小时前
C#视觉模板匹配与动态绘制实战(绘制和保存,加载tb块,处理vpp脚本的方式)
前端·javascript·信息可视化