# 友盟分享集成说明

## 目录结构

    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 权限
- 内容：网络权限声明

## 架构设计

- 接口隔离：业务层只依赖接口，不依赖实现
- ARouter 依赖注入：通过 ARouter 实现模块间解耦，base-core 定义接口，能力层实现接口
- 工厂模式：统一入口，隐藏创建逻辑（内部使用 ARouter 获取服务）
- 单例模式：全局共享一个服务实例
- 分层架构：base-core (接口) → capability-share (实现) → ARouter (注册) → Factory (获取)
- 完全封装：使用透明代理 Activity 自动处理 `onActivityResult`，业务层无需关心实现细节

### ARouter 架构说明

- base-core 模块定义 `IShareService` 接口（位于 `com.narutohuo.xindazhou.core.share`）
- capability-share 模块实现 `IShareService` 接口，并通过 `@Route(path = "/share/service")` 注册到 ARouter
- base-core 模块中的 `WXEntryActivity` 通过 ARouter 注入 `IShareCallback` 实现（`@Route(path = "/share/callback")`）
- Factory 内部使用 `ARouter.getInstance().navigation(IShareService::class.java)` 获取服务实例
- 业务层 通过 Factory 获取服务，无需直接依赖实现模块

## 核心功能说明

### 1. 分享回调流程（完全封装，统一处理所有平台）

完整回调链路：

    业务层调用 shareService.share(activity, content, callback)
        ↓
    ShareServiceImpl.share() 自动启动 ShareProxyActivity
        ↓
    ShareProxyActivity.onCreate() 调用 shareService.shareManual()
        ↓
    ShareServiceImpl.shareManual() 调用友盟 SDK 进行分享（或显示分享弹窗）
        ↓
    用户在第三方应用（如微信、QQ、微博）完成分享操作
        ↓
    第三方应用回调到各自的回调 Activity：
      - 微信 → WXEntryActivity（base-core 模块，通过 ARouter 注入 IShareCallback）
        ↓ WXEntryActivity.onWeChatCallback() 调用 shareCallback.onWeChatCallback()
        ↓ ShareCallbackImpl.onWeChatCallback() 处理回调
      - QQ → AuthActivity（QQ SDK 自带，友盟自动处理）
      - 微博 → WBShareTransActivity（微博 SDK 自带，友盟自动处理）
        ↓
    友盟 SDK 通过 onActivityResult 回调到 ShareProxyActivity.onActivityResult()
        ↓
    ShareProxyActivity.onActivityResult() 调用 shareService.onActivityResult()
        ↓
    ShareServiceImpl.onActivityResult() 调用 UMShareAPI.get(activity).onActivityResult()
        ↓
    友盟 SDK 触发 ShareServiceImpl 中设置的 UMShareListener.onResult() / onError() / onCancel()
        ↓
    UMShareListener 调用业务层传入的 callback 函数
        ↓
    ShareProxyActivity 收到回调结果，调用业务层的 callback，并自动关闭自身
        ↓
    业务层的 callback { response -> ... } 被调用 ✅

关键点：

- ✅ 统一入口：`share()` 方法自动启动 `ShareProxyActivity`，所有平台的分享都通过它处理
- ✅ 统一回调：所有平台（微信、QQ、微博等）的回调都统一回到 `ShareProxyActivity.onActivityResult()`
- ✅ ARouter 解耦：`WXEntryActivity` 在 `base-core` 模块，通过 ARouter 注入 `IShareCallback` 实现，实现模块间解耦
- ✅ 业务层透明：业务层不需要在 Activity 中处理 `onActivityResult`，完全封装在模块内部
- ✅ 自动关闭：`ShareProxyActivity` 收到回调后自动关闭，用户无感知

## 已完成的工作

✅ 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 调用，并实现 `IShareService` 接口
- `ShareServiceImpl` 已通过 ARouter 注册（`@Route(path = "/share/service")`）
- `ShareCallbackImpl` 已实现 `IShareCallback` 接口，并通过 ARouter 注册（`@Route(path = "/share/callback")`）
- `ShareServiceFactory` 已创建，内部使用 ARouter 获取服务
- `IShareService` 接口已在 `base-core` 模块定义
- `IShareCallback` 接口已在 `base-core` 模块定义
- `WXEntryActivity` 已移至 `base-core` 模块，通过 ARouter 注入回调实现
- ARouter 集成完成：模块间解耦，通过 ARouter 进行依赖注入

