Android - Convert URI to file path on lollipop

匿名 (未验证) 提交于 2019-12-03 02:31:01

问题:

I'm currently attempting to make a media player for audio. I'm currently running lollipop. I ran into a problem setting the dataSource for the media player. First, here's how I set the dataSource:

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(); } 

And the Uri comes out to this:

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

I did some research, and from my understanding, after Android 4.1, you can no longer use a URI for the dataSource. When I run this app with the code above, I'll get this error:

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) 

So now I need to convert the URI to a file path and provide that as the dataSource. And, after more research, it appears kitkat changed the way URI's are provided so its difficult to get the file path from the URI. However, I'm not sure if this change persisted into Android Lollipop 5.0.2.

Essentially, I have the URI of a song, but I need to provide something other than a URI to a dataSource. Is there any way that I can convert the URI on Lollipop, and, if not, how can I provide the dataSource only knowing the song's id? Thanks.

回答1:

Lollipop decided to take another course with getting files from the system. (Some say it is from KitKat, but I haven't encountered it yet on KitKat). The code below is to get the filepath on lollipop

    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; } 

If you still have problems, this is the full answer that checks for images, audio, video, files, etc.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!