Сохранение аудиофайла с помощью API Mediastore вызывает исключение RemoteException в API 28-

#android #audio #mediastore

#Android #Аудио #mediastore

Вопрос:

Я не нашел никакой официальной документации, объясняющей, как сохранить аудиофайл на внешнем хранилище с помощью MediaStore API. В API 29 все работает. В API 28 — я получаю эту ошибку:

 E/JavaBinder: *** Uncaught remote exception!  (Exceptions are not yet supported across processes.)
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
    at java.lang.String.substring(String.java:2036)
    at com.android.providers.media.MediaProvider.insertFile(MediaProvider.java:2188)
    at com.android.providers.media.MediaProvider.insertInternal(MediaProvider.java:2592)
    at com.android.providers.media.MediaProvider.insert(MediaProvider.java:1872)
    at android.content.ContentProvider$Transport.insert(ContentProvider.java:266)
    at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:152)
    at android.os.Binder.execTransact(Binder.java:731)
  

Это код, который я использую (когда я вызываю «вставить», я получаю нулевой Uri):

  //@RequiresApi(VERSION_CODES.Q)
@SuppressLint("InlinedApi")
private fun export(name: String, path: String) {
    val resolver = applicationContext.contentResolver
    val audioCollection =  if (VERSION.SDK_INT >= VERSION_CODES.Q) {
        MediaStore.Audio.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
    } else {
        MediaStore.Audio.Media.getContentUri(MediaStore.VOLUME_EXTERNAL)
    }

    val newAudioFileDetails = ContentValues().apply {
        put(MediaStore.Audio.Media.DISPLAY_NAME, name)
        put(MediaStore.Audio.Media.DATA, "data")
        put(MediaStore.Audio.Media.IS_PENDING, 1)
    }

    val recordingUri = resolver.insert(audioCollection, newAudioFileDetails)
    Log.d(TAG, "recording Uri: ${recordingUri.toString()}")
    recordingUri?.let { recordingUri ->
        resolver.openFileDescriptor(recordingUri, "w")?.use {
            val bytesCopied = File(path).inputStream().copyTo(FileOutputStream(it.fileDescriptor))
            Log.d("TAG", "bytes copied: $bytesCopied")
        }

        newAudioFileDetails.let {
            it.clear()
            it.put(MediaStore.Audio.Media.IS_PENDING, 0)
            resolver.update(recordingUri, it, null, null)
        }
    }
}
  

Редактировать
Я также пытался с этим, но при вставке я всегда получаю нулевой Uri:

 val newAudioFileDetails = ContentValues().apply {
        put(MediaStore.Audio.Media.DISPLAY_NAME, name)
        put(MediaStore.Audio.Media.IS_PENDING, 1)

        if (VERSION.SDK_INT < VERSION_CODES.Q) {
            val audioDir = File(Environment.getExternalStoragePublicDirectory(
                    Environment.DIRECTORY_MUSIC), "MyNewAlbumName")
            val audioPath = File(audioDir, "$name.mp3").absolutePath
            put(MediaStore.Audio.AudioColumns.DATA, audioPath)
        }
  

Комментарии:

1. У вас есть StringIndexOutOfBoundsException .

2. ......Media.DATA, "data" ? Что это должно быть? Вы должны указать путь.

3. какой путь я должен указать?

4. Исключение StringIndexOutOfBoundsException генерируется классом ContentResolver: я просто получаю в ответ нулевой Uri

5. Путь, по которому должен быть сохранен ваш файл. Полный путь к каталогу. Или полный путь к файлу. Попробуйте оба.