## 需要您配置的内容

### 1. 在友盟官网注册应用

1. 访问 友盟+官网
2. 注册账号并创建应用
3. 获取 AppKey 和 AppSecret

### 2. 配置第三方平台

#### 2.1 微信平台配置

1. 访问 微信开放平台
2. 创建移动应用，获取 AppID 和 AppSecret

#### 2.2 QQ平台配置

1. 访问 QQ开放平台
2. 创建移动应用，获取 AppID 和 AppKey

#### 2.3 新浪微博配置

1. 访问 新浪微博开放平台
2. 创建移动应用，获取 AppKey 和 AppSecret

### 3. 配置 AndroidManifest.xml

注意：权限声明和回调 Activity 配置已在各模块的 `AndroidManifest.xml` 中完成，`app` 模块无需配置。

- ✅ 权限声明：已在 `capability-share/src/main/AndroidManifest.xml` 中配置
- ✅ 回调 Activity：
  - `WXEntryActivity` 已在 `base-core/src/main/AndroidManifest.xml` 中配置
  - `AuthActivity`（QQ）、`WBShareTransActivity`（微博）已在 `capability-share/src/main/AndroidManifest.xml` 中配置
- ✅ ARouter 初始化：已在 `XinDaZhouApplication` 中完成（见步骤5）

说明：

- ✅ 所有配置都在各模块内部管理，`app` 模块无需配置
- ✅ AppKey 和平台配置通过代码完成（见步骤4），更灵活

### 4. 配置资源文件（推荐方式）

注意：配置位置已改为 `capability-share/src/main/res/values/strings.xml`，`app` 模块无需配置。

在 `capability-share/src/main/res/values/strings.xml` 中配置分享参数（推荐方式，配置统一管理）：

    <!-- capability-share/src/main/res/values/strings.xml -->
    <resources>
        <!-- 友盟配置（必填） -->
        <string name="share_umeng_app_key">您的友盟 AppKey</string>
        <string name="share_umeng_channel">developer-default</string>

        <!-- 微信平台配置（可选） -->
        <string name="share_wechat_app_id">您的微信 AppID</string>
        <string name="share_wechat_app_secret">您的微信 AppSecret</string>

        <!-- QQ平台配置（可选） -->
        <string name="share_qq_app_id">您的QQ AppID</string>
        <string name="share_qq_app_key">您的QQ AppKey</string>
        <!-- QQ AppID Scheme（用于回调，格式：tencent + AppID） -->
        <string name="qq_app_id_scheme">tencent您的QQ AppID</string>

        <!-- 微博平台配置（可选） -->
        <string name="share_weibo_app_key">您的新浪微博 AppKey</string>
        <string name="share_weibo_app_secret">您的新浪微博 AppSecret</string>
        <string name="share_weibo_redirect_url">您的新浪微博回调地址</string>
    </resources>

### 5. 在 Application 中初始化（统一入口）

在您的 `XinDaZhouApplication` 类中初始化分享服务：

    // app/src/main/java/com/narutohuo/xindazhou/XinDaZhouApplication.kt
    package com.narutohuo.xindazhou

    import android.app.Application
    import com.alibaba.android.arouter.launcher.ARouter
    import com.narutohuo.xindazhou.share.factory.ShareServiceFactory

    class XinDaZhouApplication : Application() {

        override fun onCreate() {
            super.onCreate()

            // ========== 初始化 ARouter（必须在其他初始化之前）==========
            if (BuildConfig.DEBUG) {
                ARouter.openLog()
                ARouter.openDebug()
            }
            ARouter.init(this)

            // ========== 初始化分享服务（从资源文件读取配置）==========
            try {
                ShareServiceFactory.init(context = this)
            } catch (e: Exception) {
                // 分享服务初始化失败不影响应用运行，但分享功能将不可用
                android.util.Log.e("XinDaZhouApplication", "分享服务初始化失败", e)
            }
        }
    }

