Skip to content

Instantly share code, notes, and snippets.

@noln
Last active July 17, 2024 14:33
Show Gist options
  • Save noln/584afabed1362fabbc2516275a5f755b to your computer and use it in GitHub Desktop.
Save noln/584afabed1362fabbc2516275a5f755b to your computer and use it in GitHub Desktop.
Share an Image or Video file to Instagram, via MediaStore Uri
import android.annotation.SuppressLint
import android.content.*
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import java.io.File
class MainActivity : AppCompatActivity() {
private val IG_PACKAGE = "com.instagram.android"
private val TAG = "Log Tag"
private lateinit var launchImageIntentButton: Button
private lateinit var launchVideoIntentButton: Button
@SuppressLint("SdCardPath")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// get a handle on the button
launchImageIntentButton = findViewById(R.id.button_image)
launchVideoIntentButton = findViewById(R.id.button_video)
// Copy the 'image.jpg' and 'video.mp4' files to /data/data/<your package name>/files
// for this example. Note: Ensure that you use the proper mechanism to get files directory
// from context for production app usage.
launchImageIntentButton.setOnClickListener { launchIntent("/data/data/$packageName/files/image.jpg") }
launchVideoIntentButton.setOnClickListener { launchIntent("/data/data/$packageName/files/video.mp4") }
}
private fun launchIntent(filePath: String) {
val context: Context? = this
val intent = Intent(Intent.ACTION_SEND)
insertToMediaStore(File(filePath))?.let { shareableContent ->
val clipLabel = when (shareableContent.mimeType.startsWith("image")) {
true -> "Image"
false -> "Video"
}
val clipData = ClipData.newRawUri(clipLabel, shareableContent.contentUri)
intent.type = shareableContent.mimeType
intent.clipData = clipData
intent.putExtra(Intent.EXTRA_STREAM, shareableContent.contentUri)
intent.`package` = IG_PACKAGE
val target = Intent.createChooser(intent, "Sharing Media")
target?.let { context?.startActivity(it) }
} ?: run {
Log.e(TAG, "Unsupported media file")
return
}
}
data class ShareableContent(val contentUri: Uri, val mimeType: String)
fun insertToMediaStore(file: File): ShareableContent? {
val mimeTypeString = when (file.extension) {
"jpg", "jpeg" -> "image/jpeg"
"png" -> "image/png"
"mp4" -> "video/mp4" // add whichever other video extensions that you want to support
else -> return null
}
val uri = when (mimeTypeString.startsWith("image")) {
true -> insertImageToMediaStore(
file,
"Pictures/Your Image Subdirectory",
mimeTypeString
)
else -> insertVideoToMediaStore(
file,
"Movies/Your Video Subdirectory",
mimeTypeString
)
}
uri?.let {
return ShareableContent(contentUri = uri, mimeType = mimeTypeString)
} ?: throw RuntimeException("Unable to insert to media store")
}
@SuppressLint("InlinedApi")
fun insertImageToMediaStore(file: File, relativePath: String, mimeType: String): Uri? {
val values = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, file.name)
put(MediaStore.Images.Media.MIME_TYPE, mimeType)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
put(MediaStore.MediaColumns.RELATIVE_PATH, relativePath)
put(MediaStore.MediaColumns.IS_PENDING, 1)
}
}
val collection = when (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
true -> MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL)
false -> MediaStore.Images.Media.EXTERNAL_CONTENT_URI
}
insertFileToMediaStore(contentResolver, collection, values, file)?.let {
return it
} ?: run {
return null
}
}
@SuppressLint("InlinedApi")
fun insertVideoToMediaStore(file: File, relativePath: String, mimeType: String): Uri? {
val values = ContentValues().apply {
put(MediaStore.Video.Media.DISPLAY_NAME, file.name)
put(MediaStore.Video.Media.MIME_TYPE, mimeType)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
put(MediaStore.MediaColumns.RELATIVE_PATH, relativePath)
put(MediaStore.MediaColumns.IS_PENDING, 1)
}
}
val collection = when (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
true -> MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL)
false -> MediaStore.Video.Media.EXTERNAL_CONTENT_URI
}
insertFileToMediaStore(contentResolver, collection, values, file)?.let {
return it
} ?: run {
return null
}
}
private fun insertFileToMediaStore(
contentResolver: ContentResolver,
collection: Uri,
values: ContentValues,
file: File
): Uri? {
val uri = contentResolver.insert(collection, values)
uri?.let {
contentResolver.openOutputStream(uri)?.use { outputStream ->
try {
outputStream.write(file.readBytes())
outputStream.close()
} catch (e: Exception) {
e.printStackTrace()
}
}
values.clear()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
values.put(MediaStore.Images.Media.IS_PENDING, 0)
contentResolver.update(uri, values, null, null)
}
} ?: throw RuntimeException("Unable to write file to MediaStore")
return uri
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment