# 友盟分享集成说明
## 目录结构
```
capability-share/src/
└── main/
├── AndroidManifest.xml # Android 清单文件(权限声明)
└── java/
└── com/narutohuo/xindazhou/share/
├── api/ # API 接口层
│ └── ShareService.kt # 分享服务接口定义(统一 share() 方法 + 9个平台方法)
├── factory/ # 工厂类层
│ └── ShareServiceFactory.kt # 服务工厂(统一入口,单例获取)
├── impl/ # 实现层
│ └── ShareServiceImpl.kt # 分享服务具体实现(封装友盟SDK)
├── ui/ # UI层
│ ├── ShareDialogFragment.kt # 分享弹窗(封装在模块内部)
│ └── ShareProxyActivity.kt # 透明代理 Activity(自动处理 onActivityResult)
└── model/ # 数据模型层
├── ShareResponse.kt # 分享相关的数据模型
│ ├── ShareContent # 分享内容模型
│ ├── ShareResponse # 分享响应模型
│ └── SharePlatform # 分享平台枚举
└── ShareConfig.kt # 分享服务配置模型
├── ShareConfig # 主配置类
├── WeChatConfig # 微信平台配置
├── QQConfig # QQ平台配置
└── WeiboConfig # 微博平台配置
```
## 功能说明
### 1. api/ 层 - 接口定义
- **职责**:定义分享服务的公共接口,业务层只依赖接口
- **内容**:`ShareService` 接口
- `share()` - 统一分享方法(推荐使用,业务层调用)
- **自动处理 onActivityResult**,业务层不需要在 Activity 中处理回调
- 如果 `ShareContent.platform` 已指定,直接分享到该平台
- 如果 `ShareContent.platform` 为 null,显示分享弹窗让用户选择
- 内部使用透明代理 Activity 封装所有实现细节
- `shareManual()` - 手动分享方法(内部使用,避免递归调用)
- 供 `ShareProxyActivity` 内部调用,业务层不应直接使用
- 如果指定了平台,直接分享到该平台;否则显示分享弹窗
- `showShareDialog()` - 显示分享弹窗(底部弹出)
### 2. factory/ 层 - 工厂类
- **职责**:提供统一的服务实例获取和初始化方式
- **内容**:`ShareServiceFactory` 单例工厂
- **作用**:
- 隐藏实现细节,统一入口,便于替换实现
- 提供 `init()` 方法统一初始化,避免在 Application 中直接调用服务方法
- 提供 `getInstance()` 方法获取服务实例
### 3. impl/ 层 - 具体实现
- **职责**:实现 `ShareService` 接口的具体逻辑
- **内容**:`ShareServiceImpl` 单例实现类
- **功能**:
- 封装友盟分享 SDK 调用
- 封装友盟初始化逻辑(`initialize()`)
- 封装分享回调处理(`onActivityResult()`)- 通过透明代理 Activity 自动处理
- 封装资源释放(`release()`)
- 实现统一的 `share()` 方法,自动使用透明代理 Activity,业务层无需处理回调
- 实现 `shareManual()` 方法(内部使用,避免递归调用),供 `ShareProxyActivity` 调用
- 实现 `showShareDialog()` 方法,显示分享弹窗
- 处理分享回调(成功/失败/取消)
- 错误处理和日志记录
- 支持网页、图片、文本等多种分享类型
### 3.1 ui/ 层 - UI组件
- **职责**:封装分享相关的 UI 组件
- **内容**:
- `ShareDialogFragment` - 分享弹窗(底部弹出)
- 底部弹出(Material Design BottomSheet)
- 显示所有可用分享平台(微信、朋友圈、QQ、QQ空间、微博、更多)
- 用户选择平台后自动执行分享
- 弹窗逻辑完全封装在模块内部,主工程无需关心
- `ShareProxyActivity` - 透明代理 Activity(自动处理 onActivityResult)
- 继承自 `FragmentActivity`,支持显示 `ShareDialogFragment`
- 完全封装在模块内部,业务层不需要知道它的存在
- 自动处理分享回调,业务层不需要在 Activity 中处理 `onActivityResult`
- 内部使用 `shareManual()` 方法避免递归调用
- 透明主题,用户看不到
- 分享完成后自动关闭
### 4. model/ 层 - 数据模型
- **职责**:定义分享相关的数据模型
- **内容**:
- `ShareContent` - 分享内容模型(标题、描述、URL、图片等)
- **Builder 模式**:`ShareContent.builder()` 链式调用构建,支持灵活的参数组合
- **平台类型**:`platform: SharePlatform?` 字段
- 如果指定,直接分享到该平台(不显示弹窗)
- 如果为 null,显示分享弹窗让用户选择
- `ShareResponse` - 分享响应模型(成功/失败、错误信息等)
- `SharePlatform` - 分享平台枚举(9个平台)
- `ShareConfig` - 分享服务配置模型(封装友盟和各平台配置)
- `WeChatConfig` - 微信平台配置
- `QQConfig` - QQ平台配置
- `WeiboConfig` - 微博平台配置
### 5. AndroidManifest.xml - 权限配置
- **职责**:声明模块所需的 Android 权限
- **内容**:网络权限声明
## 架构设计
- **接口隔离**:业务层只依赖接口,不依赖实现
- **工厂模式**:统一入口,隐藏创建逻辑
- **单例模式**:全局共享一个服务实例
- **分层架构**:api → factory → impl → 第三方SDK
- **完全封装**:使用透明代理 Activity 自动处理 `onActivityResult`,业务层无需关心实现细节
## 已完成的工作
✅ **SDK 依赖已添加**
- `com.umeng.umsdk:common:9.6.8` - 友盟基础库
- `com.umeng.umsdk:share-core:7.3.2` - 友盟分享核心库
- `com.umeng.umsdk:share-board:7.3.2` - 友盟分享面板
- `com.umeng.umsdk:share-wx:7.3.2` - 微信分享
- `com.umeng.umsdk:share-qq:7.3.2` - QQ分享
- `com.umeng.umsdk:share-sina:7.3.2` - 新浪微博分享
✅ **代码实现已完成**
- `ShareServiceImpl` 已实现友盟分享 SDK 调用
- `ShareServiceFactory` 已创建
## 需要您配置的内容
### 1. 在友盟官网注册应用
1. 访问 [友盟+官网](https://www.umeng.com/)
2. 注册账号并创建应用
3. 获取 **AppKey** 和 **AppSecret**
### 2. 配置第三方平台
#### 2.1 微信平台配置
1. 访问 [微信开放平台](https://open.weixin.qq.com/)
2. 创建移动应用,获取 **AppID** 和 **AppSecret**
#### 2.2 QQ平台配置
1. 访问 [QQ开放平台](https://open.qq.com/)
2. 创建移动应用,获取 **AppID** 和 **AppKey**
#### 2.3 新浪微博配置
1. 访问 [新浪微博开放平台](https://open.weibo.com/)
2. 创建移动应用,获取 **AppKey** 和 **AppSecret**
### 3. 配置 AndroidManifest.xml
在 `app/src/main/AndroidManifest.xml` 中添加权限声明(**meta-data 配置已通过代码完成,无需在 Manifest 中配置**):
```xml
```
**说明**:
- ✅ 权限声明是必需的
- ✅ AppKey 和平台配置通过代码完成(见步骤4),更灵活
- ✅ 如果需要在 Manifest 中配置,也可以保留,代码配置会覆盖 Manifest 配置
### 4. 配置资源文件(推荐方式)
在 `app/src/main/res/values/strings.xml` 中配置分享参数(**推荐方式,配置统一管理**):
```xml
您的友盟 AppKey
developer-default
您的微信 AppID
您的微信 AppSecret
您的QQ AppID
您的QQ AppKey
您的新浪微博 AppKey
您的新浪微博 AppSecret
您的新浪微博回调地址
```
### 5. 在 Application 中初始化(统一入口)
在您的 `XinDaZhouApplication` 类中初始化分享服务,**支持三种方式**:
#### 方式1:使用默认配置(从资源文件读取,最简单)
```kotlin
// app/src/main/java/com/narutohuo/xindazhou/XinDaZhouApplication.kt
package com.narutohuo.xindazhou
import android.app.Application
import com.narutohuo.xindazhou.share.factory.ShareServiceFactory
class XinDaZhouApplication : Application() {
override fun onCreate() {
super.onCreate()
// ========== 初始化分享服务(最简单,从资源文件读取配置)==========
ShareServiceFactory.init(context = this)
}
}
```
**优势**:
- ✅ **最简单**:只需一行代码,配置都在资源文件中
- ✅ **统一入口**:通过 `ShareServiceFactory.init()` 统一初始化,代码更清晰
- ✅ 业务层不直接依赖友盟API
- ✅ 如果更换SDK,只需修改实现层,业务层无需改动
- ✅ 配置统一管理,代码更清晰
### 6. 使用分享功能(完全封装,无需处理回调)
**重要更新**:分享功能已完全封装,业务层**不需要**在 `MainActivity` 中处理 `onActivityResult`!
分享组件内部使用透明代理 Activity 自动处理所有回调,业务层只需要调用 `share()` 方法即可:
```kotlin
// app/src/main/java/com/narutohuo/xindazhou/user/ui/profile/UserFragment.kt
class UserFragment : Fragment() {
private val shareService = ShareServiceFactory.getInstance()
private fun shareContent() {
val content = ShareContent.builder()
.setTitle("分享标题")
.setDescription("分享描述")
.setUrl("https://example.com")
.build()
// 直接调用 share() 方法,自动处理所有回调
shareService.share(requireActivity(), content) { response ->
if (response.success) {
Toast.makeText(requireContext(), "分享成功", Toast.LENGTH_SHORT).show()
}
}
}
}
```
**说明**:
- ✅ **完全封装**:业务层不需要处理 `onActivityResult`,所有回调都在组件内部处理
- ✅ **使用简单**:只需调用 `share()` 方法,传入分享内容和回调即可
- ✅ **透明代理**:组件内部使用透明 Activity 处理回调,用户看不到
- ✅ **自动关闭**:分享完成后,透明 Activity 自动关闭,回到原界面
## 支持的分享平台
### 已完整支持(通过友盟SDK)
- ✅ **微信** - `shareToWeChat()`
- ✅ **微信朋友圈** - `shareToWeChatMoments()`
- ✅ **QQ** - `shareToQQ()`
- ✅ **QQ空间** - `shareToQZone()`
- ✅ **新浪微博** - `shareToWeibo()`
### 部分支持(待实现)
- ⚠️ **抖音** - `shareToDouyin()` - 待实现
- ⚠️ **小红书** - `shareToXiaohongshu()` - 待实现
- ⚠️ **快手** - `shareToKuaishou()` - 待实现
- ✅ **系统分享** - `shareToSystem()` - 调用系统分享菜单
## 使用示例
### 在 Fragment 中使用分享(实际项目示例)
分享功能在 Fragment 中使用:
```kotlin
// app/src/main/java/com/narutohuo/xindazhou/user/ui/profile/UserFragment.kt
package com.narutohuo.xindazhou.user.ui.profile
import android.view.View
import android.widget.Button
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.narutohuo.xindazhou.R
import com.narutohuo.xindazhou.share.factory.ShareServiceFactory
import com.narutohuo.xindazhou.share.model.ShareContent
import com.narutohuo.xindazhou.share.model.ShareResponse
import timber.log.Timber
class UserFragment : Fragment() {
// 获取分享服务实例(单例)
private val shareService = ShareServiceFactory.getInstance()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// 示例:分享按钮点击
view.findViewById