更新记录
1.1.0(2026-04-07)
【重要更新】QQ分享API优化调整
1.0.9(2026-04-03)
Harmony平台 支持分享到QQ空间
1.0.8(2026-04-02)
新增部分调试日志
查看更多平台兼容性
uni-app(4.36)
| Vue2 | Vue2插件版本 | Vue3 | Vue3插件版本 | Chrome | Safari | app-vue | app-vue插件版本 | app-nvue | app-nvue插件版本 | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 | 鸿蒙插件版本 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | 1.0.0 | √ | 1.0.0 | × | × | √ | 1.0.2 | √ | 1.0.2 | 5.0 | 1.0.2 | 12 | 1.0.2 | 15 | 1.0.4 |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
uni-app x(4.36)
| Chrome | Safari | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 | 鸿蒙插件版本 | 微信小程序 |
|---|---|---|---|---|---|---|---|---|
| × | × | 5.0 | 1.0.0 | 12 | 1.0.0 | 15 | 1.0.4 | × |
tt-qq-sdk
🚀 腾讯QQ SDK插件,为 uni-app x 提供完整的QQ集成解决方案,包含登录、分享、用户信息等功能
📖 目录
SDK版本信息
| 平台 | 版本 |
|---|---|
| iOS | 3.5.18 |
| Android | 3.5.18 |
| Harmony | 1.0.4 |
📚 推荐阅读: QQ互联官方开发文档
重要调整(v1.1.0)
以下为本次升级涉及的参数与接口调整(建议重点关注):
-
分享接口拆分(不再共用一套参数)
share(options):仅用于分享到 QQ 好友,使用TTQQShareToFriendOptionsshareToQzone(options):仅用于分享到 QQ 空间,使用TTQQShareToQzoneOptions
-
空间分享不再使用
typeshareToQzone(options)不需要type- Harmony 平台内部固定映射到 SDK
type=3009
-
字段命名统一为
targetUrl- 旧字段
href已统一为targetUrl - 好友分享中不再区分
videoUrl/musicUrl,统一用targetUrl
- 旧字段
-
参数收敛
TTQQShareToQzoneOptions仅保留有效字段:title、desc、previewImagePath、targetUrlscene已移除,不再通过一个字段切换好友/空间
-
关键必填规则(与实现一致)
- Android:
shareToQzone的targetUrl为必填(缺失会失败,错误码407) - Android:
share(type=0)文本分享必须传targetUrl(实际按图文能力落地) - iOS:
share(type=1/2/3/4)需要previewImagePath,其中type=2/3/4建议必传targetUrl
- Android:
如你从旧版本迁移,请优先检查:是否仍在传
scene/href/videoUrl/musicUrl,并改为当前参数结构。
平台支持说明
支持平台
- ✅ Android - 完整功能支持
- ✅ iOS - 完整功能支持
- ✅ Harmony - 部分功能支持(登录、分享)
平台差异对比
| 功能 | Android | iOS | Harmony |
|---|---|---|---|
| 基础功能 | |||
| SDK初始化 | ✅ | ✅ | ✅ |
| 检测QQ安装 | ✅ | ✅ | ✅ |
| 隐私协议检查 | ✅ | ✅ | ❌ |
| 设置隐私协议 | ✅ | ✅ | ❌ |
| 登录功能 | |||
| QQ登录 | ✅ | ✅ | ✅ |
| 获取用户信息 | ✅ | ✅ | ❌ |
| 退出登录 | ✅ | ✅ | ❌ |
| 分享功能 | |||
| 文本分享 | ✅ | ✅ | ✅ |
| 图片分享 | ✅ | ✅ | ✅ |
| 视频分享 | ✅ | ✅ | ❌ |
| 网页分享 | ✅ | ✅ | ❌ |
| 音乐分享 | ✅ | ✅ | ❌ |
Harmony平台概览
🔐 登录流程差异
- Android/iOS: 直接返回
accessToken、openid、expireTime - Harmony: 只返回
authCode,需要通过服务端获取完整登录信息
📤 分享功能差异
- Android/iOS: 使用传统参数(title、desc、imagePath等)
- Harmony:
shareJson分三种:好友图文 ark、好友大图、QQ 空间,对应share/shareToQzone与不同 JSON 形态;均需后台签名(详见「Harmony平台特殊说明」→「1.2 鸿蒙 shareJson 三种形态」)
🚫 不支持的功能
- 隐私协议相关API
- 获取用户信息
- 退出登录
- 视频、网页、音乐分享
🚨 重要提示
⚠️ 必须使用自定义基座运行,否则无法找到插件方法
⚠️ Android/iOS 平台必须用户同意隐私协议,否则相关功能无法使用
环境配置
前置条件
- 在QQ互联开放平台申请移动应用
- 获取
AppID - 配置应用包名、签名和通用链接
iOS平台配置
1. 配置 URL Scheme
无需在项目根目录添加或修改 Info.plist。请直接编辑插件内的 uni_modules/tt-qq-sdk/utssdk/app-ios/Info.plist,将以下配置项补充为您的实际值:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- 允许查询QQ应用 -->
<key>LSApplicationQueriesSchemes</key>
<array>
<string>mqqapi</string>
<string>mqq</string>
<string>mqqOpensdkSSoLogin</string>
<string>mqqconnect</string>
<string>mqqopensdkdataline</string>
<string>mqqopensdkgrouptribeshare</string>
<string>mqqopensdkfriend</string>
<string>mqqopensdkapi</string>
<string>mqqopensdkapiV2</string>
<string>mqqopensdkapiV3</string>
<string>mqzoneopensdk</string>
<string>wtloginmqq</string>
<string>wtloginmqq2</string>
<string>mqqwpa</string>
<string>mqzone</string>
<string>mqzonev2</string>
<string>mqzoneshare</string>
<string>wtloginqzone</string>
<string>mqzonewx</string>
<string>mqzoneopensdkapiV2</string>
<string>mqzoneopensdkapi19</string>
<string>mqzoneopensdkapi</string>
<string>mqzoneopensdk</string>
</array>
<!-- URL Scheme 配置 -->
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>QQ</string>
<key>CFBundleURLSchemes</key>
<array>
<!-- 这里填写您在QQ互联申请的 AppID,格式为: tencent + AppID -->
<string>tencent您的QQ_AppID</string>
</array>
</dict>
</array>
</dict>
</plist>
2. 配置通用链接 (Universal Link)
📖 详细配置请参考: uni官方文档-通用链接
Harmony平台配置
⚠️ 重要授权说明:
- uni-app 项目: 由于官方目前不支持试用以及普通授权,建议通过示例中的 uni-app x 项目测通后购买源码授权使用
- uni-app x 项目: 可直接使用
1. 配置 module.json5
在项目根目录的 harmony-configs/entry/src/main/module.json5 文件中添加以下配置:
{
"module": {
"name": "entry",
"type": "entry",
"description": "$string:module_desc",
"mainElement": "EntryAbility",
"deviceTypes": [
"phone",
"tablet",
"2in1"
],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:main_pages",
"querySchemes": [
"https",
"qqopenapi"
],
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:layered_image",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": [
"entity.system.home",
"entity.system.browsable"
],
"actions": [
"action.system.home",
"ohos.want.action.viewData"
],
"uris": [
{
"scheme": "qqopenapi", // 接收 QQ 回调数据
"host": "您的QQ_AppID", // 业务申请的互联 appId,如果填错会导致 QQ 无法回调
"pathRegex": "\\b(auth|share)\\b",
"linkFeature": "Login"
}
]
}
]
}
],
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
}
}
2. 重要配置说明
⚠️ 关键配置项:
querySchemes: 必须包含"qqopenapi"用于处理QQ回调uris.scheme: 必须设置为"qqopenapi"uris.host: 必须填写您在QQ互联开放平台申请的 AppIDuris.pathRegex: 用于匹配登录和分享回调路径requestPermissions: 必须申请网络权限
⚠️ 注意事项:
- 确保在QQ互联开放平台正确配置应用包名和签名
host字段必须与QQ互联开放平台配置的AppID完全一致- 测试时请使用与平台配置相同的签名文件
Android平台配置
1. 配置 AndroidManifest.xml
无需在项目根目录添加或修改 AndroidManifest.xml。请直接编辑插件内的 uni_modules/tt-qq-sdk/utssdk/app-android/AndroidManifest.xml,将以下配置项补充为您的实际值:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="您的应用包名">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application>
<!-- QQ授权Activity -->
<activity
android:name="com.tencent.tauth.AuthActivity"
android:exported="true"
android:launchMode="singleTask"
android:noHistory="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- 这里填写您在QQ互联申请的AppID,注意不需要tencent前缀 -->
<data android:scheme="您的QQ_AppID" />
</intent-filter>
</activity>
<!-- QQ分享Activity -->
<activity
android:name="com.tencent.connect.common.AssistActivity"
android:exported="true"
android:configChanges="orientation|keyboardHidden|screenSize"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
</application>
</manifest>
2. 重要配置说明
⚠️ 关键配置项:
android:scheme必须填写您在QQ互联开放平台申请的 AppIDAuthActivity的android:exported="true"必须设置,否则无法接收QQ回调AssistActivity用于处理分享功能,必须包含
⚠️ 注意事项:
- 确保在QQ互联开放平台正确配置应用包名和签名
- 测试时请使用与平台配置相同的签名文件
- Android平台的scheme配置与iOS不同,不需要添加"tencent"前缀
快速开始
1. 导入插件
import { getTTQQSDK } from '@/uni_modules/tt-qq-sdk';
export default {
data() {
return {
qqSDK: null as any,
}
},
onLoad() {
// 获取QQ SDK实例
this.qqSDK = getTTQQSDK()
// 注册QQ SDK
this.initQQSDK()
},
methods: {
// 初始化QQ SDK
initQQSDK() {
// SDK初始化代码见下方
}
}
}
2. 初始化 SDK
initQQSDK() {
if (!this.qqSDK) {
console.error('QQ SDK初始化失败')
return
}
// 设置用户已同意隐私协议(必须)
this.qqSDK.setIsAgreedAuthorization(true)
this.qqSDK.register({
appid: "您的QQ_AppID", // 必填:QQ互联申请的AppID
universalLink: "您的通用链接", // iOS必填:通用链接
success: (res) => {
console.log("✅ QQ SDK初始化成功");
// 可以在这里进行后续操作,如检测QQ是否安装
this.checkQQInstalled()
},
fail: (err) => {
console.error("❌ QQ SDK初始化失败:", err);
uni.showToast({
title: 'QQ SDK初始化失败',
icon: 'error'
})
}
});
}
基础使用
检测QQ是否安装
checkQQInstalled() {
const isInstalled = this.qqSDK?.isInstall()
if (!isInstalled) {
uni.showModal({
title: '提示',
content: '请先安装QQ客户端',
showCancel: false
})
return false
}
return true
}
隐私协议检查
checkPrivacyAgreement() {
const isAgreed = this.qqSDK?.isAgreedAuthorization()
if (!isAgreed) {
uni.showModal({
title: '隐私协议',
content: '使用QQ功能需要同意隐私授权协议',
showCancel: false
})
return false
}
return true
}
功能介绍
QQ登录授权
💡 QQ登录需要用户先同意隐私协议,然后进行授权操作
平台差异说明
Android/iOS 平台
- 直接返回完整的登录信息:
accessToken、openid、expireTime - 支持隐私协议检查和设置
- 支持获取用户信息和退出登录
Harmony平台
- 只返回
authCode,需要通过服务端获取完整登录信息 - 不支持隐私协议相关API
- 不支持获取用户信息和退出登录
参数说明
TTQQLoginOptions
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| success | function | ❌ | 登录成功回调函数 |
| fail | function | ❌ | 登录失败回调函数 |
| complete | function | ❌ | 登录完成回调函数 |
返回值 TTQQLoginSuccess
| 参数 | 类型 | 说明 | 平台支持 |
|---|---|---|---|
| accessToken | string | Access Token凭证,用于后续访问各开放接口 | Android/iOS |
| expireTime | string | Access Token的失效期 | Android/iOS |
| openid | string | 用户授权登录后对该用户的唯一标识 | Android/iOS |
| authCode | string | 授权码,Harmony平台专用 | Harmony |
示例代码
Android/iOS 平台登录
// QQ登录
handleQQLogin() {
// 先检查QQ是否安装
if (!this.checkQQInstalled()) {
return
}
// 检查隐私协议
if (!this.checkPrivacyAgreement()) {
return
}
this.qqSDK?.login({
success: (res) => {
console.log("✅ QQ登录成功:", res);
console.log("AccessToken:", res.accessToken);
console.log("OpenID:", res.openid);
console.log("过期时间:", res.expireTime);
// 保存登录信息
uni.setStorageSync('qqLoginInfo', {
"accessToken": res.accessToken,
"openid": res.openid,
"expireTime": res.expireTime
} as UTSJSONObject);
// 登录成功后获取用户信息
this.getUserInfo()
},
fail: (err) => {
console.error("❌ QQ登录失败:", err);
this.handleLoginError(err)
},
complete: (res) => {
console.log("QQ登录完成:", res);
}
});
}
Harmony平台登录
// Harmony平台QQ登录
handleHarmonyQQLogin() {
// 检查QQ是否安装
if (!this.checkQQInstalled()) {
return
}
this.qqSDK?.login({
success: (res) => {
console.log("✅ Harmony平台QQ登录成功");
console.log("AuthCode:", res.authCode);
// 保存authCode
uni.setStorageSync('qqLoginInfo', {
"authCode": res.authCode,
"platform": "harmony"
} as UTSJSONObject);
// 通过服务端获取完整登录信息
this.getTokenFromServer(res.authCode);
},
fail: (err) => {
console.error("❌ Harmony平台QQ登录失败:", err);
this.handleLoginError(err)
}
});
}
// 通过authCode从服务端获取token
getTokenFromServer(authCode: string) {
uni.request({
url: 'https://your-server.com/api/qq/getToken',
method: 'POST',
data: {
authCode: authCode,
appId: "您的QQ平台AppID"
},
success: (res) => {
console.log("✅ 获取token成功:", res.data);
// 保存完整的登录信息
uni.setStorageSync('qqLoginInfo', {
"accessToken": res.data.accessToken,
"openid": res.data.openid,
"expireTime": res.data.expireTime,
"platform": "harmony"
} as UTSJSONObject);
uni.showToast({
title: '登录成功',
icon: 'success'
});
},
fail: (err) => {
console.error("❌ 获取token失败:", err);
uni.showToast({
title: '获取登录信息失败',
icon: 'error'
});
}
});
}
跨平台兼容登录
// 兼容所有平台的登录方法
handleUniversalLogin() {
if (!this.checkQQInstalled()) {
return
}
// #ifndef APP-HARMONY
// Android/iOS 平台需要检查隐私协议
if (!this.checkPrivacyAgreement()) {
return
}
// #endif
this.qqSDK?.login({
success: (res) => {
// #ifndef APP-HARMONY
// Android/iOS 平台处理
console.log("AccessToken:", res.accessToken);
console.log("OpenID:", res.openid);
console.log("过期时间:", res.expireTime);
uni.setStorageSync('qqLoginInfo', {
"accessToken": res.accessToken,
"openid": res.openid,
"expireTime": res.expireTime
} as UTSJSONObject);
this.getUserInfo();
// #endif
// #ifdef APP-HARMONY
// Harmony平台处理
console.log("AuthCode:", res.authCode);
uni.setStorageSync('qqLoginInfo', {
"authCode": res.authCode,
"platform": "harmony"
} as UTSJSONObject);
this.getTokenFromServer(res.authCode);
// #endif
},
fail: (err) => {
this.handleLoginError(err);
}
});
}
// 处理登录错误
handleLoginError(error: any) {
const errCode = error.errCode;
const errMsg = error.errMsg;
switch(errCode) {
case 201:
console.log('用户取消登录');
break;
case 202:
uni.showToast({
title: '登录失败',
icon: 'error'
});
break;
case 203:
uni.showModal({
title: '隐私协议',
content: '使用QQ功能需要同意隐私授权协议',
showCancel: false
});
break;
default:
uni.showToast({
title: errMsg || '登录失败',
icon: 'error'
});
break;
}
}
使用登录信息
登录成功后,您将获得以下重要信息:
// 处理登录成功信息
handleLoginSuccess(loginResult: any) {
const { accessToken, openid, expireTime } = loginResult;
// 保存到本地存储
uni.setStorageSync('qqLoginInfo', {
accessToken,
openid,
expireTime: parseInt(expireTime) // 转换为时间戳
});
// 检查token是否过期
const now = Date.now() / 1000;
const expired = parseInt(expireTime) < now;
if (expired) {
console.log('⚠️ Token已过期,需要重新登录');
this.reLogin();
return;
}
// Token有效,可以使用accessToken调用QQ开放接口
console.log('✅ Token有效,可以进行后续操作');
// 获取用户详细信息
this.getUserInfo();
}
// 获取保存的登录信息
getStoredLoginInfo() {
const loginInfo = uni.getStorageSync('qqLoginInfo') as UTSJSONObject | null;
if (loginInfo != null && loginInfo["accessToken"] != null) {
// 检查是否过期
const now = Date.now() / 1000;
const expireTime = loginInfo["expireTime"] as string;
if (parseInt(expireTime) > now) {
return loginInfo;
} else {
// 清除过期信息
uni.removeStorageSync('qqLoginInfo');
return null;
}
}
return null;
}
// 使用accessToken调用QQ开放接口(示例)
allQQApi(apiPath: string, params: any = {}) {
const loginInfo = this.getStoredLoginInfo();
if (!loginInfo) {
console.error('未登录或token已过期');
return null;
}
try {
const response = await uni.request({
url: `https://graph.qq.com/${apiPath}`,
data: {
access_token: loginInfo["accessToken"],
oauth_consumer_key: loginInfo["openid"],
openid: loginInfo["openid"]
//...params
}
});
return response.data;
} catch (error) {
console.error('调用QQ API失败:', error);
return null;
}
}
获取用户信息
💡 获取QQ用户信息(需要先登录成功)
参数说明
TTQQGetUserInfoOptions
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| success | function | ❌ | 获取成功回调函数 |
| fail | function | ❌ | 获取失败回调函数 |
| complete | function | ❌ | 获取完成回调函数 |
返回值 TTQQGetUserInfoSuccess
| 参数 | 类型 | 说明 |
|---|---|---|
| response | Map<String, any> | 用户信息数据,包含昵称、头像等 |
示例代码
// 获取用户信息
getUserInfo() {
this.qqSDK?.getUserInfo({
success: (res) => {
console.log("✅ 获取用户信息成功:", res.response);
// 常用用户信息字段
const nickname = res.response.get('nickname'); // 昵称
const figureurl = res.response.get('figureurl_qq_1'); // 头像URL
const gender = res.response.get('gender'); // 性别
const province = res.response.get('province'); // 省份
const city = res.response.get('city'); // 城市
// 处理用户信息
this.handleUserInfo({
nickname,
avatar: figureurl,
gender,
province,
city
});
},
fail: (err) => {
console.error("❌ 获取用户信息失败:", err);
uni.showToast({
title: '获取用户信息失败',
icon: 'error'
});
},
complete: (res) => {
console.log("获取用户信息完成:", res);
}
});
}
// 处理用户信息
handleUserInfo(userInfo: any) {
// 保存用户信息到本地存储
uni.setStorageSync('qqUserInfo', userInfo);
// 更新页面显示
this.userInfo = userInfo;
// 跳转到主页面或其他操作
uni.switchTab({
url: '/pages/tabBar/home/home'
});
}
QQ分享功能
💡
share(options)(好友)支持type选择;shareToQzone(options)(空间)不需要type,通过targetUrl传业务链接
平台差异说明
Android/iOS 平台
- 支持文本、图片、视频、网页、音乐分享
- 使用传统参数:
title、desc、imagePath、targetUrl等 - 支持分享到QQ好友和QQ空间
Harmony平台
- 只支持文本和图片分享(ark类型2)
- 使用专用参数:
shareJson、timestamp、nonce、shareJsonSign - 需要业务后台提供签名数据
分享类型与接口
分享类型 (type)
-
0- 纯文本分享 ✅ Android/iOS(Harmony 不直接使用该type) -
1- 图片分享 ✅ Android/iOS(Harmony 不直接使用该type) -
2- 视频分享 ✅ Android/iOS -
3- 新闻/网页分享 ✅ Android/iOS -
4- 音乐分享 ✅ Android/iOS -
share(options)- 分享到QQ好友 -
shareToQzone(options)- 分享到QQ空间
参数说明
TTQQShareToFriendOptions / TTQQShareToQzoneOptions
| 参数 | 类型 | 必填 | 说明 | 平台支持 |
|---|---|---|---|---|
| 通用参数 | ||||
| type | number | ✅ | 分享类型,见上表(仅 TTQQShareToFriendOptions / share(options) 使用;Harmony会忽略) |
好友分享 |
| Android/iOS 专用参数 | ||||
| title | string | 条件 | 分享标题(纯文本时最长1536字符,其他类型最长30字符) | Android/iOS |
| desc | string | 条件 | 分享描述(最长40字符,纯文本分享不需要) | Android/iOS |
| imagePath | string | 条件 | 图片本地路径(图片分享时必填,限制5M) | Android/iOS |
| previewImagePath | string | 条件 | 预览图本地路径(限制1M) | Android/iOS |
| targetUrl | string | 条件 | 跳转链接(Android: 文本/视频/网页/音乐/空间必填;iOS: 视频/网页/音乐建议必填,空间建议必填) | Android/iOS |
| Harmony平台专用参数 | ||||
| shareJson | string | ✅ | Harmony 必填:形态随场景而变——好友图文 ark / 好友大图 / QQ 空间 三套 JSON 不同,见「Harmony平台特殊说明」1.2 节 | Harmony |
| timestamp | number | ✅ | 分享时的当前时间戳(Harmony平台必需) | Harmony |
| nonce | number | ✅ | 随机自然数(Harmony平台必需) | Harmony |
| shareJsonSign | string | ✅ | shareJson + timestamp + nonce 三部分签名(Harmony平台必需) | Harmony |
| openId | string | ❌ | 用户openid(Harmony平台分享时需要) | Harmony |
ℹ️
shareToQzone(options)不需要传type。Harmony 平台固定映射到 SDKtype=3009,Android/iOS 由插件内部按空间分享规则处理。 ℹ️shareToQzone(options)仅保留有效字段:title、desc、previewImagePath、targetUrl(Harmony 仍使用shareJson/timestamp/nonce/shareJsonSign/openId)。
各平台传参速查(推荐)
| 场景 | Android 必填 | iOS 必填 | Harmony 必填 | 备注 |
|---|---|---|---|---|
share 文本(type=0) |
type、title、targetUrl |
type、title |
shareJson、timestamp、nonce、shareJsonSign |
Android 文本实际按图文能力落地;Harmony 忽略 type,走 ark 分享 |
share 图片(type=1) |
type、title、desc、imagePath |
type、title、desc、imagePath、previewImagePath |
shareJson、timestamp、nonce、shareJsonSign |
iOS 图片分享要求预览图;Harmony 由 shareJson 决定内容 |
share 视频(type=2) |
type、title、desc、targetUrl |
type、title、desc、targetUrl、previewImagePath |
shareJson、timestamp、nonce、shareJsonSign |
Android/iOS 均通过 targetUrl 传视频落地链接 |
share 网页(type=3) |
type、title、desc、targetUrl |
type、title、desc、targetUrl、previewImagePath |
shareJson、timestamp、nonce、shareJsonSign |
iOS 缺少 targetUrl 会返回错误码 408 |
share 音乐(type=4) |
type、title、desc、targetUrl |
type、title、desc、targetUrl、previewImagePath |
shareJson、timestamp、nonce、shareJsonSign |
Android/iOS 均通过 targetUrl 传音乐落地链接 |
shareToQzone 空间分享 |
title、targetUrl |
title、previewImagePath(targetUrl 建议必填) |
shareJson、timestamp、nonce、shareJsonSign |
不使用 type;Harmony 映射到 SDK type=3009 |
ℹ️ Harmony 平台
openId为可选参数;鸿蒙下shareJson三种形态见「Harmony平台特殊说明」1.2;Android/iOS 仍以title/desc/...传统入参为主,插件不对鸿蒙shareJson做字段白名单校验。 ⚠️ Android 空间分享targetUrl为硬性必填,缺失会失败(错误码407)。
使用示例
1. 分享文本
⚠️ Android 平台不支持纯文本分享,
type=0时必须传targetUrl,实际按图文消息分享。
shareText() {
this.qqSDK?.share({
type: 0,
title: '这是一条文本消息',
targetUrl: 'https://www.example.com', // Android 文本分享必填
success: (res) => {
console.log('✅ 文本分享成功');
uni.showToast({ title: '分享成功' });
},
fail: (err) => {
console.error('❌ 分享失败:', err);
uni.showToast({ title: '分享失败', icon: 'error' });
}
});
}
2. 分享图片
shareImageToQzone() {
this.qqSDK?.shareToQzone({
title: '图片标题',
desc: '图片描述',
previewImagePath: '/static/preview-image.jpg', // 预览图路径
targetUrl: 'https://www.example.com', // Android 空间分享必填(iOS建议必填)
success: (res) => {
console.log('✅ 图片分享成功');
},
fail: (err) => {
console.error('❌ 图片分享失败:', err);
}
});
}
3. 分享网页
shareWebPage() {
this.qqSDK?.share({
type: 3,
title: '网页标题',
desc: '网页描述',
targetUrl: 'https://www.example.com',
previewImagePath: '/static/webpage-thumb.jpg',
success: (res) => {
console.log('✅ 网页分享成功');
},
fail: (err) => {
console.error('❌ 网页分享失败:', err);
}
});
}
4. 分享视频
shareVideo() {
this.qqSDK?.share({
type: 2,
title: '视频标题',
desc: '视频描述',
targetUrl: 'https://www.example.com/video/123',
previewImagePath: '/static/video-thumb.jpg',
success: () => {
console.log('✅ 视频分享成功');
},
fail: (err) => {
console.error('❌ 视频分享失败:', err);
}
});
}
5. 分享音乐(Android)
shareMusic() {
this.qqSDK?.share({
type: 4,
title: '音乐标题',
desc: '音乐描述',
targetUrl: 'https://www.example.com/music/123',
previewImagePath: '/static/music-thumb.jpg',
success: () => {
console.log('✅ 音乐分享成功');
},
fail: (err) => {
console.error('❌ 音乐分享失败:', err);
}
});
}
Harmony平台分享示例
// Harmony平台分享文本
shareTextHarmony() {
// 从业务后台获取分享参数
const shareParams = this.getHarmonyShareParams('text', {
title: 'Harmony平台文本分享',
content: '这是Harmony平台的文本分享内容'
});
this.qqSDK?.share({
type: 0,
// Harmony平台必需参数
shareJson: shareParams.shareJson,
timestamp: shareParams.timestamp,
nonce: shareParams.nonce,
shareJsonSign: shareParams.shareJsonSign,
openId: shareParams.openId,
success: (res) => {
console.log('✅ Harmony平台文本分享成功');
},
fail: (err) => {
console.error('❌ Harmony平台分享失败:', err);
}
});
}
// Harmony平台分享图片
shareImageHarmony() {
const shareParams = this.getHarmonyShareParams('image', {
title: 'Harmony平台图片分享',
summary: '这是Harmony平台的图片分享',
picture_url: 'https://example.com/image.jpg'
});
this.qqSDK?.share({
type: 1,
// Harmony平台必需参数
shareJson: shareParams.shareJson,
timestamp: shareParams.timestamp,
nonce: shareParams.nonce,
shareJsonSign: shareParams.shareJsonSign,
openId: shareParams.openId,
success: (res) => {
console.log('✅ Harmony平台图片分享成功');
},
fail: (err) => {
console.error('❌ Harmony平台分享失败:', err);
}
});
}
// 从业务后台获取Harmony分享参数
getHarmonyShareParams(type: string, content: any) {
// 构建shareJson数据
const shareData = {
"msg_style": 0,
"title": content.title,
"summary": content.summary || content.content,
"brief": "互联分享",
"url": content.url || "https://www.dcloud.io/",
"picture_url": content.picture_url || ""
};
return {
shareJson: JSON.stringify(shareData),
timestamp: Date.now(),
nonce: Math.floor(Math.random() * 1000000), // 随机自然数
shareJsonSign: "mock_signature_for_test", // 实际使用时需要后台签名
openId: "test_openid_123456"
};
}
跨平台兼容分享
// 兼容所有平台的分享方法
shareUniversal(type: number, content: any) {
const shareParams = {
type: type,
// Android/iOS 参数
title: content.title,
desc: content.desc,
imagePath: content.imagePath,
previewImagePath: content.previewImagePath,
targetUrl: content.targetUrl,
// Harmony平台参数(其他平台会忽略)
shareJson: this.getHarmonyShareJson(type, content),
timestamp: Date.now(),
nonce: Math.floor(Math.random() * 1000000), // 随机自然数
shareJsonSign: "mock_signature_for_test",
openId: "test_openid_123456",
success: (res) => {
console.log('✅ 分享成功');
},
fail: (err) => {
console.error('❌ 分享失败:', err);
}
};
this.qqSDK?.share(shareParams);
}
// 生成Harmony平台的shareJson
getHarmonyShareJson(type: number, content: any) {
const shareData = {
"msg_style": 0,
"title": content.title,
"summary": content.desc || content.summary,
"brief": "互联分享"
};
if (type === 1 && content.imagePath) {
shareData["picture_url"] = content.imagePath;
}
if (content.targetUrl) {
shareData["url"] = content.targetUrl;
}
return JSON.stringify(shareData);
}
Harmony平台特殊说明
🔐 登录流程详解
Harmony平台的QQ登录流程与Android/iOS有显著差异:
1. 登录流程对比
Android/iOS 平台:
用户点击登录 → SDK直接返回完整信息 → 保存到本地
返回:accessToken, openid, expireTime
Harmony平台:
用户点击登录 → SDK返回authCode → 调用服务端获取token → 保存到本地
返回:authCode → 服务端处理 → accessToken, openid, expireTime
2. 服务端接口要求
请求格式:
POST /api/qq/getToken
{
"authCode": "Harmony平台返回的授权码",
"appId": "您的QQ平台AppID"
}
响应格式:
{
"code": 0,
"message": "success",
"data": {
"accessToken": "获取到的访问令牌",
"openid": "用户唯一标识",
"expireTime": "过期时间戳"
}
}
📤 分享功能详解
1. 分享类型限制
Harmony平台只支持ark类型分享,具体限制如下:
| 分享类型 | Harmony支持 | 说明 |
|---|---|---|
| 文本分享 | ✅ | 支持ark类型文本分享 |
| 图片分享 | ✅ | 支持ark类型图片分享 |
| 视频分享 | ❌ | 不支持 |
| 网页分享 | ❌ | 不支持 |
| 音乐分享 | ❌ | 不支持 |
1.1 分享接口映射(Harmony)
Harmony平台通过不同接口映射到QQ OpenSDK分享 type:
| SDK接口 | 含义 | 对应SDK type |
|---|---|---|
share(options) |
分享到QQ好友 | 2 |
shareToQzone(options) |
分享到QQ空间 | 3009 |
1.2 鸿蒙 shareJson 三种形态(与 Android/iOS 入参无关)
以下仅针对 Harmony 调用 QQ OpenSDK 时的 shareJson 字符串(另需 timestamp、nonce、shareJsonSign 等,见下文「签名计算」)。字段以 HarmonyOS_SDK接口说明 为准;三种形态不可混用。
| 场景 | 插件 API | OpenSDK type |
shareJson 要点 |
|---|---|---|---|
| 分享好友 · 图文 ark | share(options) |
2 | msg_style: 0,title、summary、brief、url、picture_url(网络图) |
| 分享好友 · 大图 | share(options) |
2 | msg_style: 6,share_uris:本地文件 URI 数组(仅首张生效;须 fileUri.getUriFromPath 等) |
| QQ 空间(含「分享到 QQ 空间」类能力) | shareToQzone(options) |
3009 | targetUrl、imageUrls(网络图 URL 数组)、title、summary 等,不要再使用好友 ark 的 url/picture_url |
1)好友 · 图文 ark(官方 3.1)
{
"msg_style": 0,
"title": "鸿蒙ARK图文",
"summary": "ARK分享的内容",
"brief": "互联分享",
"url": "https://www.qq.com",
"picture_url": "https://example.com/cover.png"
}
2)好友 · 大图(官方 3.2)
{
"msg_style": 6,
"share_uris": [
"file://entry/files/your_image.png"
]
}
3)QQ 空间(官方 3.3)
{
"title": "2024科技峰会精彩回顾",
"summary": "聚焦AI与元宇宙的前沿探索",
"targetUrl": "https://www.qq.com",
"imageUrls": [
"https://example.com/a.png",
"https://example.com/b.png"
]
}
示例页 pages/index/share.uvue 在 鸿蒙构建(APP-HARMONY)下会单独展示上述三种 shareJson 与对应调起按钮;Android / iOS 构建下仍保留原有「分享场景 / 分享类型 / 执行分享」面板,行为与示例代码与此前一致。
2. 分享参数结构(ShareData 公共字段)
除 shareJson 外,鸿蒙侧还需传入 timestamp、nonce、shareJsonSign(必填);openId 可选。shareJson 的具体键名随上表三种形态变化,不要用同一份 JSON 同时冒充好友与空间。
3. 签名计算
Harmony平台需要业务后台计算签名:
// 服务端签名计算示例
const shareJson = JSON.stringify(shareData);
const timestamp = Date.now();
const nonce = Math.floor(Math.random() * 1000000); // 随机自然数
const signString = shareJson + timestamp + nonce;
const shareJsonSign = calculateSignWithAppKey(signString);
🚫 不支持的功能
Harmony平台不支持以下功能:
1. 隐私协议相关
isAgreedAuthorization()- 获取授权状态setIsAgreedAuthorization()- 设置授权状态
2. 用户信息相关
getUserInfo()- 获取用户信息
3. 登录管理相关
logout()- 退出登录
4. 分享类型限制
- 视频分享(type: 2)
- 网页分享(type: 3)
- 音乐分享(type: 4)
🔧 开发建议
1. 条件编译使用
// 使用条件编译处理平台差异
// #ifndef APP-HARMONY
// Android/iOS 平台代码
this.qqSDK?.getUserInfo({
success: (res) => {
console.log("用户信息:", res);
}
});
// #endif
// #ifdef APP-HARMONY
// Harmony平台代码
console.log("Harmony平台不支持获取用户信息");
// #endif
2. 错误处理
// Harmony平台专用错误码
switch(errCode) {
case 501:
console.log("shareJson参数不能为空");
break;
case 502:
console.log("timestamp参数不能为空");
break;
case 503:
console.log("nonce参数不能为空");
break;
case 504:
console.log("shareJsonSign参数不能为空");
break;
case 505:
console.log("Harmony平台只支持文本和图片分享");
break;
}
3. 服务端集成
// Harmony平台需要服务端支持
class HarmonyQQService {
async getTokenFromServer(authCode: string) {
const response = await fetch('/api/qq/getToken', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
authCode: authCode,
appId: process.env.QQ_APP_ID
})
});
return await response.json();
}
async getShareParams(content: any) {
const response = await fetch('/api/qq/getShareParams', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(content)
});
return await response.json();
}
// 生成分享参数
generateShareParams(shareData: any) {
const shareJson = JSON.stringify(shareData);
const timestamp = Date.now();
const nonce = Math.floor(Math.random() * 1000000); // 随机自然数
const signString = shareJson + timestamp + nonce;
const shareJsonSign = this.calculateSign(signString);
return {
shareJson,
timestamp,
nonce,
shareJsonSign
};
}
private calculateSign(signString: string): string {
// 使用AppKey进行签名计算
// 这里需要根据实际的签名算法实现
return "calculated_signature";
}
}
退出登录
💡 退出QQ登录状态
平台支持说明
- ✅ Android/iOS: 支持退出登录功能
- ❌ Harmony: 不支持退出登录功能
参数说明
TTQQLogoutOptions
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| success | function | ❌ | 退出成功回调函数 |
| fail | function | ❌ | 退出失败回调函数 |
| complete | function | ❌ | 退出完成回调函数 |
示例代码
// 退出登录
handleLogout() {
this.qqSDK?.logout({
success: (res) => {
console.log("✅ 退出登录成功:", res);
// 清除本地用户信息和登录信息
uni.removeStorageSync('qqUserInfo');
uni.removeStorageSync('qqLoginInfo');
// 重置页面状态
this.userInfo = null;
// 跳转到登录页面或首页
uni.navigateTo({
url: '/pages/login/login'
});
},
fail: (err) => {
console.error("❌ 退出登录失败:", err);
uni.showToast({
title: '退出失败',
icon: 'error'
});
},
complete: (res) => {
console.log("退出登录完成:", res);
}
});
}
错误处理
错误码说明
| 错误码 | 错误信息 | 适用场景 | 解决方案 |
|---|---|---|---|
| 基础错误 | |||
| 101 | 未安装QQ | 所有功能 | 提示用户安装QQ客户端 |
| 102 | SDK未初始化或初始化失败 | 所有功能 | 检查SDK初始化参数,重新注册 |
| 203 | 未同意隐私政策 | 所有功能 | 提示用户同意隐私授权协议 |
| 登录错误 | |||
| 201 | 取消登录 | 登录功能 | 用户主动取消,无需处理 |
| 202 | 登录失败 | 登录功能 | 检查网络和QQ客户端状态 |
| 204 | 网络异常 | 登录功能 | 检查网络连接 |
| 用户信息错误 | |||
| 301 | 获取用户信息失败 | 获取用户信息 | 确保已登录,检查网络状态 |
| 分享错误 | |||
| 401 | title不能为空 | 分享功能 | 提供分享标题 |
| 402 | imagePath不能为空 | 图片分享 | 提供有效的本地图片路径 |
| 403 | 预览图片获取失败 | 分享功能 | 检查预览图路径和文件 |
| 404 | desc不能为空 | 分享功能 | 提供分享描述(纯文本分享除外) |
| 405 | 预览图不能为空 | iOS分享 | iOS平台分享时必须提供预览图 |
| 406 | targetUrl不能为空 | 视频/音乐分享 | 提供有效的跳转链接 |
| 407 | targetUrl不能为空 | 文本/网页/空间分享 | 提供有效的跳转链接 |
| 408 | targetUrl不能为空 | iOS网页分享 | 提供有效的跳转链接 |
| Harmony平台专用错误 | |||
| 501 | shareJson参数不能为空 | Harmony分享 | 提供shareJson参数 |
| 502 | timestamp参数不能为空 | Harmony分享 | 提供timestamp参数 |
| 503 | nonce参数不能为空 | Harmony分享 | 提供nonce参数 |
| 504 | shareJsonSign参数不能为空 | Harmony分享 | 提供shareJsonSign参数 |
| 505 | Harmony平台只支持文本和图片分享 | Harmony分享 | 保留错误码(当前版本未使用) |
| 其他错误 | |||
| 999 | 其他错误 | 所有功能 | 查看原始错误信息和详细日志 |
错误处理最佳实践
// 统一错误处理函数
handleQQError(error: any, action: string) {
console.error(`❌ ${action}失败:`, error);
// 获取错误码和错误信息
const errCode = error.errCode || error.code;
const errMsg = error.errMsg || error.message;
switch(errCode) {
case 101:
uni.showModal({
title: 'QQ未安装',
content: '请先安装QQ客户端后再试',
showCancel: false,
confirmText: '知道了'
});
break;
case 102:
uni.showModal({
title: 'SDK初始化失败',
content: '请检查QQ AppID配置是否正确',
showCancel: false
});
break;
case 203:
uni.showModal({
title: '隐私协议',
content: '使用QQ功能需要同意隐私授权协议',
showCancel: false
});
break;
case 201:
// 用户取消,不显示错误提示
console.log('用户取消操作');
break;
case 202:
case 204:
uni.showToast({
title: '登录失败,请重试',
icon: 'error'
});
break;
case 301:
uni.showToast({
title: '获取用户信息失败',
icon: 'error'
});
break;
case 401:
case 402:
case 404:
case 405:
case 406:
case 407:
uni.showToast({
title: '分享参数不完整',
icon: 'error'
});
break;
case 403:
case 408:
uni.showToast({
title: '文件获取失败',
icon: 'error'
});
break;
case 999:
// 其他错误,显示具体错误信息
uni.showToast({
title: errMsg || '操作失败',
icon: 'error'
});
break;
default:
// QQ SDK原始错误
if (errMsg && errMsg !== '用户取消') {
uni.showToast({
title: errMsg,
icon: 'error'
});
}
break;
}
}
// 使用示例
this.qqSDK?.login({
success: (result) => {
console.log('登录成功:', result);
},
fail: (error) => {
this.handleQQError(error, 'QQ登录');
}
});
调试技巧
// 开发环境下打印详细错误信息
debugQQError(error: any) {
if (process.env.NODE_ENV === 'development') {
console.group('🐛 QQ SDK错误详情');
console.log('错误码:', error.errCode || error.code);
console.log('错误信息:', error.errMsg || error.message);
console.log('错误主体:', error.errSubject);
console.log('原始错误:', error.cause);
console.groupEnd();
}
}
常见问题
1. 找不到插件方法?
解决方案: 确保使用自定义基座运行,标准基座不包含原生插件。
2. iOS平台登录/分享无响应?
解决方案:
- 检查
uni_modules/tt-qq-sdk/utssdk/app-ios/Info.plist中的 URL Scheme 配置 - 确认通用链接配置正确
- 验证QQ互联开放平台的 iOS 应用配置
- 确保 URL Scheme 格式为
tencent + AppID
3. Android平台功能异常?
解决方案:
- 确认应用签名与QQ互联开放平台配置一致
- 检查包名是否正确
- 确保QQ客户端版本支持相关功能
4. 提示未同意隐私协议?
解决方案:
- 在初始化SDK前调用
setIsAgreedAuthorization(true) - 确保用户已明确同意隐私授权协议
- 检查隐私协议相关的UI流程
5. 分享图片失败?
解决方案:
- 确保图片路径为本地路径,不支持网络图片
- 检查图片文件是否存在
- 图片大小不要超过限制(分享图片5M,预览图1M)
- iOS平台必须提供预览图
6. 获取用户信息失败?
解决方案:
- 确保已成功登录
- 检查网络连接状态
- 确认用户授权了相应的权限
- 验证QQ客户端是否为最新版本
7. 通用链接配置问题?
解决方案:
- 确保域名支持HTTPS
- 验证apple-app-site-association文件配置正确
- 检查苹果开发者账号中的Associated Domains配置
- 测试通用链接是否能正常跳转
8. QQ客户端版本兼容性?
解决方案:
- 建议使用最新版本的QQ客户端
- 某些功能可能需要特定版本的QQ支持
- 在功能使用前先检查QQ是否安装
9. Harmony平台登录只返回authCode?
解决方案:
- 这是Harmony平台的正常行为,需要调用服务端接口获取完整登录信息
- 实现服务端的token获取接口
- 使用authCode调用QQ互联平台的token接口
10. Harmony平台分享失败?
解决方案:
- 检查是否提供了所有必需参数:shareJson、timestamp、nonce、shareJsonSign
- 确保shareJson格式正确,符合ark类型要求
- 验证服务端签名计算是否正确
- 确认只使用了支持的分享类型(文本、图片)
11. Harmony平台不支持某些功能?
解决方案:
- 使用条件编译处理平台差异
- 对于不支持的功能,提供替代方案或提示用户
- 参考平台支持说明表格,了解功能支持情况
12. 如何实现跨平台兼容?
解决方案:
- 使用条件编译
#ifdef APP-HARMONY和#ifndef APP-HARMONY - 为不同平台提供不同的参数和逻辑
- 在接口调用时包含所有平台的参数,让SDK自动选择
13. Harmony平台配置问题?
解决方案:
- 检查
module.json5中的querySchemes是否包含"qqopenapi" - 确认
uris.host字段与QQ互联开放平台的AppID完全一致 - 验证
uris.scheme设置为"qqopenapi" - 确保已申请
ohos.permission.INTERNET网络权限 - 检查
pathRegex是否正确匹配回调路径
14. Harmony平台QQ回调失败?
解决方案:
- 确认
module.json5中的host字段与QQ互联开放平台配置一致 - 检查应用签名是否与QQ互联开放平台配置匹配
- 验证
uris配置是否正确 - 确保应用已正确安装并具有处理回调的权限
📞 技术支持
如果在使用过程中遇到问题,请:
- 查阅上方常见问题
- 参考QQ互联官方开发文档
- 检查配置是否正确
- 确认QQ客户端版本
祝您开发愉快! 🎉

收藏人数:
购买源码授权版(
试用
使用 HBuilderX 导入示例项目
赞赏(1)
下载 731
赞赏 4
下载 11895623
赞赏 1914
赞赏
京公网安备:11010802035340号