2015-01-10 4 views
2

В настоящее время я пытаюсь сделать медиаплеер для аудио. В настоящее время я использую леденец. У меня возникла проблема с настройкой dataSource для медиаплеера. Во-первых, вот как я устанавливаю DataSource:Android - конвертировать URI в путь к файлу на lollipop

public void playSong() { 
    player.reset(); 
    Song selSong = songs.get(songPos); 
    long currSong = selSong.getId(); 
    //Get Uri of song 
    Uri trackUri = ContentUris.withAppendedId(
      MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, currSong); 
    try { 
     //Tell the player the song to play 
     player.setDataSource(getApplicationContext(), trackUri); 
    } catch (Exception e) { 
     Log.e("MUSIC SERVICE", "Error setting data source", e); 
     Log.d("URI Path", trackUri.toString()); 
    } 

    //Will prepare the song and call onPrepare of player 
    player.prepareAsync(); 
} 

И Uri выходит так:

content://media/external/audio/media/22

Я сделал некоторые исследования, и от моего понимания, после того, как Android 4.1, вы можете больше не используйте URI для источника данных. Когда я запускаю это приложение с кодом выше, я получаю эту ошибку:

E/MediaPlayer﹕ Unable to create media player 
E/MUSIC SERVICE﹕ Error setting data source 
    java.io.IOException: setDataSource failed.: status=0x80000000 
      at android.media.MediaPlayer.nativeSetDataSource(Native Method) 

Так что теперь мне нужно, чтобы преобразовать URI в путь к файлу и предусмотреть, что в качестве источника данных. И, после дополнительных исследований, кажется, что kitkat изменил способ предоставления URI, поэтому его трудно получить путь к файлу из URI. Тем не менее, я не уверен, что это изменение сохранилось в Android Lollipop 5.0.2.

По существу, у меня есть URI песни, но мне нужно предоставить что-то иное, чем URI для источника данных. Есть ли способ, которым я могу преобразовать URI на Lollipop, и, если нет, как я могу предоставить dataSource только знать идентификатор песни? Благодарю.

+1

«Я провел некоторое исследование и из своего понимания , после Android 4.1 вы больше не сможете использовать URI для dataSource "- цитата, пожалуйста. Во всяком случае, обратное верно - вы не можете предположить, что путь к файлу будет работать. «Когда я запустил это приложение с приведенным выше кодом, я получу эту ошибку» - если вы тестируете Android 4.4+, добавьте разрешение «READ_EXTERNAL_STORAGE». «похоже, что kitkat изменил способ предоставления URI, поэтому его трудно получить путь к файлу из URI» - нет требования, чтобы 'Uri' был файлом, не говоря уже о том, к которому вы можете получить доступ. – CommonsWare

+0

Конечно, я посмотрю, смогу ли найти, где я нашел это заявление. Я просто предположил, что это правильно, поскольку мой URI не работал. У меня есть разрешение READ_EXTERNAL_STORAGE, а также INTERNET. – user2082169

+0

Вот где я читаю, что URI не будет работать. Возможно, я неправильно понял. Он говорит, что на Android 4.1.1 вам нужно использовать локальный путь, если вы используете конструктор, который проходит в String. http://stackoverflow.com/questions/16395559/mediaplayer-setdatasource-failed-with-status-0x80000000-for-ringtone-set-by-file/22152628#22152628 – user2082169

ответ

0

Lollipop решил взять еще один курс с получением файлов из системы. (Некоторые говорят, что это от KitKat, но я еще не встречался с ним в KitKat). Приведенный ниже код, чтобы получить FilePath на леденец

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && isMediaDocument(uri)) 
    { 
     final String docId = DocumentsContract.getDocumentId(uri); 
     final String[] split = docId.split(":"); 
     final String type = split[0]; 

     Uri contentUri = null; 
     if ("audio".equals(type)) 
     { 
      contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 
     } 

     final String selection = "_id=?"; 
     final String[] selectionArgs = new String[] { 
       split[1] 
     }; 

     String filePath = getDataColumn(context, contentUri, selection, selectionArgs); 
    } 

isMediaDocument:

public static boolean isMediaDocument(Uri uri) 
{ 
    return "com.android.providers.media.documents".equals(uri.getAuthority()); 
} 

getDataColumn:

private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) 
{ 
    Cursor cursor = null; 
    final String column = "_data"; 
    final String[] projection = { 
      column 
    }; 

    try { 
     cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); 
     if (cursor != null && cursor.moveToFirst()) 
     { 
      final int column_index = cursor.getColumnIndexOrThrow(column); 
      return cursor.getString(column_index); 
     } 
    } finally { 
     if (cursor != null) 
      cursor.close(); 
    } 
    return null; 
} 

Если у вас есть проблемы, this является полный ответ, который проверяет наличие изображений , аудио, видео, файлы и т. д.

+0

Это решение, похоже, не работает для меня. Кажется, что файлы на диске имеют столбец с нулевым _data. https://code.google.com/p/android/issues/detail?id=63651 –

+0

@hhoang Хм, это странно, если у меня есть какое-то время на этой неделе, я буду искать ответ –

+0

Просто для уточнения, похоже _data будет пустым, если содержимое uri, отправленное, на самом деле не хранится на устройстве. Например, если я попытаюсь поделиться фотографией с приложением Google фотографий, которое хранится в облаке. Столбец _data будет пустым. Единственная работа, которую я нашел, - это скопировать файл, а затем передать полный путь нового файла к моей активности. Однако я не уверен, что это лучший доступный метод. Я написал здесь вопрос SO, если бы вы могли взглянуть. http://stackoverflow.com/questions/29378651/get-filepath-from-google-drive-in-lollipop-mediastore-mediacolumns-data-null –

Смежные вопросы