HarmonyOS鸿蒙Next中QQ分享功能,我这样分享过后,QQ那边显示分享失败是为什么,求助各位大佬
HarmonyOS鸿蒙Next中QQ分享功能,我这样分享过后,QQ那边显示分享失败是为什么,求助各位大佬
import {
IQQOpenApi,
OpenApiConfig,
QQOpenApiFactory,
ShareData,
ShareResult,
ShareResultType } from '@tencent/qq-open-sdk'
import { promptAction } from '@kit.ArkUI'
import { BusinessError } from '@kit.BasicServicesKit'
import { Logger } from 'accomponentitembase'
import { buffer, util } from '@kit.ArkTS'
import { cryptoFramework } from '@kit.CryptoArchitectureKit'
export class QQUtil {
static appId = 111111111
private static qqOpenApi: IQQOpenApi
/**
* 分享
* @param title 标题
* @param summary 内容
* @param brief QQ信息列表显示的内容
* @param imageUrl 图片链接
* @param url 跳转链接
*/
static async share(title: string, summary: string, brief: string, imageUrl: string, url: string) {
let content = new Object({
msg_style: 0,
title: title,
summary: summary,
brief: brief,
url: url,
picture_url: imageUrl
})
let shareData: ShareData = new ShareData()
shareData.timestamp = Date.parse(new Date().toString()) / 1000
shareData.nonce = Math.floor(Math.random() * 100000000 + 100)
shareData.shareJson = JSON.stringify(content)
let signContent = 'POSTconnect.qq.com/share?appid=' + QQUtil.appId.toString()
+ '&nonce=' + shareData.nonce.toString()
+ '&ts=' + shareData.timestamp.toString()
+ '&' + shareData.shareJson
let sign = await QQUtil.sign(signContent);
shareData.shareJsonSign = sign
const qqOpenApi = QQUtil.getQQOpenApi()
if (!qqOpenApi.isQQInstalled()) {
promptAction.showToast({message:"qq未安装"})
return
}
qqOpenApi.share(2, shareData,QQUtil.appId.toString()).then((result: ShareResult) => {
Logger.info('TAG', `qqOpenApi.share, result=${JSON.stringify(result)}`)
switch (result.resultType) {
case ShareResultType.Success: {
promptAction.showToast({ message: "分享成功" })
}
break
case ShareResultType.Cancel: {
let msg: string = result.message ?? "用户取消分享"
promptAction.showToast({ message: msg })
}
break
case ShareResultType.Error: {
let msg: string = result.message ?? "分享失败"
promptAction.showToast({ message: msg })
}
break
}
})
.catch((err: BusinessError) => {
Logger.error("TAG", `error, code=${JSON.stringify(err.code)}, message=${JSON.stringify(err.message)}`)
})
}
static getQQOpenApi(): IQQOpenApi {
if (!QQUtil.qqOpenApi) {
let openApiOption: OpenApiConfig = {
forceEnableWeb: false,
autoHandleAuthResult: true,
}
QQUtil.qqOpenApi =
QQOpenApiFactory.createApi(QQUtil.appId, openApiOption)
}
return QQUtil.qqOpenApi
}
static async sign(shareJson: string): Promise<string> {
let keyData = new Uint8Array(buffer.from('QQ加密appSecret', 'utf-8').buffer);
let symKeyBlob: cryptoFramework.DataBlob = { data: keyData };
let aesGenerator = cryptoFramework.createSymKeyGenerator('HMAC');
let symKey = await aesGenerator.convertKey(symKeyBlob);
let macAlgName = 'SHA1'; // 摘要算法名。
let mac = cryptoFramework.createMac(macAlgName);
await mac.init(symKey);
// 数据量较少时,可以一次性执行update操作,将所有数据传入。该接口不对入参长度进行限制。
await mac.update({ data: new Uint8Array(buffer.from(shareJson, 'utf-8').buffer) });
let macResult = await mac.doFinal();
let base64 = new util.Base64Helper();
return base64.encodeToStringSync(macResult.data);
}
}
export const qqShare = QQUtil.share
更多关于HarmonyOS鸿蒙Next中QQ分享功能,我这样分享过后,QQ那边显示分享失败是为什么,求助各位大佬的实战教程也可以访问 https://www.itying.com/category-93-b0.html
AppSecret配置错误:
代码中keyData使用固定字符串’QQ加密appSecret’,实际开发需替换为QQ开放平台分配的真实AppSecret。密钥不匹配会导致签名校验失败。
签名算法实现差异:
你使用HMAC-SHA1算法,但需注意:
let aesGenerator = cryptoFramework.createSymKeyGenerator('HMAC'); // 需确认是否指定SHA1
let macAlgName = 'SHA1'; // 必须与QQ开放平台要求一致
需核对QQ SDK文档要求的签名算法,部分平台可能要求SHA256。
更多关于HarmonyOS鸿蒙Next中QQ分享功能,我这样分享过后,QQ那边显示分享失败是为什么,求助各位大佬的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
我已经解决了,这里还是需要使用AppKey来进行签名
import { CryptoJS } from '@ohos/crypto-js'
import {
IQQOpenApi,
OpenApiConfig,
QQOpenApiFactory,
ShareData,
ShareResult,
ShareResultType } from '@tencent/qq-open-sdk'
import { promptAction } from '@kit.ArkUI'
import { BusinessError } from '@kit.BasicServicesKit'
import { Logger } from 'accomponentitembase'
export class QQUtil {
static appId = 111111111
static AppKey = ''
private static qqOpenApi: IQQOpenApi
/**
* 分享
* @param title 标题
* @param summary 内容
* @param brief QQ信息列表显示的内容
* @param imageUrl 图片链接
* @param url 跳转链接
*/
static share(title: string, summary: string, brief: string, imageUrl: string, url: string) {
let content = new Object({
msg_style: 0,
title: title,
summary: summary,
brief: brief,
url: url,
picture_url: imageUrl
})
let shareData: ShareData = new ShareData()
shareData.timestamp = Date.parse(new Date().toString()) / 1000
shareData.nonce = Math.floor(Math.random() * 100000000 + 100)
shareData.shareJson = JSON.stringify(content)
let signContent = 'POSTconnect.qq.com/share?appid=' + QQUtil.appId.toString()
+ '&nonce=' + shareData.nonce.toString()
+ '&ts=' + shareData.timestamp.toString()
+ '&' + shareData.shareJson
//这里的签名信息还是使用插件CryptoJS
const hmac = CryptoJS.HmacSHA1(signContent, QQUtil.AppKey);
let sign = hmac.toString(CryptoJS.enc.Base64);
shareData.shareJsonSign = sign
const qqOpenApi = QQUtil.getQQOpenApi()
if (!qqOpenApi.isQQInstalled()) {
promptAction.showToast({message:"qq未安装"})
return
}
qqOpenApi.share(2, shareData).then((result: ShareResult) => {
Logger.info('TAG', `qqOpenApi.share, result=${JSON.stringify(result)}`)
switch (result.resultType) {
case ShareResultType.Success: {
promptAction.showToast({ message: "分享成功" })
}
break
case ShareResultType.Cancel: {
let msg: string = result.message ?? "用户取消分享"
promptAction.showToast({ message: msg })
}
break
case ShareResultType.Error: {
let msg: string = result.message ?? "分享失败"
promptAction.showToast({ message: msg })
}
break
}
})
.catch((err: BusinessError) => {
Logger.error("TAG", `error, code=${JSON.stringify(err.code)}, message=${JSON.stringify(err.message)}`)
})
}
static getQQOpenApi(): IQQOpenApi {
if (!QQUtil.qqOpenApi) {
let openApiOption: OpenApiConfig = {
forceEnableWeb: false,
autoHandleAuthResult: true,
}
QQUtil.qqOpenApi =
QQOpenApiFactory.createApi(QQUtil.appId, openApiOption)
}
return QQUtil.qqOpenApi
}
}
export const qqShare = QQUtil.share
鸿蒙Next中QQ分享失败可能原因:
- SDK版本不兼容鸿蒙Next系统;
- 应用签名未在QQ开放平台正确配置;
- 鸿蒙Next权限管理限制分享操作;
- QQ客户端未适配鸿蒙Next新特性。
请检查QQ开放平台配置和鸿蒙SDK文档。
分享失败可能有以下几个原因:
-
签名计算错误:检查
signContent
的拼接格式是否符合QQ开放平台要求,特别是appid
、nonce
、ts
和shareJson
的顺序和分隔符是否正确。确保appSecret
是有效的密钥。 -
时间戳问题:
timestamp
使用的是秒级时间戳,但Date.parse()
返回的是毫秒,除以1000是正确的,但建议直接使用Math.floor(Date.now() / 1000)
更简洁。 -
网络权限:确认应用已申请必要的网络权限(如
ohos.permission.INTERNET
),否则可能导致连接QQ服务器失败。 -
QQ版本兼容性:确保用户安装的QQ版本支持OpenSDK功能,过旧版本可能无法处理分享请求。
-
参数格式:检查
shareJson
中的字段(如picture_url
和url
)是否是有效的URL格式,无效链接会导致分享失败。
建议在catch
块中输出详细的错误信息(如err.code
和err.message
),以便进一步定位问题。