This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // converts any uri(content/file) to a local temp file first in cache directory for easy read/write | |
| suspend fun Uri.toLocalFile(context: Context,localFileLocation:File = context.cacheDir): File? { | |
| val uri = this | |
| return withContext(Dispatchers.IO) { | |
| try { | |
| val fileInfo = FileInfo.fromSAFUri(context,uri) | |
| val fileName = fileInfo?.nameWithExtension?: "${System.currentTimeMillis()}.bin" | |
| val tempFile = File(localFileLocation, fileName) | |
| context.contentResolver.openInputStream(uri)?.use { inputStream -> | |
| FileOutputStream(tempFile).use { outputStream -> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| data class FileInfo( | |
| val nameWithExtension: String, | |
| val extension: String?, | |
| val mimeType: String?, | |
| val size: Long?, | |
| val sizeFormatted: String?, | |
| val createdOn: Long?, | |
| val modifiedOn: Long?, | |
| val originalLocationPath: String? | |
| ){ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| state = state.copy(fileToBeSaved = state.mediaFile) // state.copy(bitmapToBeSaved = getCurrentImageViewBitmap()) | |
| saveFileToSystemSAF.launch("MyFile.pdf") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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() | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @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 | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @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" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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) | |
| } |