| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060 |
- package com.narutohuo.xindazhou.share.impl
- import android.app.Activity
- import android.content.Context
- import android.content.Intent
- import android.os.Handler
- import android.os.Looper
- import com.alibaba.android.arouter.facade.annotation.Route
- import com.alibaba.android.arouter.facade.template.IProvider
- import com.narutohuo.xindazhou.core.log.ILog
- import com.narutohuo.xindazhou.core.share.IShareService
- import com.narutohuo.xindazhou.share.api.ShareService
- import com.narutohuo.xindazhou.share.model.ShareConfig
- import com.narutohuo.xindazhou.share.model.ShareContent
- import com.narutohuo.xindazhou.share.model.SharePlatform
- import com.narutohuo.xindazhou.share.model.ShareResponse
- import com.umeng.commonsdk.UMConfigure
- import com.umeng.socialize.PlatformConfig
- import com.umeng.socialize.ShareAction
- import com.umeng.socialize.UMShareAPI
- import com.umeng.socialize.UMShareListener
- import com.umeng.socialize.bean.SHARE_MEDIA
- import com.umeng.socialize.media.UMImage
- import com.umeng.socialize.media.UMWeb
- import com.umeng.socialize.media.UMediaObject
- /**
- * 分享服务实现类(单例模式)
- *
- * 使用单例方便管理,多个界面可以共享同一个分享服务
- *
- * 封装友盟分享 SDK,提供统一的分享服务接口
- *
- * 通过 ARouter 注册,实现 base-core 与 share 模块的解耦
- */
- @Route(path = "/share/service", name = "分享服务")
- class ShareServiceImpl private constructor() : IProvider, IShareService, ShareService {
-
- companion object {
- @Volatile
- private var INSTANCE: ShareServiceImpl? = null
-
- /**
- * 获取分享服务单例
- */
- @JvmStatic
- fun getInstance(): ShareServiceImpl {
- return INSTANCE ?: synchronized(this) {
- INSTANCE ?: ShareServiceImpl().also { INSTANCE = it }
- }
- }
-
- /**
- * 销毁单例(用于测试)
- */
- @JvmStatic
- fun destroyInstance() {
- INSTANCE = null
- }
- }
-
- private val tag = "ShareService"
- private val mainHandler = Handler(Looper.getMainLooper())
- private var isInitialized = false
-
- // 临时存储分享内容和回调(用于弹窗选择平台后执行分享)
- private var pendingShareContent: ShareContent? = null
- private var pendingShareCallback: ((ShareResponse) -> Unit)? = null
-
- /**
- * ARouter IProvider 接口的初始化方法
- *
- * 注意:此方法在 ARouter 初始化 provider 时调用,不应该抛出异常
- */
- override fun init(context: Context) {
- try {
- ILog.d(tag, "ShareServiceImpl 初始化(ARouter)")
- // 这里不进行实际的初始化,实际的初始化在 ShareServiceFactory.init() 中完成
- // 这样可以避免在 ARouter 初始化时出现问题
- } catch (e: Exception) {
- // 确保不会抛出异常,避免影响 ARouter 初始化
- ILog.e(tag, "ShareServiceImpl ARouter 初始化异常(不影响使用)", e)
- }
- }
-
- // ========== IShareService 接口实现(适配层) ==========
-
- override fun initialize(
- context: Context,
- umengAppKey: String?,
- umengChannel: String,
- weChatAppId: String?,
- weChatAppSecret: String?,
- qqAppId: String?,
- qqAppKey: String?,
- weiboAppKey: String?,
- weiboAppSecret: String?,
- weiboRedirectUrl: String?
- ) {
- // 适配 IShareService 接口,将参数转换为 ShareConfig
- val config = ShareConfig(
- umengAppKey = umengAppKey,
- umengChannel = umengChannel,
- weChatConfig = if (weChatAppId != null && weChatAppSecret != null) {
- com.narutohuo.xindazhou.share.model.WeChatConfig(
- appId = weChatAppId,
- appSecret = weChatAppSecret
- )
- } else null,
- qqConfig = if (qqAppId != null && qqAppKey != null) {
- com.narutohuo.xindazhou.share.model.QQConfig(
- appId = qqAppId,
- appKey = qqAppKey
- )
- } else null,
- weiboConfig = if (weiboAppKey != null && weiboAppSecret != null && weiboRedirectUrl != null) {
- com.narutohuo.xindazhou.share.model.WeiboConfig(
- appKey = weiboAppKey,
- appSecret = weiboAppSecret,
- redirectUrl = weiboRedirectUrl
- )
- } else null
- )
- initialize(context, config)
- }
-
- override fun share(
- activity: Activity,
- title: String,
- description: String,
- url: String?,
- imageUrl: String?,
- thumbImageUrl: String?,
- platform: String?,
- callback: (Boolean, String?, String?) -> Unit
- ) {
- // 适配 IShareService 接口,将基本类型参数转换为 ShareContent
- val platformEnum = platform?.let {
- try {
- SharePlatform.valueOf(it.uppercase())
- } catch (e: Exception) {
- null
- }
- }
- val content = ShareContent(
- title = title,
- description = description,
- platform = platformEnum,
- url = url,
- imageUrl = imageUrl,
- thumbImageUrl = thumbImageUrl
- )
- share(activity, content) { response ->
- callback(response.success, response.data?.name, response.errorMessage)
- }
- }
-
- override fun shareManual(
- activity: Activity,
- title: String,
- description: String,
- url: String?,
- imageUrl: String?,
- thumbImageUrl: String?,
- platform: String?,
- callback: (Boolean, String?, String?) -> Unit
- ) {
- val platformEnum = platform?.let {
- try {
- SharePlatform.valueOf(it.uppercase())
- } catch (e: Exception) {
- null
- }
- }
- val content = ShareContent(
- title = title,
- description = description,
- platform = platformEnum,
- url = url,
- imageUrl = imageUrl,
- thumbImageUrl = thumbImageUrl
- )
- shareManual(activity, content) { response ->
- callback(response.success, response.data?.name, response.errorMessage)
- }
- }
-
- override fun showShareDialog(
- activity: Activity,
- title: String,
- description: String,
- url: String?,
- imageUrl: String?,
- thumbImageUrl: String?,
- callback: (Boolean, String?, String?) -> Unit
- ) {
- val content = ShareContent(
- title = title,
- description = description,
- platform = null,
- url = url,
- imageUrl = imageUrl,
- thumbImageUrl = thumbImageUrl
- )
- showShareDialog(activity, content) { response ->
- callback(response.success, response.data?.name, response.errorMessage)
- }
- }
-
- override fun shareToWeChat(
- activity: Activity,
- title: String,
- description: String,
- url: String?,
- imageUrl: String?,
- thumbImageUrl: String?,
- callback: (Boolean, String?, String?) -> Unit
- ) {
- val content = ShareContent(
- title = title,
- description = description,
- platform = SharePlatform.WECHAT,
- url = url,
- imageUrl = imageUrl,
- thumbImageUrl = thumbImageUrl
- )
- shareToWeChat(activity, content) { response ->
- callback(response.success, response.data?.name, response.errorMessage)
- }
- }
-
- override fun shareToWeChatMoments(
- activity: Activity,
- title: String,
- description: String,
- url: String?,
- imageUrl: String?,
- thumbImageUrl: String?,
- callback: (Boolean, String?, String?) -> Unit
- ) {
- val content = ShareContent(
- title = title,
- description = description,
- platform = SharePlatform.WECHAT_MOMENTS,
- url = url,
- imageUrl = imageUrl,
- thumbImageUrl = thumbImageUrl
- )
- shareToWeChatMoments(activity, content) { response ->
- callback(response.success, response.data?.name, response.errorMessage)
- }
- }
-
- override fun shareToQQ(
- activity: Activity,
- title: String,
- description: String,
- url: String?,
- imageUrl: String?,
- thumbImageUrl: String?,
- callback: (Boolean, String?, String?) -> Unit
- ) {
- val content = ShareContent(
- title = title,
- description = description,
- platform = SharePlatform.QQ,
- url = url,
- imageUrl = imageUrl,
- thumbImageUrl = thumbImageUrl
- )
- shareToQQ(activity, content) { response ->
- callback(response.success, response.data?.name, response.errorMessage)
- }
- }
-
- override fun shareToQZone(
- activity: Activity,
- title: String,
- description: String,
- url: String?,
- imageUrl: String?,
- thumbImageUrl: String?,
- callback: (Boolean, String?, String?) -> Unit
- ) {
- val content = ShareContent(
- title = title,
- description = description,
- platform = SharePlatform.QZONE,
- url = url,
- imageUrl = imageUrl,
- thumbImageUrl = thumbImageUrl
- )
- shareToQZone(activity, content) { response ->
- callback(response.success, response.data?.name, response.errorMessage)
- }
- }
-
- override fun shareToWeibo(
- activity: Activity,
- title: String,
- description: String,
- url: String?,
- imageUrl: String?,
- thumbImageUrl: String?,
- callback: (Boolean, String?, String?) -> Unit
- ) {
- val content = ShareContent(
- title = title,
- description = description,
- platform = SharePlatform.WEIBO,
- url = url,
- imageUrl = imageUrl,
- thumbImageUrl = thumbImageUrl
- )
- shareToWeibo(activity, content) { response ->
- callback(response.success, response.data?.name, response.errorMessage)
- }
- }
-
- override fun shareToDouyin(
- activity: Activity,
- title: String,
- description: String,
- url: String?,
- imageUrl: String?,
- thumbImageUrl: String?,
- callback: (Boolean, String?, String?) -> Unit
- ) {
- val content = ShareContent(
- title = title,
- description = description,
- platform = SharePlatform.DOUYIN,
- url = url,
- imageUrl = imageUrl,
- thumbImageUrl = thumbImageUrl
- )
- shareToDouyin(activity, content) { response ->
- callback(response.success, response.data?.name, response.errorMessage)
- }
- }
-
- override fun shareToXiaohongshu(
- activity: Activity,
- title: String,
- description: String,
- url: String?,
- imageUrl: String?,
- thumbImageUrl: String?,
- callback: (Boolean, String?, String?) -> Unit
- ) {
- val content = ShareContent(
- title = title,
- description = description,
- platform = SharePlatform.XIAOHONGSHU,
- url = url,
- imageUrl = imageUrl,
- thumbImageUrl = thumbImageUrl
- )
- shareToXiaohongshu(activity, content) { response ->
- callback(response.success, response.data?.name, response.errorMessage)
- }
- }
-
- override fun shareToKuaishou(
- activity: Activity,
- title: String,
- description: String,
- url: String?,
- imageUrl: String?,
- thumbImageUrl: String?,
- callback: (Boolean, String?, String?) -> Unit
- ) {
- val content = ShareContent(
- title = title,
- description = description,
- platform = SharePlatform.KUAISHOU,
- url = url,
- imageUrl = imageUrl,
- thumbImageUrl = thumbImageUrl
- )
- shareToKuaishou(activity, content) { response ->
- callback(response.success, response.data?.name, response.errorMessage)
- }
- }
-
- override fun shareToSystem(
- activity: Activity,
- title: String,
- description: String,
- url: String?,
- imageUrl: String?,
- thumbImageUrl: String?,
- callback: (Boolean, String?, String?) -> Unit
- ) {
- val content = ShareContent(
- title = title,
- description = description,
- platform = SharePlatform.SYSTEM,
- url = url,
- imageUrl = imageUrl,
- thumbImageUrl = thumbImageUrl
- )
- shareToSystem(activity, content) { response ->
- callback(response.success, response.data?.name, response.errorMessage)
- }
- }
-
- // ========== ShareService 接口实现(原有接口) ==========
-
- override fun initialize(context: Context, config: ShareConfig) {
- if (isInitialized) {
- ILog.w(tag, "分享服务已经初始化,跳过重复初始化")
- return
- }
-
- ILog.d(tag, "初始化分享服务")
-
- try {
- // 获取友盟 AppKey(优先使用配置中的,否则从资源文件读取)
- val umengAppKey = config.umengAppKey ?: run {
- val resources = context.resources
- val packageName = context.packageName
- try {
- val resId = resources.getIdentifier("share_umeng_app_key", "string", packageName)
- if (resId != 0) {
- resources.getString(resId)
- } else {
- throw IllegalArgumentException("友盟 AppKey 未配置,请在 ShareConfig 中设置或 strings.xml 中定义 share_umeng_app_key")
- }
- } catch (e: Exception) {
- throw IllegalArgumentException("友盟 AppKey 未配置,请在 ShareConfig 中设置或 strings.xml 中定义 share_umeng_app_key", e)
- }
- }
-
- // 初始化友盟
- UMConfigure.init(
- context.applicationContext,
- umengAppKey,
- config.umengChannel,
- UMConfigure.DEVICE_TYPE_PHONE,
- null
- )
-
- // 配置微信平台
- config.weChatConfig?.let {
- PlatformConfig.setWeixin(it.appId, it.appSecret)
- ILog.d(tag, "微信平台配置完成")
- }
-
- // 配置QQ平台
- config.qqConfig?.let {
- if (it.appId.isNotBlank() && it.appKey.isNotBlank() &&
- it.appId != "your_qq_appid_here" && it.appKey != "your_qq_appkey_here") {
- PlatformConfig.setQQZone(it.appId, it.appKey)
- ILog.d(tag, "QQ平台配置完成: appId=${it.appId}, appKey=${it.appKey.take(5)}...")
- } else {
- ILog.w(tag, "QQ平台配置无效,QQ分享功能将不可用。请在 strings.xml 中配置正确的 share_qq_app_id 和 share_qq_app_key")
- }
- } ?: run {
- ILog.w(tag, "QQ平台未配置,QQ分享功能将不可用。请在 strings.xml 中配置 share_qq_app_id 和 share_qq_app_key")
- }
-
- // 配置微博平台
- config.weiboConfig?.let {
- PlatformConfig.setSinaWeibo(it.appKey, it.appSecret, it.redirectUrl)
- ILog.d(tag, "微博平台配置完成: appKey=${it.appKey.take(5)}..., redirectUrl=${it.redirectUrl}")
- } ?: run {
- ILog.w(tag, "微博平台未配置,微博分享功能将不可用。请在 strings.xml 中配置 share_weibo_app_key、share_weibo_app_secret 和 share_weibo_redirect_url")
- }
-
- isInitialized = true
- ILog.d(tag, "分享服务初始化完成")
- } catch (e: Exception) {
- ILog.e(tag, "分享服务初始化失败", e)
- throw e
- }
- }
-
- override fun onActivityResult(activity: Activity, requestCode: Int, resultCode: Int, data: Intent?) {
- try {
- // 处理友盟分享回调
- UMShareAPI.get(activity).onActivityResult(requestCode, resultCode, data)
- } catch (e: Exception) {
- ILog.e(tag, "处理分享回调失败", e)
- }
- }
-
- override fun release(activity: Activity) {
- try {
- // 释放友盟分享资源
- UMShareAPI.get(activity).release()
- ILog.d(tag, "分享服务资源已释放")
- } catch (e: Exception) {
- ILog.e(tag, "释放分享服务资源失败", e)
- }
- }
-
- override fun share(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit) {
- // 自动启动 ShareProxyActivity,统一处理所有平台的分享回调
- // 业务层不需要在 Activity 的 onActivityResult 中处理回调,完全封装在模块内部
- com.narutohuo.xindazhou.share.ui.ShareProxyActivity.startShare(activity, content, callback)
- }
-
- /**
- * 分享(可选回调)
- *
- * 如果不提供回调,会使用全局回调(如果已设置)
- */
- @JvmOverloads
- fun shareWithOptionalCallback(activity: Activity, content: ShareContent, callback: ((ShareResponse) -> Unit)? = null) {
- val finalCallback = callback ?: com.narutohuo.xindazhou.share.factory.ShareServiceFactory.getGlobalCallback()
- if (finalCallback != null) {
- share(activity, content, finalCallback)
- } else {
- ILog.w(tag, "分享时未提供回调,且全局回调未设置,分享结果将无法获取")
- // 仍然执行分享,但结果会被忽略
- share(activity, content) { /* ignore */ }
- }
- }
-
- /**
- * 手动分享方法(内部使用,避免递归调用)
- *
- * 如果指定了平台,直接分享到该平台;否则显示分享弹窗
- * 此方法不会启动 ShareProxyActivity,用于 ShareProxyActivity 内部调用
- *
- * 注意:业务层应该使用 share() 方法,它会自动处理所有回调
- */
- override fun shareManual(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit) {
- // 如果指定了平台,直接分享到该平台
- if (content.platform != null) {
- shareToPlatform(activity, content, content.platform, callback)
- } else {
- // 否则显示分享弹窗
- showShareDialog(activity, content, callback)
- }
- }
-
- override fun showShareDialog(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit) {
- // 使用 ShareDialogFragment 显示分享弹窗
- if (activity !is androidx.fragment.app.FragmentActivity) {
- ILog.e(tag, "showShareDialog: Activity 必须是 FragmentActivity")
- callback(
- ShareResponse(
- success = false,
- errorMessage = "Activity 必须是 FragmentActivity",
- timestamp = System.currentTimeMillis()
- )
- )
- return
- }
-
- // 临时存储回调和内容
- pendingShareContent = content
- pendingShareCallback = callback
-
- val dialog = com.narutohuo.xindazhou.share.ui.ShareDialogFragment.newInstance(this)
- dialog.show(activity.supportFragmentManager, "ShareDialog")
- }
-
- /**
- * 执行分享(由 ShareDialogFragment 调用)
- */
- fun executeShare(activity: Activity, platform: SharePlatform) {
- val content = pendingShareContent ?: run {
- pendingShareCallback?.invoke(
- ShareResponse(
- success = false,
- errorMessage = "分享内容为空",
- timestamp = System.currentTimeMillis()
- )
- )
- clearPendingShare()
- return
- }
-
- val callback = pendingShareCallback ?: return
- clearPendingShare()
-
- val contentWithPlatform = content.copy(platform = platform)
- shareToPlatform(activity, contentWithPlatform, platform, callback)
- }
-
- /**
- * 清除待处理的分享
- */
- private fun clearPendingShare() {
- pendingShareContent = null
- pendingShareCallback = null
- }
-
- /**
- * 根据平台类型分享到指定平台
- */
- private fun shareToPlatform(
- activity: Activity,
- content: ShareContent,
- platform: SharePlatform,
- callback: (ShareResponse) -> Unit
- ) {
- when (platform) {
- SharePlatform.WECHAT -> shareToWeChat(activity, content, callback)
- SharePlatform.WECHAT_MOMENTS -> shareToWeChatMoments(activity, content, callback)
- SharePlatform.QQ -> shareToQQ(activity, content, callback)
- SharePlatform.QZONE -> shareToQZone(activity, content, callback)
- SharePlatform.WEIBO -> shareToWeibo(activity, content, callback)
- SharePlatform.DOUYIN -> {
- // 抖音分享暂时禁用,需要字节跳动 SDK
- callback(
- ShareResponse(
- success = false,
- data = SharePlatform.DOUYIN,
- errorMessage = "抖音分享功能暂未启用",
- timestamp = System.currentTimeMillis()
- )
- )
- }
- SharePlatform.XIAOHONGSHU -> shareToXiaohongshu(activity, content, callback)
- SharePlatform.KUAISHOU -> shareToKuaishou(activity, content, callback)
- SharePlatform.SYSTEM -> shareToSystem(activity, content, callback)
- }
- }
-
- /**
- * 创建友盟分享监听器
- */
- private fun createShareListener(
- platform: SharePlatform,
- callback: (ShareResponse) -> Unit
- ): UMShareListener {
- return object : UMShareListener {
- override fun onStart(shareMedia: SHARE_MEDIA?) {
- ILog.d(tag, "onStart: $shareMedia")
- }
-
- override fun onResult(shareMedia: SHARE_MEDIA?) {
- ILog.d(tag, "onResult: $shareMedia 分享成功")
- mainHandler.post {
- callback(
- ShareResponse(
- success = true,
- data = platform,
- timestamp = System.currentTimeMillis()
- )
- )
- }
- }
-
- override fun onError(shareMedia: SHARE_MEDIA?, throwable: Throwable?) {
- val errorMsg = throwable?.message ?: "分享失败"
- ILog.e(tag, "onError: $shareMedia - $errorMsg", throwable)
-
- // 解析错误信息,提供更友好的提示
- val friendlyMsg = when {
- errorMsg.contains("未安装", ignoreCase = true) ||
- errorMsg.contains("not installed", ignoreCase = true) -> {
- when (platform) {
- SharePlatform.WECHAT, SharePlatform.WECHAT_MOMENTS -> "请先安装微信"
- SharePlatform.QQ, SharePlatform.QZONE -> "请先安装 QQ"
- SharePlatform.WEIBO -> "请先安装微博"
- else -> "请先安装对应的应用"
- }
- }
- errorMsg.contains("未授权", ignoreCase = true) ||
- errorMsg.contains("unauthorized", ignoreCase = true) ||
- errorMsg.contains("2008", ignoreCase = true) -> {
- when (platform) {
- SharePlatform.QQ, SharePlatform.QZONE -> "QQ 未授权,请在 QQ 开放平台申请并配置 AppID 和 AppKey"
- else -> "未授权,请检查配置"
- }
- }
- errorMsg.contains("取消", ignoreCase = true) ||
- errorMsg.contains("cancel", ignoreCase = true) -> "用户取消分享"
- else -> errorMsg
- }
-
- mainHandler.post {
- callback(
- ShareResponse(
- success = false,
- data = platform,
- errorMessage = friendlyMsg,
- timestamp = System.currentTimeMillis()
- )
- )
- }
- }
-
- override fun onCancel(shareMedia: SHARE_MEDIA?) {
- ILog.d(tag, "onCancel: $shareMedia 分享取消")
- mainHandler.post {
- callback(
- ShareResponse(
- success = false,
- data = platform,
- errorMessage = "用户取消分享",
- timestamp = System.currentTimeMillis()
- )
- )
- }
- }
- }
- }
-
- /**
- * 将 SharePlatform 转换为 SHARE_MEDIA
- */
- private fun toShareMedia(platform: SharePlatform): SHARE_MEDIA? {
- return when (platform) {
- SharePlatform.WECHAT -> SHARE_MEDIA.WEIXIN
- SharePlatform.WECHAT_MOMENTS -> SHARE_MEDIA.WEIXIN_CIRCLE
- SharePlatform.QQ -> SHARE_MEDIA.QQ
- SharePlatform.QZONE -> SHARE_MEDIA.QZONE
- SharePlatform.WEIBO -> SHARE_MEDIA.SINA
- SharePlatform.DOUYIN -> null // 抖音分享暂时禁用
- SharePlatform.XIAOHONGSHU -> null // 小红书可能需要使用其他SDK
- SharePlatform.KUAISHOU -> null // 快手可能需要使用其他SDK
- SharePlatform.SYSTEM -> SHARE_MEDIA.SMS // 系统分享使用短信作为占位符
- }
- }
-
- /**
- * 创建分享内容(UMWeb 或 UMImage)
- */
- @Suppress("UNCHECKED_CAST")
- private fun createShareMedia(activity: Activity, content: ShareContent): Any {
- return if (content.url != null) {
- // 有 URL,创建网页分享
- val web = UMWeb(content.url)
- web.title = content.title
- web.description = content.description
-
- // 设置缩略图
- if (content.thumbImageUrl != null) {
- web.setThumb(UMImage(activity, content.thumbImageUrl))
- } else if (content.imageUrl != null) {
- web.setThumb(UMImage(activity, content.imageUrl))
- }
-
- web
- } else if (content.imageUrl != null) {
- // 只有图片,创建图片分享
- UMImage(activity, content.imageUrl)
- } else {
- // 只有文本,创建文本分享(友盟不支持纯文本,使用网页形式)
- val web = UMWeb("")
- web.title = content.title
- web.description = content.description
- web
- }
- }
-
- override fun shareToWeChat(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit) {
- ILog.d(tag, "shareToWeChat: ${content.title}")
-
- try {
- val shareMedia = createShareMedia(activity, content)
- val shareAction = ShareAction(activity)
- when (shareMedia) {
- is UMWeb -> shareAction.withMedia(shareMedia)
- is UMImage -> shareAction.withMedia(shareMedia)
- else -> throw IllegalArgumentException("不支持的分享类型: ${shareMedia.javaClass.name}")
- }
- shareAction.setPlatform(SHARE_MEDIA.WEIXIN)
- shareAction.setCallback(createShareListener(SharePlatform.WECHAT, callback))
- shareAction.share()
- } catch (e: Exception) {
- ILog.e(tag, "shareToWeChat: 分享失败", e)
- callback(
- ShareResponse(
- success = false,
- data = SharePlatform.WECHAT,
- errorMessage = e.message ?: "分享失败",
- timestamp = System.currentTimeMillis()
- )
- )
- }
- }
-
- override fun shareToWeChatMoments(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit) {
- ILog.d(tag, "shareToWeChatMoments: ${content.title}")
-
- try {
- val shareMedia = createShareMedia(activity, content)
- val shareAction = ShareAction(activity)
- when (shareMedia) {
- is UMWeb -> shareAction.withMedia(shareMedia)
- is UMImage -> shareAction.withMedia(shareMedia)
- else -> throw IllegalArgumentException("不支持的分享类型: ${shareMedia.javaClass.name}")
- }
- shareAction.setPlatform(SHARE_MEDIA.WEIXIN_CIRCLE)
- shareAction.setCallback(createShareListener(SharePlatform.WECHAT_MOMENTS, callback))
- shareAction.share()
- } catch (e: Exception) {
- ILog.e(tag, "shareToWeChatMoments: 分享失败", e)
- callback(
- ShareResponse(
- success = false,
- data = SharePlatform.WECHAT_MOMENTS,
- errorMessage = e.message ?: "分享失败",
- timestamp = System.currentTimeMillis()
- )
- )
- }
- }
-
- override fun shareToQQ(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit) {
- ILog.d(tag, "shareToQQ: ${content.title}")
-
- // 检查 QQ 是否已配置
- val resources = activity.resources
- val packageName = activity.packageName
- try {
- val qqAppIdResId = resources.getIdentifier("share_qq_app_id", "string", packageName)
- val qqAppKeyResId = resources.getIdentifier("share_qq_app_key", "string", packageName)
-
- if (qqAppIdResId == 0 || qqAppKeyResId == 0) {
- callback(
- ShareResponse(
- success = false,
- data = SharePlatform.QQ,
- errorMessage = "QQ 未配置,请在 strings.xml 中配置 share_qq_app_id 和 share_qq_app_key",
- timestamp = System.currentTimeMillis()
- )
- )
- return
- }
-
- val qqAppId = resources.getString(qqAppIdResId)
- val qqAppKey = resources.getString(qqAppKeyResId)
-
- if (qqAppId == "your_qq_appid_here" || qqAppKey == "your_qq_appkey_here" ||
- qqAppId.isBlank() || qqAppKey.isBlank()) {
- callback(
- ShareResponse(
- success = false,
- data = SharePlatform.QQ,
- errorMessage = "QQ 配置无效,请在 QQ 开放平台申请 AppID 和 AppKey,并在 strings.xml 中配置",
- timestamp = System.currentTimeMillis()
- )
- )
- return
- }
- } catch (e: Exception) {
- ILog.e(tag, "shareToQQ: 检查配置失败", e)
- }
-
- try {
- val shareMedia = createShareMedia(activity, content)
- val shareAction = ShareAction(activity)
- when (shareMedia) {
- is UMWeb -> shareAction.withMedia(shareMedia)
- is UMImage -> shareAction.withMedia(shareMedia)
- else -> throw IllegalArgumentException("不支持的分享类型: ${shareMedia.javaClass.name}")
- }
- shareAction.setPlatform(SHARE_MEDIA.QQ)
- shareAction.setCallback(createShareListener(SharePlatform.QQ, callback))
- shareAction.share()
- } catch (e: Exception) {
- ILog.e(tag, "shareToQQ: 分享失败", e)
- callback(
- ShareResponse(
- success = false,
- data = SharePlatform.QQ,
- errorMessage = e.message ?: "分享失败,请检查 QQ 是否已安装并正确配置",
- timestamp = System.currentTimeMillis()
- )
- )
- }
- }
-
- override fun shareToQZone(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit) {
- ILog.d(tag, "shareToQZone: ${content.title}")
-
- try {
- val shareMedia = createShareMedia(activity, content)
- val shareAction = ShareAction(activity)
- when (shareMedia) {
- is UMWeb -> shareAction.withMedia(shareMedia)
- is UMImage -> shareAction.withMedia(shareMedia)
- else -> throw IllegalArgumentException("不支持的分享类型: ${shareMedia.javaClass.name}")
- }
- shareAction.setPlatform(SHARE_MEDIA.QZONE)
- shareAction.setCallback(createShareListener(SharePlatform.QZONE, callback))
- shareAction.share()
- } catch (e: Exception) {
- ILog.e(tag, "shareToQZone: 分享失败", e)
- callback(
- ShareResponse(
- success = false,
- data = SharePlatform.QZONE,
- errorMessage = e.message ?: "分享失败",
- timestamp = System.currentTimeMillis()
- )
- )
- }
- }
-
- override fun shareToWeibo(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit) {
- ILog.d(tag, "shareToWeibo: ${content.title}")
-
- try {
- val shareMedia = createShareMedia(activity, content)
- val shareAction = ShareAction(activity)
- when (shareMedia) {
- is UMWeb -> shareAction.withMedia(shareMedia)
- is UMImage -> shareAction.withMedia(shareMedia)
- else -> throw IllegalArgumentException("不支持的分享类型: ${shareMedia.javaClass.name}")
- }
- shareAction.setPlatform(SHARE_MEDIA.SINA)
- shareAction.setCallback(createShareListener(SharePlatform.WEIBO, callback))
- shareAction.share()
- } catch (e: Exception) {
- ILog.e(tag, "shareToWeibo: 分享失败", e)
- callback(
- ShareResponse(
- success = false,
- data = SharePlatform.WEIBO,
- errorMessage = e.message ?: "分享失败",
- timestamp = System.currentTimeMillis()
- )
- )
- }
- }
-
- override fun shareToDouyin(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit) {
- ILog.d(tag, "shareToDouyin: ${content.title} - 抖音分享暂时禁用")
- // 抖音分享暂时禁用,需要字节跳动 SDK
- callback(
- ShareResponse(
- success = false,
- data = SharePlatform.DOUYIN,
- errorMessage = "抖音分享功能暂未启用",
- timestamp = System.currentTimeMillis()
- )
- )
- }
-
- override fun shareToXiaohongshu(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit) {
- ILog.d(tag, "shareToXiaohongshu: ${content.title}")
-
- try {
- // 小红书分享:需要使用小红书开放平台SDK或通过系统分享
- // TODO: 集成小红书开放平台SDK后实现具体逻辑
- // 目前使用系统分享作为临时方案
-
- val intent = Intent(Intent.ACTION_SEND).apply {
- type = "text/plain"
- putExtra(Intent.EXTRA_SUBJECT, content.title)
- putExtra(Intent.EXTRA_TEXT, "${content.title}\n${content.description}\n${content.url ?: ""}")
- // 指定小红书包名(如果已安装)
- setPackage("com.xingin.xhs")
- }
-
- // 如果小红书未安装,使用系统分享
- if (intent.resolveActivity(activity.packageManager) != null) {
- activity.startActivity(intent)
- callback(
- ShareResponse(
- success = true,
- data = SharePlatform.XIAOHONGSHU,
- timestamp = System.currentTimeMillis()
- )
- )
- } else {
- // 回退到系统分享
- shareToSystem(activity, content, callback)
- }
- } catch (e: Exception) {
- ILog.e(tag, "shareToXiaohongshu: 分享失败", e)
- callback(
- ShareResponse(
- success = false,
- data = SharePlatform.XIAOHONGSHU,
- errorMessage = e.message ?: "分享失败,请安装小红书App",
- timestamp = System.currentTimeMillis()
- )
- )
- }
- }
-
- override fun shareToKuaishou(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit) {
- ILog.d(tag, "shareToKuaishou: ${content.title}")
-
- try {
- // 快手分享:需要使用快手开放平台SDK或通过系统分享
- // TODO: 集成快手开放平台SDK后实现具体逻辑
- // 目前使用系统分享作为临时方案
-
- val intent = Intent(Intent.ACTION_SEND).apply {
- type = "text/plain"
- putExtra(Intent.EXTRA_SUBJECT, content.title)
- putExtra(Intent.EXTRA_TEXT, "${content.title}\n${content.description}\n${content.url ?: ""}")
- // 指定快手包名(如果已安装)
- setPackage("com.smile.gifmaker")
- }
-
- // 如果快手未安装,使用系统分享
- if (intent.resolveActivity(activity.packageManager) != null) {
- activity.startActivity(intent)
- callback(
- ShareResponse(
- success = true,
- data = SharePlatform.KUAISHOU,
- timestamp = System.currentTimeMillis()
- )
- )
- } else {
- // 回退到系统分享
- shareToSystem(activity, content, callback)
- }
- } catch (e: Exception) {
- ILog.e(tag, "shareToKuaishou: 分享失败", e)
- callback(
- ShareResponse(
- success = false,
- data = SharePlatform.KUAISHOU,
- errorMessage = e.message ?: "分享失败,请安装快手App",
- timestamp = System.currentTimeMillis()
- )
- )
- }
- }
-
- override fun shareToSystem(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit) {
- ILog.d(tag, "shareToSystem: ${content.title}")
-
- try {
- // 系统分享使用 Android 原生 Intent
- val intent = Intent(Intent.ACTION_SEND).apply {
- type = "text/plain"
- putExtra(Intent.EXTRA_SUBJECT, content.title)
- putExtra(Intent.EXTRA_TEXT, "${content.title}\n${content.description}\n${content.url ?: ""}")
- }
-
- val chooser = Intent.createChooser(intent, "分享到")
- activity.startActivity(chooser)
-
- // 系统分享无法获取结果,直接返回成功
- callback(
- ShareResponse(
- success = true,
- data = SharePlatform.SYSTEM,
- timestamp = System.currentTimeMillis()
- )
- )
- } catch (e: Exception) {
- ILog.e(tag, "shareToSystem: 分享失败", e)
- callback(
- ShareResponse(
- success = false,
- data = SharePlatform.SYSTEM,
- errorMessage = e.message ?: "分享失败",
- timestamp = System.currentTimeMillis()
- )
- )
- }
- }
- }
|