Я также в настоящее время борюсь с этим.
Я думаю, что вы хотите сделать, вы не можете больше делать, когда вы находитесь на Android Q, потому что у вас нет доступаМузыкальный каталог на Q .Вам разрешено создавать файлы и обращаться к ним только в тех каталогах, которые вы создали.Вы не создали музыкальный каталог.
Теперь каждое изменение в Media должно произойти, бросил MediaStore.Таким образом, вы заранее вставляете свой музыкальный файл, а затем получаете выходной поток из MediaStore для записи в него.Все изменения в Q on Media должны быть сделаны через MediaStore, поэтому вы информируете MediaStore об изменениях, которые больше не могут произойти, потому что вы никогда не получаете прямой доступ к файлу.
У этого есть один гигантский кавиат в том, что все новые возможности в MediaStore, которые делают это возможным, не существуют в более старых версиях Android.Поэтому в настоящее время я верю, что вам нужно будет реализовать все дважды, к сожалению.По крайней мере, если вы хотите активно влиять на то, куда ваша музыка сохраняется в этом месте.
Эти два столбца MediaStore являются новыми в Q и не существуют до Q, ведь вам, вероятно, придется использовать в Q
MediaStore.Audio.Media.RELATIVE_PATH
с этим вы можете влиять на путь, где он сохраняется.Поэтому я поместил туда «Music / MyAppName / MyLibraryName», и это в конечном итоге приведет к сохранению «song.mp3» в «Music / MyAppName / MyLibraryName / song.mp3» MediaStore.Audio.Media.IS_PENDING
. Для этого следует установить значение 1в то время как песня все еще пишется, а затем вы можете обновить ее до 0.
Я также теперь начал реализовывать вещи дважды с проверками версий Android.Это раздражает.Я не хочу это делать.Но, похоже, это единственный способ.
Я просто добавлю немного кода о том, как мне удалось вставить музыку на Android.Q и ниже.Это не идеально.Я должен указать тип MIME для Q, потому что флаки теперь каким-то образом станут .flac.mp3, потому что, похоже, он этого не понимает.
Итак, в любом случае это часть, которую я уже обновил доработать с Q и раньше, он загружает музыкальный файл с музыкального проигрывателя на моем NAS.Приложение написано на kotlin, но я не уверен, что это для вас проблема.
override fun execute(library : Library, remoteApi: RemoteApi, ctx: Context) : Boolean {
var success = false
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val values = ContentValues().apply {
put(MediaStore.Audio.Media.RELATIVE_PATH, library.rootFolderRelativePath)
put(MediaStore.Audio.Media.DISPLAY_NAME, remoteLibraryEntry.getFilename())
put(MediaStore.Audio.Media.IS_PENDING, 1)
}
val collection = MediaStore.Audio.Media
.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val uri = ctx.contentResolver.insert(collection, values)
ctx.contentResolver.openOutputStream(uri!!).use {
success = remoteApi.downloadMusic(remoteLibraryEntry, it!!)
}
if(success) {
values.clear()
val songId = JDrop.mediaHelper.getSongId(uri)
JDrop.db.music.insert(Music(mediaStoreId = songId, remoteId = remoteLibraryEntry.remoteId, libraryId = library.id))
values.put(MediaStore.Audio.Media.IS_PENDING, 0)
ctx.contentResolver.update(uri, values, null, null)
} else {
ctx.contentResolver.delete(uri, null, null)
}
} else {
val file = File("${library.rootFolderPublicDirectory}/${remoteLibraryEntry.getFilename()}")
if(file.exists()) file.delete()
success = remoteApi.downloadMusic(remoteLibraryEntry, file.outputStream())
if (success) {
MediaScannerConnection.scanFile(ctx, arrayOf(file.path), arrayOf("audio/*")) { _, uri ->
val songId = JDrop.mediaHelper.getSongId(uri)
JDrop.db.music.insert(Music(mediaStoreId = songId, remoteId = remoteLibraryEntry.remoteId, libraryId = library.id))
}
}
}
return success
}
И здесь используется метод MediaStoreHelper
fun getSongId(uri : Uri) : Long {
val cursor = resolver.query(uri, arrayOf(Media._ID), null, null, null)
return if(cursor != null && cursor.moveToNext()) {
val idIndex = cursor.getColumnIndex(Media._ID)
val id = cursor.getLong(idIndex)
cursor.close()
id
} else {
cursor?.close()
-1
}
}
Одна вещь, когда вы не указываете MIMEтип, кажется, предполагает, что mp3 является MIME-типом.Таким образом, файлы .flac будут сохранены как name.flac.mp3, потому что он добавляет тип файла mp3, если его нет, и думает, что это mp3.Он не добавляет еще один .mp3 для mp3 файлов.В настоящее время у меня нигде нет MIME-типа ... так что я собираюсь сделать это сейчас, я думаю.
Есть также полезный рассказ о вводе-выводе в Google о распределенной / общей памяти https://youtu.be/3EtBw5s9iRY
Это, вероятно, не ответит на все ваши вопросы.Это достаточно точно не для меня.Но было полезно начать с приблизительного представления о том, что они даже изменили для начала.
Для удаления и обновления файлов то же самое в Q, если вы вызываете delete в записи медиастора,файл будет удален.Прежде, Q, вы должны также вручную удалить файл.Но если вы сделаете это на Q, ваше приложение упадет.Итак, снова вы должны проверить, есть ли у вас Q или более старая версия Android, и предпринять соответствующие действия.