Android Проблема с магазином мультимедиа: вставка нового списка воспроизведения возвращает нулевой URI - PullRequest
0 голосов
/ 11 января 2020

Я реализовал метод для создания списка воспроизведения в Media Store, используя метод ниже:

public static long createPlaylist(ContentResolver resolver, String name) {
    ContentValues values = new ContentValues(1);
    values.put(MediaStore.Audio.Playlists.NAME, name);
    Uri uri = resolver.insert(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, values);
    if (uri == null) {
        throw new Exception(
            "Failed to insert playlist: " + values);
    }

    String idString = uri.getLastPathSegment();
    if (idString == null) {
         throw new Exception(
              "Failed to parse uri last segment: " + uri);
    }

    return Long.parseLong(idString);
}

Метод возвращает идентификатор недавно созданного списка воспроизведения. Он отлично работает на всех устройствах, кроме Nokia 3.1 Android 9. Не удается вернуть нулевой URI при вставке значений в распознаватель контента.

Я также пытался вставить значения, как показано в коде ниже:

ContentValues values = new ContentValues(3);
values.put(MediaStore.Audio.Playlists.NAME, name);
values.put(MediaStore.Audio.Playlists.DATE_ADDED, now);
values.put(MediaStore.Audio.Playlists.DATE_MODIFIED, now);

В чем может быть причина этого? Я думал, что это должно работать одинаково на всех устройствах из-за общей реализации Media Store в рамках.

Спасибо за любую помощь заранее.

Ответы [ 2 ]

0 голосов
/ 22 апреля 2020

Посмотрите логи logcat. Метод insert регистрирует, почему он возвратил ноль. Например, у меня возникла та же проблема, и она позволила мне найти причину:

SQLiteDatabase(26594): android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: files._data (code 2067 SQLITE_CONSTRAINT_UNIQUE)

Так что в моем случае я пытался сохранить файл с именем, которое уже существовало.


РЕДАКТИРОВАТЬ:

Больше точности по моей проблеме:

Я создавал имя файла "hello.png" с resolver.insert(...), как вы. Обычно, если файл с таким именем уже существует в файловой системе, новый файл автоматически переименовывается в «hello (x) .png»

Затем для целей тестирования мне пришлось удалить этот файл с помощью adb, используя adb shell rm -rf <myFolder>. Но это была моя ошибка.

Начиная с Android 10, вы должны использовать ContentResolver и Media Store, который является базой данных, отслеживающей файлы, сохраненные приложением. rm -rf не обновляет эту базу данных, поэтому для файловой системы файл с именем hello.png не существовал (тогда файл не переименовывается в hello (1).png). Но в базе данных была запись о том, что такой файл существует, отсюда исключение SQLiteConstraintException.

Вкл. Android 10+, чтобы удалить файл, созданный приложением , вы должны использовать

adb shell content delete <args>

adb shell content, позволяющие вам делать SQL подобные запросы к базе данных ContentResolver. Например:

adb shell content query --uri content://media/external/images/media

создает список всех внешних изображений. Затем вы можете создать правильный запрос для удаления нужного файла (ов).

В моем случае это было:

adb shell content delete --uri content://media/external/images/media --where bucket_display_name="\'HelloCollection\'"

Эта команда как удалит запись в базе данных, так и удалит файл в файловой системе.

0 голосов
/ 12 января 2020

Не уверен, почему вы хотите получить значение для URI. Мой метод вставки работает без сбоев, даже на android 10. Он в основном такой же, как ваш пример (хотя вставка в плейлисты приводит к ошибке разрешения доступа к файлу в Android 10)

    public void createnewPlaylist(Context context, String newplaylist) {
    if (newplaylist != null && context != null) {

        ContentResolver resolver = context.getContentResolver();
        ContentValues values = new ContentValues(1);
        values.put(MediaStore.Audio.Playlists.NAME, newplaylist);
        try {
            resolver.insert(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, values);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
...