优势：

- ✅ 最简单：只需一行代码，配置都在资源文件中
- ✅ 统一入口：通过 `ShareServiceFactory.init()` 统一初始化，代码更清晰
- ✅ ARouter 解耦：通过 ARouter 实现模块间解耦，base-core 与 share 模块完全解耦
- ✅ 业务层不直接依赖友盟API
- ✅ 如果更换SDK，只需修改实现层，业务层无需改动
- ✅ 配置统一管理，代码更清晰

### 6. 使用分享功能（完全封装，无需处理回调）

重要更新：分享功能已完全封装，业务层不需要在 `MainActivity` 中处理 `onActivityResult`！

分享组件内部使用透明代理 Activity 自动处理所有回调，业务层只需要调用 `share()` 方法即可：

    // 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 中使用：

    // 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<Button>(R.id.btnShare)?.setOnClickListener {
                shareContent()
            }
        }

        /**
         * 分享内容示例（推荐：使用统一的 share() 方法）
         */
        private fun shareContent() {
            // 创建分享内容（使用 Builder 模式）
            val content = ShareContent.builder()
                .setTitle("新大洲智能车控")
                .setDescription("分享给您一个有趣的内容")
                .setUrl("https://example.com/share/123")
                .setImageUrl("https://example.com/image.jpg")
                .setThumbImageUrl("https://example.com/thumb.jpg")
                // 不设置 platform，会显示分享弹窗
                .build()

            // 方式1：统一方法（推荐）- 显示分享弹窗，用户选择平台
            shareService.share(requireActivity(), content) { response: ShareResponse ->
                if (response.success) {
                    // response.data 就是用户选择的平台（SharePlatform）
                    val platform = response.data  // 例如：SharePlatform.WECHAT、SharePlatform.QQ 等
                    Timber.d("分享成功: 平台=${platform}")
                    Toast.makeText(requireContext(), "分享成功到：${platform}", Toast.LENGTH_SHORT).show()
                } else {
                    Timber.e("分享失败: ${response.errorMessage}")
                    Toast.makeText(requireContext(), "分享失败: ${response.errorMessage}", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

关键点：

- ✅ Fragment 中使用 `requireActivity()` 获取 Activity 实例
- ✅ 完全封装：分享回调在组件内部的透明代理 Activity 中自动处理
- ✅ 无需配置：业务层不需要在 `MainActivity` 中处理 `onActivityResult`
- ✅ 使用简单：只需调用 `share()` 方法，传入分享内容和回调即可

### ShareContent Builder 模式使用示例

    // 方式1：完整参数（网页分享）
    val content1 = ShareContent.builder()
        .setTitle("分享标题")
        .setDescription("分享描述")
        .setUrl("https://example.com")
        .setImageUrl("https://example.com/image.jpg")
        .setThumbImageUrl("https://example.com/thumb.jpg")
        .build()

    // 方式2：仅文本（纯文本分享）
    val content2 = ShareContent.builder()
        .setTitle("分享标题")
        .setDescription("分享描述")
        .build()

    // 方式3：图片分享（无链接）
    val content3 = ShareContent.builder()
        .setTitle("图片分享")
        .setDescription("这是一张图片")
        .setImageUrl("https://example.com/image.jpg")
        .build()

    // 方式4：链式调用，灵活组合
    val content4 = ShareContent.builder()
        .setTitle("标题")
        .setDescription("描述")
        .setUrl("https://example.com")
        .build()  // 只设置必填项，其他可选参数不设置

Builder 模式优势：

- ✅ 参数灵活，不需要创建多个构造函数
- ✅ 代码可读性强，链式调用清晰
- ✅ 参数验证在 `build()` 时统一检查
- ✅ 支持必填参数验证（title 和 description 不能为空）

## 扩展平台支持

以下平台接口已暴露，具体实现待完成：

- 抖音 - `shareToDouyin()` - 待实现
- 小红书 - `shareToXiaohongshu()` - 待实现
- 快手 - `shareToKuaishou()` - 待实现

## 参考文档

- 友盟分享官方文档
- 友盟分享 Android SDK 下载