free geoip
34

Kotlin App Not Saving Image to Gallery Fix

When developing an Android application using Kotlin, many developers face a common issue: the app does not save images to…

When developing an Android application using Kotlin, many developers face a common issue: the app does not save images to the device gallery. This problem can occur due to missing permissions, incorrect file paths, or changes in Android storage policies (especially from Android 10 and above with Scoped Storage).

In this article, we will go through step-by-step solutions on how to fix the issue of Kotlin app not saving image to gallery. We will provide a complete example with source code and explain how to properly request permissions, save images, and make them visible in the gallery.

Kotlin App Not Saving Image to Gallery

1. Why Images Don’t Appear in Gallery

There are several reasons why your image might not show up in the gallery:

  • Missing Storage Permission: On Android 9 and below, WRITE_EXTERNAL_STORAGE is required.
  • Scoped Storage: Starting from Android 10, apps must use MediaStore API instead of directly writing to external storage.
  • No Media Scanner Update: The gallery app relies on the system media scanner. If the image is not scanned, it won’t appear.
  • Wrong File Path: Saving to a non-public directory prevents gallery apps from detecting the file.

2. Request Necessary Permissions

Before saving an image, you must ensure the app has the correct permissions. Add this to your AndroidManifest.xml:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="28"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

Note: From Android 10 (API 29), WRITE_EXTERNAL_STORAGE is deprecated. You should use the MediaStore API.

3. Kotlin Example: Saving Image to Gallery

The following Kotlin code snippet shows how to save a Bitmap image to the gallery properly:

fun saveImageToGallery(context: Context, bitmap: Bitmap, title: String) {
    val filename = "$title.jpg"
    val fos: OutputStream?

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        val resolver = context.contentResolver
        val contentValues = ContentValues().apply {
            put(MediaStore.MediaColumns.DISPLAY_NAME, filename)
            put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
            put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
        }

        val imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
        fos = imageUri?.let { resolver.openOutputStream(it) }
    } else {
        val imagesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
        val image = File(imagesDir, filename)
        fos = FileOutputStream(image)

        // Inform Media Scanner about the new file
        context.sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(image)))
    }

    fos?.use {
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, it)
    }
}

This function automatically detects whether the device is running Android Q (10) or higher and uses MediaStore. On older devices, it writes directly to external storage and triggers a media scan broadcast.

4. Example Use Case

Let’s say you want to save an image captured from the camera or generated in your app. Here’s a complete example inside an Activity:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val bitmap = BitmapFactory.decodeResource(resources, R.drawable.sample_image)

        val saveButton = findViewById<Button>(R.id.saveButton)
        saveButton.setOnClickListener {
            saveImageToGallery(this, bitmap, "MySavedImage")
            Toast.makeText(this, "Image Saved to Gallery", Toast.LENGTH_SHORT).show()
        }
    }
}

After running this code, the image should appear in the gallery. If it does not, make sure you:

  • Granted the necessary storage permissions (on devices < Android 10).
  • Use MediaStore API for Android 10 and above.
  • Check device storage settings and gallery refresh.

5. Comparison: Direct File Save vs MediaStore API

The following table compares the old method (direct save) with the modern method (MediaStore):

MethodSupported Android VersionProsCons
Direct File SaveAndroid 9 and belowSimple, direct access to external storageDeprecated, requires extra permissions, not working on Android 10+
MediaStore APIAndroid 10 and aboveSecure, no WRITE_EXTERNAL_STORAGE permission neededMore complex implementation

6. Common Mistakes and Fixes

  • Forgetting Media Scanner: Without scanning, gallery won’t update. Always use MediaStore insert or Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.
  • Wrong File Format: Make sure you save as JPG or PNG with correct MIME type.
  • Saving to Private Directory: Images saved in app private folder won’t be visible in gallery.

7. Conclusion

If your Kotlin app is not saving images to the gallery, the issue is usually related to permissions or incorrect storage API usage. By following the code above and using the MediaStore API for Android 10+, you can ensure images are correctly saved and visible in the gallery across all devices.

This guide provided both code snippets and troubleshooting tips to help you resolve the issue permanently. Whether you are building a camera app, photo editor, or social media application, applying these practices will guarantee smooth saving of images to the user’s gallery.

rysasahrial

Leave a Reply

Your email address will not be published. Required fields are marked *