Scoped Storage Tutorial for Android 11: Deep Dive |

Scoped storage is mandatory for all apps targeting Android 11. In this tutorial, you’ll learn how to implement the latest storage APIs in Android 11 by adding features to a meme-generating app.

This is a companion discussion topic for the original entry at

Well, I may be too late to comment on an article that is 2 years old, but it does not work on my old phone running Marshmallow.
I am testing the starter project.

E/AndroidRuntime: FATAL EXCEPTION: main
    Process:, PID: 2827
    android.database.sqlite.SQLiteException: no such column: relative_path (Sqlite code 1): , while compiling: SELECT _id, relative_path, _display_name, _size, mime_type, width, height, date_modified FROM images ORDER BY date_modified DESC, (OS error - 22:Invalid argument)
        at android.database.DatabaseUtils.readExceptionFromParcel(
        at android.database.DatabaseUtils.readExceptionFromParcel(
        at android.content.ContentProviderProxy.query(
        at android.content.ContentResolver.query(
        at android.content.ContentResolver.query(
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$

Hello dttt,

It’s never too late! :] That happened, because RELATIVE_PATH is from a newer version of Android, and the images table on the database on Marshmallow doesn’t have that column. My suggestion is to just add a verification like this one:

fun hasAndroid11OrNewer(): Boolean {

To decide when to use RELATIVE_PATH.