Skip to content

Instantly share code, notes, and snippets.

@StylianosGakis
Created August 29, 2023 07:48
Show Gist options
  • Save StylianosGakis/7dba7fc700240d6979b3a305902ea604 to your computer and use it in GitHub Desktop.
Save StylianosGakis/7dba7fc700240d6979b3a305902ea604 to your computer and use it in GitHub Desktop.
Snippet to snapping an image out of a composable and sharing it through a share sheet
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity
android:name="..."
android:exported="true"
android:label="..."
android:theme="...">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
</application>
</manifest>
import android.annotation.SuppressLint
import android.content.ClipData
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Picture
import android.net.Uri
import android.os.Environment
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.draw
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.core.content.FileProvider
import com.your.app.id.BuildConfig
import okio.buffer
import okio.sink
import java.io.File
@SuppressLint("NewApi")
@Composable
fun ShareComposable() {
val context = LocalContext.current
val picture: Picture = remember { Picture() }
Box(
modifier = Modifier
.fillMaxSize()
.drawWithCache {
val width = size.width.toInt()
val height = size.height.toInt()
onDrawWithContent {
val pictureCanvas = androidx.compose.ui.graphics.Canvas(picture.beginRecording(width, height))
draw(this, layoutDirection, pictureCanvas, size) {
this@onDrawWithContent.drawContent()
}
picture.endRecording()
drawIntoCanvas { canvas -> canvas.nativeCanvas.drawPicture(picture) }
}
},
contentAlignment = Alignment.Center,
) {
Column(verticalArrangement = Arrangement.spacedBy(16.dp), horizontalAlignment = Alignment.CenterHorizontally) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.height(64.dp)
.fillMaxWidth()
.padding(horizontal = 16.dp)
.background(Color(0xFFFBEDC5))
.border(1.dp, Color(0xFFFFBF00)),
) {
Text(text = "Some content", modifier = Modifier.padding(16.dp))
}
Button(
onClick = {
val photoFile: File = File(
/* parent = */ context.getExternalFilesDir(Environment.DIRECTORY_PICTURES),
/* child = */ "IMAGE_${System.currentTimeMillis()}.png",
)
val photoUri: Uri = FileProvider.getUriForFile(
/* context = */ context,
/* authority = */ "${BuildConfig.APPLICATION_ID}.provider",
/* file = */ photoFile,
)
val bitmap = Bitmap.createBitmap(picture) // Needs API 28+, not sure of alternatives
photoFile.sink().buffer().use { // From okio
bitmap.compress(Bitmap.CompressFormat.PNG, 100, it.outputStream()) // PNG or JPEG, not sure
}
val sendIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
setType("image/*")
putExtra(Intent.EXTRA_STREAM, photoUri)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
clipData = ClipData.newRawUri("image thumbnail", photoUri)
}
context.startActivity(Intent.createChooser(sendIntent, "From Compose UI!"))
},
) {
Text("Share composable")
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="share_pictures"
path="/" />
</paths>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment