Skip to content

Instantly share code, notes, and snippets.

View root-ansh's full-sized avatar
🔍
curiously exploring problems and their solutions

Ansh Sachdeva root-ansh

🔍
curiously exploring problems and their solutions
View GitHub Profile
@root-ansh
root-ansh / TestContent.kt
Created September 21, 2025 07:50
AnimatedContent
@HiltViewModel
class TestViewModel @Inject constructor(
): ViewModel(){
data class Entry(val value: String, val id: Long)
data class MyScreenState(val list:List<Entry> = listOf())
sealed interface MyScreenIntent{ data object StartEmission: MyScreenIntent }
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
fun Context.openSystemViewerForSAFUri(uri: Uri?) {
uri?:return
val mimeType1 = FileInfo.fromSAFUri(this,uri)?.mimeType
val extension = MimeTypeMap.getFileExtensionFromUrl(uri.toString())
val mimeType2 = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.lowercase())
val mimeType3 = "*/*"
val intent = Intent(Intent.ACTION_VIEW).apply {
setDataAndType(uri, mimeType1?:mimeType2?:mimeType3)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
@Throws
suspend fun Context.saveFileToUserMemory(
sourceFile: File,
targetDirectory: String = Environment.DIRECTORY_DOWNLOADS
): Uri {
return withContext(Dispatchers.IO){
if (!sourceFile.exists()) error("Source file does not exist")
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.Q) error("Saving to public directories is only supported on Android Q and above")
val extension = sourceFile.extension.lowercase()
val mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) ?: "application/octet-stream"
@Throws
suspend fun Context.saveFileToUserSelectedPath(uri: Uri, sourceFile: File): Uri {
return withContext(Dispatchers.IO) {
contentResolver.openOutputStream(uri)?.use { outputStream ->
sourceFile.inputStream().use { inputStream ->
inputStream.copyTo(outputStream)
}
}
uri
}
fun File.imageFileToBitmap(): Bitmap? { // wont work for content uri files. first create to local file
val localNonSAFFile = this
return if (localNonSAFFile.exists()) {
BitmapFactory.decodeFile(localNonSAFFile.absolutePath)
} else {
null
}
}
private fun getCurrentImageViewBitmap(): Bitmap{
val drawable = binding.imagePreviewPlaceholder.drawable
val bitmap = if (drawable is BitmapDrawable) {
drawable.bitmap
} else {
val bitmap = createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight)
val canvas = Canvas(bitmap)
drawable.setBounds(0, 0, canvas.width, canvas.height)
drawable.draw(canvas)
bitmap
lifecycleScope.launch {
val uri = context.saveBitmapToUserMemory(getCurrentImageViewBitmap())
val uri = context.saveFileToUserMemory(file)
Snackbar
.make(binding.root,"Saved file :currentlyVisibleImage to downloads", Snackbar.LENGTH_SHORT)
.setAction("show"){context.openSystemViewerForSAFUri(uri)} //check next section for info on this
.show()
}
state = state.copy(fileToBeSaved = state.mediaFile) // state.copy(bitmapToBeSaved = getCurrentImageViewBitmap())
saveFileToSystemSAF.launch("MyFile.pdf")
private val saveFileToSystemSAF: ActivityResultLauncher<String> = registerForActivityResult(CreateDocument(mimeType = "*/*")) { result -> // or mimeType = "application/pdf" / "image/*"
val uri = result
val file = state.fileToBeSaved // the file/bitmap that needs to be writteen to user selected uri
val context = this
if (uri!=null && file!=null){
lifecycleScope.launch {
context.saveFileToUserSelectedPath(uri,file) // writing file to user selected uri
Snackbar
.make(binding.root,"Saved file :${file.name} to user selected directory", Snackbar.LENGTH_SHORT)
.setAction("show"){context.openSystemViewerForSAFUri(uri)} //check next section for info on this