Skip to content
🌊海洋蓝
🌸樱花粉
🍃森林绿
🔮幻夜紫
🌙暗夜黑

HarmonyOS6 接入快手 SDK 指南

介绍

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

效果一览

环境准备

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

环境要求

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

接入步骤

  1. 在模块中引入 SDK依赖,如 Entry模块
json
  "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://... 当其他应用或系统触发这类链接时,鸿蒙系统会尝试启动当前应用并传递参数。
  2. 典型应用场景
    • 跨应用跳转:其他应用通过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 表示应用已经启动的,然后被重新拉起

typescript
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中初始化
typescript
  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如果没有安装快手,会跳转到应用市场安装。不传则不会跳转到应用市场
typescript
  // 授权功能实现
  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成功
1000appId is empty
1001request is error
1002request is empty
1003request bundle id is empty
1004request harmony app id is empty
1005not install kuaishou app
2000auth request requiredScopes is empty
2002无效的授权内容
2101提交授权信息失败,缺少授权参数
100200100请求缺少参数或参数类型错误
100200101无效的client,无效的 app 或 developer,可能是验证参数不正确(回调地址等信息)
100200102请求被拒绝,可能是无效的 token 等
100200103请求的 responseType 错误
100200104请求的 grantType 不支持
100200105请求的 code 错误
100200106请求的 scope 错误
100200107无效的 openid
100200108access_token过期
100200109用户取消该 app 授权
100200110用户授权过期
100200111用户未授权过
100200112bundleToken不合法
100200113refresh_token过期
100200500服务内部错误

接入发布单图能力

  1. 分享请求构建

    1. 使用createSingleImagePublish(APPID)创建单图分享请求对象

    2. 初始化ArrayList存储媒体URI列表,并添加选中图片的URI

    3. 设置callbackLocalEntry指定回调入口为EntryAbility

  2. 关键参数配置

    1. 显式设置harmonyAppId参数(注释提示该行代码具有重要性)

    2. 通过上下文this.context保持与当前页面的关联

  3. 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. 视频分享请求构建

    1. 对象创建:createSingleVideoPublish(APPID)生成视频分享请求对象(区别于图片接口)
    2. 媒体列表管理:
    • 初始化ArrayList容器
    • 将视频URI添加到容器
    • 设置请求的mediaUri属性为容器对象
  2. 关键参数配置

    1. callbackLocalEntry指定回调入口为"EntryAbility"(需与实际Ability名称一致)

    2. harmonyAppId显式赋值(通过独立变量harmonyAppID注入,需确保配置有效性)

  3. 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成功
1000appId is empty
1001request is error
1002request is empty
1003request bundle id is empty
1004request harmony app id is empty
1005not 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)

    https://open.kuaishou.com/platformDocs/develop/mobile-app/Harmony-OS.html#一、设计目标

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

    https://ohpm.openharmony.cn/#/cn/detail/@kwai_open_platform%2Fopensdk

联系我

可以加我微信,带你了解更多互联网 HarmonyOS相关的资讯。

Released under the MIT License.