向MediaMetadataRetriever中的setDataSource()发送Uri时发生java IllegalArgumentException
我也遇到过类似的问题:-
MediaMetadataRetriever setdatasource IllegalArgumentException
IllegalArgumentException in setDataSource for MediaPlayer
MediaMetadataRetriever setDataSource throws IllegalArgumentException
我建议添加外部存储权限,或者该路径可能错误或无效。setDataSource()
方法可以同时采用Context
和Uri
。当我发送它们时,我会收到非法的辩论例外
以下是我发送到Uri的方法:-
static List<String> getMusicNames(Context context,List<Uri> Uris){//get the music names
List<String> musicNames=new ArrayList<String>();
for(Uri uri:Uris){
MediaMetadataRetriever mData = new MediaMetadataRetriever();
mData.setDataSource(context, uri);//<<<<<at this line the error
musicNames.add(mData.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE));
}//returning the music names
return musicNames;
}
我发送的Uri如下:-
Arrays.asList(songUri)
它可以是多个Uri,也可以只是一个Uri
当我调试这个程序时,这个Uri会转到方法:-content://com.安卓.externalstorage.documents/document/primary%3ADownload%2F01-1085088-Full%20Song-Track%201%20_%20Sakkarathil%20amma.mp3
我确定音频文件在那里,我在另一个应用程序中打开了它
我从SharedReference获取Uri,如下所示:-
Uri.parse(pref.getString("gotsong",""))//get the song Uri
我在SharedReference中设置Uri如下:-
editor.putString("gotsong", uri.toString());// save the song uri
事实上,如果我没有从共享首选项中检索并直接从文件中获取,也不例外
public class IllegalArgumentException extends RuntimeException Thrown to indicate that a method has been passed an illegal or inappropriate argument.
这是最初的setDataSource()
方法。我已经指出了引发异常的位置:-
public void setDataSource(Context context, Uri uri)
throws IllegalArgumentException, SecurityException {
if (uri == null) {
throw new IllegalArgumentException()//<<<<<<<<<<<<<<<<<<<<<<<<<<<HERE
}
String scheme = uri.getScheme();
if(scheme == null || scheme.equals("file")) {
setDataSource(uri.getPath());
return;
}
AssetFileDescriptor fd = null;
try {
ContentResolver resolver = context.getContentResolver();
try {
fd = resolver.openAssetFileDescriptor(uri, "r");
} catch(FileNotFoundException e) {
throw new IllegalArgumentException();//<<<<<<<<<<<<<<<<<<<<<<<<<<<HERE
}
if (fd == null) {
throw new IllegalArgumentException();//<<<<<<<<<<<<<<<<<<<<<<<<<<<HERE
}
FileDescriptor descriptor = fd.getFileDescriptor();
if (!descriptor.valid()) {
throw new IllegalArgumentException();//<<<<<<<<<<<<<<<<<<<<<HERE
}
// Note: using getDeclaredLength so that our behavior is the same
// as previous versions when the content provider is returning
// a full file.
if (fd.getDeclaredLength() < 0) {
setDataSource(descriptor);
} else {
setDataSource(descriptor, fd.getStartOffset(), fd.getDeclaredLength());
}
return;
} catch (SecurityException ex) {
} finally {
try {
if (fd != null) {
fd.close();
}
} catch(IOException ioEx) {
}
}
setDataSource(uri.toString());
}
很明显,Uri不是空的,所以这是另外三个原因之一,一个在FileNotFoundException中,另两个我不明白
我的问题实际上类似于这个问题:-Save uri to sharedPreferences and play with mediaplayer
# 1 楼答案
它与路径中的Utf8字符串有关。 所以在使用它之前,你需要解码Utf8中的url。那么它肯定会起作用
# 2 楼答案
我发现问题是,如果Uri被保存在SharedReferences中,而没有读写Uri的权限,则会出现IllegalArgumentException,特别是针对音频文件这样的文件的Uri Iam。因此,该方法适用于以下情况:例如,如果我直接发送文件Uri,如果我保存共享pref中包含文件的文件夹路径,然后提取Uri并将其发送到该方法,或者如果我授予这些权限,以便在共享pref中保存文件,然后检索并发送到该方法
所以我实现了雷克的答案:
https://stackoverflow.com/a/46506626/7552894
首先,我制定了“意向为行动”文件:
我在第一次得到意图后添加了这一部分:
-保存到共享优先级。恢复正常。有趣的是,直接来自文件的Uri看起来是这样的:-
content://com.android.externalstorage.documents/document/primary%3ADownload%2FDeath%20Grips%20-%20Get%20Got.mp3
如果未保存在共享优先级中,则获取结果
然而,从新的意图中得到的结果看起来是这样的:-
content://com.android.providers.downloads.documents/document/433
可以拯救的人
编辑
此外,文件夹树Uri可以在没有读取Uri权限的情况下保存和检索,只有文件树需要Uri权限。我试图从Uri树中获取文件夹树,但这在获取文件时不起作用,Uri必须来自Intent