Since Android 10+, the Android Sharesheet has supported providing image previews of files shared using ACTION_SEND.
Making a custom ActivityResultContract with the Android documentation for sending binary content,
you get something like this:
class ShareVideo : ActivityResultContract<Uri, Unit>() {
override fun createIntent(context: Context, input: Uri): Intent {
return Intent(Intent.ACTION_SEND).apply {
type = "video/*"
putExtra(Intent.EXTRA_STREAM, input)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
}
override fun parseResult(resultCode: Int, intent: Intent?) {
return
}
}
...
@Composable
fun ShareVideo(file: Uri) {
val shareVideo = rememberLauncherForActivityResult(ShareVideo()) {}
Button(onClick={ shareVideo.launch(file) }) {
Text("Share Video")
}
}
However, this does not result in a preview image in the Sharesheet.
What am I doing wrong?

As it turns out, every answer implementing
ACTION_SENDwraps theIntent(Intent.ACTION_SEND)withIntent.createChooser(...)That is, every
ACTION_SENDintent should be wrapped inside of anACTION_CHOOSERintent, which itself mostly copies the information found in theACTION_SENDintent, which makes you wonder what the difference is. According to the documentation, theACTION_CHOOSERintent has a richer interface for when defaults are not allowed, or don't make sense. TheACTION_SENDintent is a simpler interface for when a default is intended.So the correct
ActivityResultContractimplementation for sharing binary files withACTION_SENDis something like