You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Android系统分享面板分享应用专属富内容?

解决方案

核心需求实现:系统分享面板+应用专属参数

你的需求可以通过Android提供的ChooserTargetService(API 24及以上)实现,低版本则可以通过自定义应用选择列表兼容,两种方案都能满足「选中应用后添加专属Intent参数」的需求:

1. API 24+ 用ChooserTargetService实现系统面板回调

ChooserTargetService允许你拦截系统分享面板的目标选择逻辑,在用户选中应用时触发自定义处理,具体步骤:

  • 注册服务:在Manifest中声明自定义服务,需绑定指定权限:
<service
    android:name=".MyChooserTargetService"
    android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
    <intent-filter>
        <action android:name="android.service.chooser.ChooserTargetService" />
    </intent-filter>
</service>
  • 实现服务逻辑:继承ChooserTargetService,为每个分享目标绑定自定义PendingIntent:
class MyChooserTargetService : ChooserTargetService() {
    override fun onGetChooserTargets(targetIntent: Intent?, filteredTargets: MutableList<ChooserTarget>?): MutableList<ChooserTarget> {
        val modifiedTargets = mutableListOf<ChooserTarget>()
        filteredTargets?.forEach { originalTarget ->
            // 携带目标包名与原始Intent,创建触发用PendingIntent
            val triggerIntent = Intent(this, ShareHandlerActivity::class.java).apply {
                putExtra("TARGET_PACKAGE", originalTarget.componentName.packageName)
                putExtra("ORIGINAL_INTENT", targetIntent)
            }
            val pendingIntent = PendingIntent.getActivity(
                this,
                originalTarget.componentName.hashCode(),
                triggerIntent,
                PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
            )
            // 替换原目标的PendingIntent,构建新的分享目标
            val modifiedTarget = ChooserTarget(
                originalTarget.label,
                originalTarget.icon,
                originalTarget.score,
                pendingIntent,
                originalTarget.componentName
            )
            modifiedTargets.add(modifiedTarget)
        }
        return modifiedTargets
    }
}
  • 触发自定义分享面板:调用Intent.createChooser时指定你的服务:
val baseShareIntent = Intent(Intent.ACTION_SEND).apply {
    putExtra(Intent.EXTRA_TEXT, "基础分享文本")
    type = "text/plain" // 基础MIME类型用于面板初始筛选
}
val chooserIntent = Intent.createChooser(baseShareIntent, "分享到").apply {
    putExtra(Intent.EXTRA_CHOOSER_TARGET_SERVICE, ComponentName(context, MyChooserTargetService::class.java))
}
startActivity(chooserIntent)
  • 处理选中逻辑:在ShareHandlerActivity中根据包名构建专属Intent:
class ShareHandlerActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val targetPackage = intent.getStringExtra("TARGET_PACKAGE") ?: return
        val originalIntent = intent.getParcelableExtra<Intent>("ORIGINAL_INTENT") ?: return

        val finalIntent = when (targetPackage) {
            "com.instagram.android" -> {
                // Instagram专属参数:添加背景图+贴纸
                Intent(Intent.ACTION_SEND).apply {
                    setPackage(targetPackage)
                    putExtra(Intent.EXTRA_STREAM, Uri.parse("content://your_image_path"))
                    putExtra("interactive_asset_uri", Uri.parse("content://your_sticker_path"))
                    type = "image/*"
                }
            }
            "com.facebook.katana" -> {
                // Facebook专属参数配置
                Intent(Intent.ACTION_SEND).apply {
                    setPackage(targetPackage)
                    putExtra(Intent.EXTRA_STREAM, Uri.parse("content://your_image_path"))
                    type = "image/*"
                }
            }
            else -> {
                // 其他应用沿用基础配置
                originalIntent.setPackage(targetPackage)
                originalIntent
            }
        }
        startActivity(finalIntent)
        finish()
    }
}

2. 低版本兼容方案(API <24)

直接查询系统中支持分享的应用,自定义选择对话框(模仿系统面板样式),选中后直接构建专属Intent:

// 查询支持基础分享的应用列表
val baseIntent = Intent(Intent.ACTION_SEND).apply { type = "text/plain" }
val pm = packageManager
val resolveInfoList = pm.queryIntentActivities(baseIntent, 0)

// 整理应用名称与包名的映射
val shareOptions = resolveInfoList.map {
    Pair(it.loadLabel(pm).toString(), it.activityInfo.packageName)
}

// 显示自定义选择对话框
AlertDialog.Builder(this)
    .setTitle("分享到")
    .setItems(shareOptions.map { it.first }.toTypedArray()) { _, which ->
        val targetPackage = shareOptions[which].second
        val finalIntent = when (targetPackage) {
            "com.instagram.android" -> {
                Intent(Intent.ACTION_SEND).apply {
                    setPackage(targetPackage)
                    putExtra(Intent.EXTRA_STREAM, Uri.parse("content://your_image_path"))
                    type = "image/*"
                }
            }
            "com.android.mms" -> {
                Intent(Intent.ACTION_SEND).apply {
                    setPackage(targetPackage)
                    putExtra(Intent.EXTRA_TEXT, "短信专属分享文本")
                    type = "text/plain"
                }
            }
            // 其他应用逻辑配置...
            else -> {
                Intent(Intent.ACTION_SEND).apply {
                    setPackage(targetPackage)
                    putExtra(Intent.EXTRA_TEXT, "通用分享文本")
                    type = "text/plain"
                }
            }
        }
        startActivity(finalIntent)
    }
    .show()

额外问题:根据应用切换MIME类型

上述两种方案均可直接解决该需求:
在用户选中应用后,根据目标包名判断应用类型(如短信、FB、Instagram),直接为Intent设置对应的MIME类型和数据即可。自定义选择列表甚至可以跳过初始MIME筛选,直接展示所有可能的分享应用。

内容的提问来源于stack exchange,提问作者SimonSays

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 07:35:20