Scoped Storage Tutorial for Android 11: Deep Dive | raywenderlich.com

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 https://www.raywenderlich.com/10768834-scoped-storage-tutorial-for-android-11-deep-dive

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: com.raywenderlich.android.lememeify, 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(DatabaseUtils.java:179)
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
        at android.content.ContentProviderProxy.query(ContentProviderNative.java:421)
        at android.content.ContentResolver.query(ContentResolver.java:502)
        at android.content.ContentResolver.query(ContentResolver.java:438)
        at com.raywenderlich.android.lememeify.FileOperations$queryImagesOnDevice$2.invokeSuspend(FileOperations.kt:77)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
        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$Worker.run(CoroutineScheduler.kt:665)

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 {
  return Build.VERSION.CODENAME >= ANDROID_R
}

To decide when to use RELATIVE_PATH.

Best,
Carlos