画像とテキストを共有するには (ACTION_SEND)

AndroidでSNS機能の共有シートを表示させるのは簡単ですが、プレビュー機能(Android 10以上)が少し分かりにくいです。

画像とテキストを共有する

画像とテキストの両方のプレビューはできないので、画像だけをプレビューさせます。

Intent(Intent.ACTION_SEND)
    .putExtra(Intent.EXTRA_STREAM, imageUri)
    .putExtra(Intent.EXTRA_TEXT, urlText)
    .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)// Preview image
    .setDataAndType(imageUri, "image/jpeg")// Preview image
    .let { Intent.createChooser(it, null) }
    .also(::startActivity)

データURIのみを設定するには、setData()を使います。MIMEタイプのみを設定するには、setType()を使います。今回のようにテキストと画像であれば、お互いの値を打ち消さないように、setDataAndType()を使うことが推奨されています。Intents and Intent Filters

テキストのみを共有する場合

テキストのプレビューには、ClipDataを渡すと左側にサムネイル画像を追加できます。これは、長いURLを共有する場合に、WEBアイコンなどを添えて分かりやすくできる仕組みです。共有したい画像のプレビューには使えません。

Intent(Intent.ACTION_SEND).also {
    it.setType("text/plain")
    it.putExtra(Intent.EXTRA_TEXT, text)
    it.putExtra(Intent.EXTRA_TITLE, text)// Preview text
    it.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)// Preview thumbnail
    it.clipData = ClipData.newRawUri(null, thumbUri)// Preview thumbnail
    startActivity(Intent.createChooser(it, null))
}

共有シートに自分のアプリを表示させたくない

他のアプリから画像やテキストを受け取れるActivity(intent-filter)を保有している場合は、共有シートに自分のアプリが表示されてしまうので、ChooserのIntent.EXTRA_EXCLUDE_COMPONENTSに該当アクティビティを設定して除外することができます。

val components = arrayOf(ComponentName(applicationContext, SharingActivity::class.java))
Intent.createChooser(it, null).putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, components)