Я бы порекомендовал не хранить аудиоданные в базе данных. Упомянутые ранее проблемы с памятью могут привести к огромным перебоям в работе ГХ, что может сделать систему нереагирующей в течение нескольких секунд или более.
Типичный подход включает несколько шагов.
Сохраните аудио в файле где-нибудь в каталоге вашего приложения.
Создайте два столбца в вашей базе данных. Один столбец (называемый как угодно) содержит URL «content: //», который ссылается на данные. Просмотр URL-адреса «content: //» - это триггер для системы, который затем просматривает содержимое столбца «_data» в той же строке. Содержимое этого столбца должно содержать полный путь к файлу.
Затем система прозрачно читает этот файл и представляет его любому коду, который фактически запросил содержимое.
У меня есть пример кода для выполнения этого с изображениями - очевидно, это не совсем то же самое, но я могу пройтись по нему здесь, и вы должны понять суть.
Конкретная проблема, которую я пытался решить, - это сохранение обложки альбома для дорожки, хранящейся на устройстве. Я хотел, чтобы можно было отображать обложку альбома в виде списка и кэшировать его локально на устройстве, чтобы многократная прокрутка выполнялась быстро и требовала многократных сетевых загрузок для одних и тех же данных.
У меня есть база данных альбомов с различными столбцами, которые лениво заполняются с удаленного сервера. Я реализую эту базу данных с использованием инфраструктуры ContentProvider. В http://developer.android.com/guide/topics/providers/content-providers.html, есть много полезной информации о ContentProviders, и вам следует сначала прочитать ее, чтобы остальное имело смысл.
Используются следующие файлы (примечание: я связался с определенными точками в дереве, потому что эта работа еще не завершена, и я хочу, чтобы ссылки на номера строк, которые я вам предоставляю, были стабильными):
https://github.com/nikclayton/android-squeezer/blob/02c08ace43f775412cc9715bf55aeb83e7b5f2dc/src/com/danga/squeezer/service/AlbumCache.java
Этот класс определяет различные константы, которые используются в других местах, и довольно идиоматичен для всего, что реализовано как ContentProvider.
В этом классе COL_ARTWORK_PATH - это столбец, который будет содержать содержимое: // URL.
https://github.com/nikclayton/android-squeezer/blob/02c08ace43f775412cc9715bf55aeb83e7b5f2dc/src/com/danga/squeezer/service/AlbumCacheProvider.java
Это реализация ContentProvider. Опять же, это довольно идиоматично для ContentProviders, которые обертывают базы данных SQLite. Некоторые интересные места:
429: albumListCallback ()
Этот код вызывается всякий раз, когда приложение получает данные об альбоме с удаленного сервера (это относится к моему приложению и не относится к вашей проблеме). К этому моменту данные были упакованы в список SqueezerAlbums, поэтому этот код должен распаковать эти данные и передать их в строки в базе данных.
456: здесь мы вызываем updateAlbumArt с достаточным количеством данных, чтобы он мог выполнить удаленную выборку обложки альбома (и я только что понял, глядя на этот код, что могу сделать это более эффективным, поскольку он обновляет базу данных чаще, чем она должен. Но я отвлекся).
475: updateAlbumArt ()
Для этого необходимо извлечь удаленный образ, изменить его размер, сохранить как исходную, так и измененную версию в файловой системе (почему оба? Поскольку я еще не закончил, и будет код для выбора правильного кэшированного размера позже).
При необходимости создается каталог кеша, загружается удаленный образ, изменяется его размер и сохраняется в файлы.
535: Это бит, который вам, вероятно, особенно интересен. При этом создается URL-адрес content: // (с использованием констант в AlbumCache.java), который ссылается на данные, и помещает его в COL_ARTWORK_PATH. Затем он устанавливает абсолютный путь к файлу в столбце _data.
571: openFile ()
Вы должны реализовать это. Пользователи ContentProvider будут вызывать openFile (), когда они хотят открыть файл в базе данных. Эта реализация использует openFileHelper (), который представляет собой код, который ищет значение в столбце _data, открывает этот файл и возвращает вызывающему ParcelFileDescriptor.
Как вы, возможно, только что поняли, ваша открытая реализация openFile () не должна этого делать - вы можете использовать другое имя столбца или, возможно, у вас есть способ перейти прямо от URL-адреса к файлу вфайловая система.Это, кажется, очень распространенная идиома.
Предполагая, что вы сделали что-то подобное, и теперь у вас есть ContentProvider для вашей базы данных, чтобы фактически получить доступ к изображению, ваше приложение должно будет сгенерировать URIкоторый ссылается на данный фрагмент контента по его идентификатору.Код в приложении для открытия файла выглядит следующим образом:
Inputstream f = this.getContentResolver().openInputStream(theUri);
, который в конечном итоге вызывает вашу реализацию openFile (), которая в итоге вызывает openFileHelper (), который в итоге попадает в нужный файл вфайловая система.Еще одно преимущество этого подхода заключается в том, что openFile () вызывается в домене безопасности вашего приложения, поэтому он может получить доступ к файлу, и, при правильной реализации, ваш ContentProvider может вызываться совершенно разными приложениями, если вы создаете URL-адреса, на которые он отвечаетобщеизвестно.