I'm trying to implement share logic in my application. Intent contains just a basic text, but there are applications that I need to pass additional image. For that reason I am building intent like this:
val intent = Intent().apply {
action = Intent.ACTION_SEND
type = "image/jpeg"
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
putExtra(Intent.EXTRA_TEXT, intentText)
//putExtra(Intent.EXTRA_STREAM, fileToShare)
}
val share = Intent.createChooser(intent, null)
share.putExtra(
Intent.EXTRA_REPLACEMENT_EXTRAS, bundleOf(
"com.google.android.gm" to bundleOf(
Intent.EXTRA_STREAM to fileToShare
),
"com.whatsapp" to bundleOf(
Intent.EXTRA_STREAM to fileToShare
),
)
)
The problem is the apps that need to receive image cant load passed to fileToShare image. There are no errors, just a Toast in Telegram that says that something like Bad file format. In the same time if i just pass exactly same image not in createChooser but in regular intent construction (take a look at the commented line) all works just fine.
Related
I am trying to send image with default android message app. There are three conditions.
I don't want to show intent chooser, which means I don't want to show share bottom sheet.
I want to send message with image.
Have to use Intent.ACTION_SENDTO, not Intent.ACTION_SEND. When I use Intent.ACTION_SEND, it shows intent chooser. I have to send message directly to the default android app.
I tried several code, but it's hard to send message with image. Here are some code that I tried.
1.
val intent = Intent(Intent.ACTION_SENDTO).apply {
putExtra("sms_body", "hello")
putExtra(Intent.EXTRA_STREAM, uri)
data = Uri.parse("smsto:12345")
}
val intent = Intent(Intent.ACTION_SENDTO).apply {
putExtra("sms_body", "hello")
putExtra(Intent.EXTRA_STREAM, uri)
data = Uri.parse("smsto:12345")
type = "image/png"
}
My app can share internally stored files with the androidx.core.content.FileProvider.
The intent and the chooser are created with the following snippet:
val shareIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(
Intent.EXTRA_STREAM,
FileProvider.getUriForFile(this, authority, file, displayName),
)
type = document.mimeType.mediaType
}
startActivity(Intent.createChooser(shareIntent, getString(R.string.share_title)))
I explicitly pass the displayName to the FileProvider, but in the app chooser, I see the file's local name (see image).
Is there a way to show the correct display name in the chooser?
I would like to display a small preview image of my content to be shared. However, when I run the code, I get a message that no app can perform this action. Unfortunately I don't know what's wrong
private fun shareContentWithPreview() {
val share = Intent.createChooser(Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, "https://developer.android.com/training/sharing/")
type = "image/jpg"
// (Optional) Here we're setting the title of the content
putExtra(Intent.EXTRA_TITLE, "Introducing content previews")
// (Optional) Here we're passing a content URI to an image to be displayed
val uri: Uri = Uri.parse("android.resource://com.one.myapplication/drawable/rome.jpg")
data = uri
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
}, null)
startActivity(Intent.createChooser(share, null))
}
Hi m8 think you are passing putExtra(Intent.EXTRA_TEXT, ...), and you should pass putExtra(Intent.EXTRA_STREAM, ...) if you a re passing a Uri
Is there a way to launch the Sharesheet (see https://developer.android.com/training/sharing/send) without having to wrap the called intent into the createChooser-returned intent, but rather specifying the wish for the Sharesheet as an ACTION and/or EXTRA. E.g. instead of
val sendIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, "This is my text to send.")
type = "text/plain"
}
val shareIntent = Intent.createChooser(sendIntent, null)
startActivity(shareIntent)
Something like:
val shareIntent: Intent = Intent().apply {
action = Intent.ACTION_CREATE_CHOOSER
putExtra(Intent.EXTRA_ACTION_TYPE, Intent.ACTION_SEND)
putExtra(Intent.EXTRA_TEXT, "This is my text to send.")
type = "text/plain"
}
startActivity(shareIntent)
My main goal is to get a Sharesheet that shows my frequent contacts/apps at the top. I'm not interested in all the functionality that createChooser might provide.
Should work at least in Android 11.
I want to pick Images(JPG, PNG) and GIF(gif) files separately. This works for most Gallery apps and file managers except Google Photos app. When I pick images or gifs using Google Photos app, all images are displayed i.e. JPG, PNG, GIF, BMP, etc. How can I tell Google Photos to allow picking only selected type of files?
Here's my code:
val contentPicker = activity.registerForActivityResult(
ActivityResultContracts.GetContent()
) { uri: Uri? ->
// Use Picked URI
}
val mime = when {
MediaType.isPhoto(mediaType) -> "image/*" // or image/jpg or image/png
MediaType.isGif(mediaType) -> "image/gif"
else -> throw RuntimeException("Wrong Media Type to pick: $mediaType")
}
contentPicker.launch(mime)
If there's another way besides this(maybe targeting Google Photos only), please share as an answer. I couldn't find any relevant question with proper answer. I want to use system apps only to pick content.
Edit (Nov 23, 2021)
Even if I use following intent to open Files app, a user can just go to Side Bar and select Photos app. Files app prevents picking gif/heic images. But, when Photos app is opened from within the Files app, user can select gif/heic images without any restriction.
fun getPickPhotoIntent(): Intent {
val pickIntent = Intent(Intent.ACTION_GET_CONTENT)
pickIntent.addCategory(Intent.CATEGORY_OPENABLE)
pickIntent.type = "image/jpg"
val mimeTypes = arrayOf("image/bmp", "image/jpeg", "image/png")
pickIntent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes)
pickIntent.putExtra(Intent.EXTRA_LOCAL_ONLY, true)
return pickIntent
}
fun getPickPhotoIntent(): Intent {
val pickIntent = Intent(com.google.android.apps.photos.picker.external.ExternalPickerActivity)//package name Used
pickIntent.addCategory(Intent.CATEGORY_OPENABLE)
pickIntent.type = "image/jpg"
val mimeTypes = arrayOf("image/bmp", "image/jpeg", "image/png")
pickIntent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes)
pickIntent.putExtra(Intent.EXTRA_LOCAL_ONLY, true)
return pickIntent
}