WRITE SD CARD
Published: 2023-09-03 09:09:18

Welcome

I have this function to save image external storege.  But only save to internal. How to fix this?


fun saveBitmapToExternal(context: Context,
                             bitmap: Bitmap,
                             fileName: String,
                             extension: String = "image/jpeg",
                             compressFormat: Bitmap.CompressFormat = Bitmap.CompressFormat.JPEG,
                             qualityCompress: Int = 100) {

        val date = System.currentTimeMillis()
        var bitmapSave: Boolean

        if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q ) {
            val collection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
            val dirDest = Environment.DIRECTORY_DCIM + "/jphoto"
            val directory = File(dirDest)
            if ( !directory.exists() ) {
                directory.mkdirs()
            }

            val newImage = ContentValues().apply {
                put(MediaStore.Images.Media.DISPLAY_NAME, fileName)
                put(MediaStore.MediaColumns.MIME_TYPE, extension)
                put(MediaStore.MediaColumns.DATE_ADDED, date)
                put(MediaStore.MediaColumns.DATE_MODIFIED, date)
                put(MediaStore.MediaColumns.SIZE, bitmap.byteCount)
                put(MediaStore.MediaColumns.WIDTH, bitmap.width)
                put(MediaStore.MediaColumns.HEIGHT, bitmap.height)
                put(MediaStore.MediaColumns.RELATIVE_PATH, dirDest)
                put(MediaStore.Images.Media.IS_PENDING, 1)
            }

            val newImageUri = context.contentResolver.insert(collection, newImage)

            context.contentResolver.openOutputStream(newImageUri!!, "w").use {
                bitmapSave = bitmap.compress(compressFormat, qualityCompress, it!!)
            }

            if ( bitmapSave ) {
                showSnackBar(resources.getString(R.string.photo_done), fontTextSize, Snackbar.LENGTH_SHORT, numberRow = 2)

                newImage.clear()

                newImage.put(MediaStore.Images.Media.IS_PENDING, 0)

                context.contentResolver.update(newImageUri, newImage, null, null)
            } else {
                context.contentResolver.delete(newImageUri, null, null)

showSnackBar(resources.getString(R.string.photo_add_error), fontTextSize, Snackbar.LENGTH_SHORT, numberRow = 2)
            }
        } else {
            val directory = File(Environment.getExternalStorageDirectory().toString() + "/DCIM/jphoto")
            if ( !directory.exists() ) {
                directory.mkdirs()
            }

            val file = File(directory, fileName)
            val save = saveImageToStream03(bitmap, FileOutputStream(file), compressFormat, qualityCompress)

            if ( save ) {
                val values = ContentValues().apply {
                    put(MediaStore.Images.Media.DISPLAY_NAME, fileName)
                    put(MediaStore.MediaColumns.MIME_TYPE, extension)
                    put(MediaStore.MediaColumns.DATE_ADDED, date)
                    put(MediaStore.MediaColumns.DATE_MODIFIED, date)
                    put(MediaStore.MediaColumns.SIZE, bitmap.byteCount)
                    put(MediaStore.MediaColumns.WIDTH, bitmap.width)
                    put(MediaStore.MediaColumns.HEIGHT, bitmap.height)
                    put(MediaStore.Images.Media.DATA, file.absolutePath)
                }
                // .DATA is deprecated in API 29

context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)

                showSnackBar(resources.getString(R.string.photo_done), fontTextSize, Snackbar.LENGTH_SHORT, numberRow = 2)
            } else {
                if ( file.exists() ) {
                    file.delete()
                }


showSnackBar(resources.getString(R.string.photo_add_error), fontTextSize, Snackbar.LENGTH_SHORT, numberRow = 2)
            }
        }
    }

    private fun saveImageToStream03(
        bitmap: Bitmap,
        outputStream: OutputStream?,
        compressFormat: Bitmap.CompressFormat = Bitmap.CompressFormat.JPEG,
        qualityCompress: Int = 100
    ) : Boolean {
        var bitmapSave = false

        if ( outputStream != null ) {
            try {
                bitmapSave = bitmap.compress(compressFormat, qualityCompress, outputStream)

                outputStream.close()
            } catch ( _ : Exception ) {
            }
        }

        //outputStream.
        return bitmapSave
    }