Ошибка недопустимого столбца ContentResolver в Android Q (SDK 29)

Наше приложение для Android в значительной степени полагается на запросы ContentResolver для получения и управления фотографиями и видео, хранящимися на устройстве. Нам известны очевидные изменения в Android Q, касающиеся полей DATA и хранилища с ограниченным доступом. Однако мы испытываем некоторые странные проблемы с нашим Pixel 2 для запросов, которые используют более сложные выражения в проекции SQL. Например, делаем что-то вроде этого:

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};

Которая до сих пор работала абсолютно нормально. Однако в последней версии Android Q мы получаем следующее исключение для каждого запроса, который использует проекции, которые не являются чистыми именами столбцов:

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)
        ...

Запрещены ли сейчас подобные проекции? Или мы что-то упускаем? Заранее спасибо!


person mAx    schedule 26.09.2019    source источник
comment
Запрещены ли сейчас подобные проекции? -- с надеждой. Они никогда не будут надежными, поскольку вы делаете предположения как о том, как ContentProvider интерпретирует запрос, так и о том, как хранятся базовые данные. Нам известны очевидные изменения в Android Q в отношении полей DATA и хранилища с ограниченным объемом - вы ссылаетесь на столбец DATA в нескольких местах в запросе, который завершился ошибкой.   -  person CommonsWare    schedule 27.09.2019
comment
@CommonsWare уверен, что замена доступа к данным - это то, о чем нам нужно позаботиться в ближайшие недели. Но в настоящее время доступ к нему не является проблемой на нашем устройстве Android 10, скорее всего, из-за флага android: requestLegacyExternalStorage = true ?! В любом случае, спасибо за подсказку относительно ненадежных порций. Похоже, сейчас нам нужно найти другое решение для этого.   -  person mAx    schedule 27.09.2019


Ответы (1)


у вас больше нет доступа к DATA столбцу

person greywolf82    schedule 26.09.2019
comment
в данном случае это не кажется причиной. Если мы скомпилируем sdk ‹29 или установим флаг android: requestLegacyExternalStorage = true, мы все равно не сможем получить доступ к ДАННЫМ на устройствах Android 10. - person mAx; 27.09.2019
comment
очевидно, потому что в Android 10 ваше приложение по умолчанию использует ограниченное хранилище, если вы не используете устаревший доступ, я повторяю, что вы не можете получить доступ к столбцу DATA - person greywolf82; 27.09.2019
comment
как я уже сказал: мы можем (из-за флага), и проблема не в этом. Та же ошибка возникает, когда мы используем аналогичные прогнозы, например, для получения только date_taken. - person mAx; 27.09.2019
comment
Ваш ответ неверен. Столбец DATA устарел, это не означает, что вы больше не можете получить к нему доступ. - person ClassA; 03.05.2020