0

Our Android application relies heavily on queries on the ContentResolver to get and manage photos and videos stored on the device. We are aware of the obvious changes in Android Q regarding the DATA fields and the scoped storage. However, we experience some weird issues on our Pixel 2 for queries, that use more complex expressions in the SQL projection. For example we do something like this:

final String[] projection = {MediaStore.MediaColumns._ID,
                                     MediaStore.MediaColumns.DATA,
                                     MediaStore.MediaColumns.MIME_TYPE,
                                     getDateColumn(target, sortMode),
                                     MediaStore.MediaColumns.TITLE,
                                     "rtrim(" + MediaStore.MediaColumns.DATA + ", replace(" +
                                     MediaStore.MediaColumns.DATA + ", '/', '')) as " + COLUMN_DIRECTORY,
                                     "substr(" + MediaStore.MediaColumns.DATA + ", " + "length(rtrim(" +
                                     MediaStore.MediaColumns.DATA + ", replace(" + MediaStore.MediaColumns.DATA +
                                     ", '/', '')) )" + ")" + "as " + COLUMN_FILENAME,
                                     MediaStore.MediaColumns.DISPLAY_NAME,
                                     MediaStore.MediaColumns.DATE_ADDED};

Which used to work absolutely fine up until now. On the latest Android Q version however, we get the following exception for every query that uses projections that are not the pure column names:

2019-09-26 15:54:56.733 30276-30659/? E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #4
    Process: xxxx, PID: 30276
    java.lang.RuntimeException: An error occurred while executing doInBackground()
        at android.os.AsyncTask$4.done(AsyncTask.java:399)
        at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
        at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
        at java.util.concurrent.FutureTask.run(FutureTask.java:271)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:919)
     Caused by: java.lang.IllegalArgumentException: Invalid column rtrim(_data, replace(_data, '/', '')) as directory
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:170)
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:140)
        at android.content.ContentProviderProxy.query(ContentProviderNative.java:423)
        at android.content.ContentResolver.query(ContentResolver.java:944)
        at android.content.ContentResolver.query(ContentResolver.java:880)
        at android.content.ContentResolver.query(ContentResolver.java:836)
        ...

Are these kind of projections forbidden now? Or are we missing something? Thanks in advance!

mAx
  • 546
  • 1
  • 6
  • 17
  • 2
    "Are these kind of projections forbidden now?" -- hopefully. They were never going to be reliable, as you are making assumptions both about how the `ContentProvider` is interpreting the query and how the underlying data is stored. "We are aware of the obvious changes in Android Q regarding the DATA fields and the scoped storage" -- you are referencing the `DATA` column in several places in the query that is failing. – CommonsWare Sep 26 '19 at 21:57
  • @CommonsWare sure, replacing the DATA access is something we need to take care of in the coming weeks. But currently accessing it is not an issue though on our Android 10 device, most likely because of the android:requestLegacyExternalStorage="true" flag?! Anyways, thanks for the hint regarding the unreliable porjections. Seems we need to find another solution for that now. – mAx Sep 27 '19 at 10:18

1 Answers1

0

you can't access anymore to DATA column

greywolf82
  • 21,813
  • 18
  • 54
  • 108
  • 1
    this does not seem to be the cause in this case. If we compile against sdk < 29 or set the flag android:requestLegacyExternalStorage="true" we still cann acess DATA on Android 10 devices. – mAx Sep 27 '19 at 10:21
  • obviously, because in Android 10 your app by default uses scoped storage, unless you use the legacy access, I repeat that you can't access DATA column – greywolf82 Sep 27 '19 at 10:27
  • like I said: we can (because of the flag) and thats not the issue right here. The same error occurs when we use similar projections to get only date_taken for example. – mAx Sep 27 '19 at 10:57
  • Your answer is incorrect. The `DATA` column is deprecated, it does not mean that you can not access it anymore. – ClassA May 03 '20 at 15:04