更新记录
1.0.0(2025-08-07)
支持 安卓/iOS 登录以及分享功能
平台兼容性
uni-app x(4.36)
Chrome | Safari | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 | 微信小程序 |
---|---|---|---|---|---|---|---|
× | × | 5.0 | 1.0.0 | 12 | 1.0.0 | × | × |
tt-qq-sdk
🚀 腾讯QQ SDK插件,为 uni-app x 提供完整的QQ集成解决方案,包含登录、分享、用户信息等功能
📖 目录
SDK版本信息
平台 | 版本 |
---|---|
iOS | 3.5.17.4 |
Android | 3.5.17.3 |
📚 推荐阅读: QQ互联官方开发文档
🚨 重要提示
⚠️ 必须使用自定义基座运行,否则无法找到插件方法
⚠️ 必须用户同意隐私协议,否则SDK所有功能都无法使用
环境配置
前置条件
- 在QQ互联开放平台申请移动应用
- 获取
AppID
- 配置应用包名、签名和通用链接
iOS平台配置
1. 配置 URL Scheme
在项目根目录的 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官方文档-通用链接
Android平台配置
1. 配置 AndroidManifest.xml
在项目根目录的 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/utssdk/interface.uts'
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登录需要用户先同意隐私协议,然后进行授权操作
参数说明
TTQQLoginOptions
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
success | function | ❌ | 登录成功回调函数 |
fail | function | ❌ | 登录失败回调函数 |
complete | function | ❌ | 登录完成回调函数 |
返回值 TTQQLoginSuccess
参数 | 类型 | 说明 |
---|---|---|
- | object | 登录成功时为空对象,需要调用getUserInfo获取用户信息 |
示例代码
// QQ登录
handleQQLogin() {
// 先检查QQ是否安装
if (!this.checkQQInstalled()) {
return
}
// 检查隐私协议
if (!this.checkPrivacyAgreement()) {
return
}
this.qqSDK?.login({
success: (res) => {
console.log("✅ QQ登录成功:", res);
// 登录成功后获取用户信息
this.getUserInfo()
},
fail: (err) => {
console.error("❌ QQ登录失败:", err);
this.handleLoginError(err)
},
complete: (res) => {
console.log("QQ登录完成:", res);
}
});
}
// 处理登录错误
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;
}
}
获取用户信息
💡 获取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分享功能
💡 支持分享文本、图片、视频、网页、音乐到QQ好友或QQ空间
分享类型和场景
分享类型 (type)
0
- 纯文本分享1
- 图片分享2
- 视频分享3
- 新闻/网页分享4
- 音乐分享
分享场景 (scene)
0
- 分享到QQ好友1
- 分享到QQ空间
参数说明
TTQQShareOptions
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
type | number | ✅ | 分享类型,见上表 |
scene | number | ✅ | 分享场景,见上表 |
title | string | 条件 | 分享标题(纯文本时最长1536字符,其他类型最长30字符) |
desc | string | 条件 | 分享描述(最长40字符,纯文本分享不需要) |
imagePath | string | 条件 | 图片本地路径(图片分享时必填,限制5M) |
previewImagePath | string | 条件 | 预览图本地路径(限制1M) |
videoUrl | string | 条件 | 视频地址(视频分享时必填) |
musicUrl | string | 条件 | 音乐地址(音乐分享时必填) |
href | string | 条件 | 网页链接(网页分享时必填) |
使用示例
1. 分享文本
shareText() {
this.qqSDK?.share({
type: 0,
scene: 0, // 分享到QQ好友
title: '这是一条文本消息',
success: (res) => {
console.log('✅ 文本分享成功');
uni.showToast({ title: '分享成功' });
},
fail: (err) => {
console.error('❌ 分享失败:', err);
uni.showToast({ title: '分享失败', icon: 'error' });
}
});
}
2. 分享图片
shareImage() {
this.qqSDK?.share({
type: 1,
scene: 1, // 分享到QQ空间
title: '图片标题',
desc: '图片描述',
imagePath: '/static/share-image.jpg', // 本地图片路径
previewImagePath: '/static/preview-image.jpg', // 预览图路径
success: (res) => {
console.log('✅ 图片分享成功');
},
fail: (err) => {
console.error('❌ 图片分享失败:', err);
}
});
}
3. 分享网页
shareWebPage() {
this.qqSDK?.share({
type: 3,
scene: 0,
title: '网页标题',
desc: '网页描述',
href: 'https://www.example.com',
previewImagePath: '/static/webpage-thumb.jpg',
success: (res) => {
console.log('✅ 网页分享成功');
},
fail: (err) => {
console.error('❌ 网页分享失败:', err);
}
});
}
退出登录
💡 退出QQ登录状态
参数说明
TTQQLogoutOptions
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
success | function | ❌ | 退出成功回调函数 |
fail | function | ❌ | 退出失败回调函数 |
complete | function | ❌ | 退出完成回调函数 |
示例代码
// 退出登录
handleLogout() {
this.qqSDK?.logout({
success: (res) => {
console.log("✅ 退出登录成功:", res);
// 清除本地用户信息
uni.removeStorageSync('qqUserInfo');
// 重置页面状态
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 | videoUrl不能为空 | 视频分享 | 提供有效的视频链接 |
407 | href不能为空 | 网页分享 | 提供有效的网页链接 |
408 | 视频获取失败 | 视频分享 | 检查视频URL有效性 |
其他错误 | |||
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平台登录/分享无响应?
解决方案:
- 检查 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是否安装
📞 技术支持
如果在使用过程中遇到问题,请:
- 查阅上方常见问题
- 参考QQ互联官方开发文档
- 检查配置是否正确
- 确认QQ客户端版本
祝您开发愉快! 🎉