Java 向MediaMetadataRetriever中的setDataSource()发送Uri时发生IllegalArgumentException
我也问过类似的问题:- 我添加了外部存储权限,或者该路径可能错误或无效。Java 向MediaMetadataRetriever中的setDataSource()发送Uri时发生IllegalArgumentException,java,android,uri,media,Java,Android,Uri,Media,我也问过类似的问题:- 我添加了外部存储权限,或者该路径可能错误或无效。setDataSource()方法可以同时使用Context和Uri。当我发送它们时,我会收到IllegalArgumentException 以下是我发送到Uri的方法:- static List<String> getMusicNames(Context context,List<Uri> Uris){//get the music names List<String> m
setDataSource()
方法可以同时使用Context
和Uri
。当我发送它们时,我会收到IllegalArgumentException
以下是我发送到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,也可以只是一个Uri
当我调试这个程序时,会显示到方法:-content://com.android.externalstorage.documents/document/primary%3ADownload%2F01-1085088首完整的%20Song曲目%201%20_u%20Sakkarathil%20amma.mp3
我确信音频文件在那里,我在另一个应用程序中打开了它
我从SharedReference获取Uri,如下所示:-
Uri.parse(pref.getString("gotsong",""))//get the song Uri
我在SharedReferences中设置Uri如下:-
editor.putString("gotsong", uri.toString());// save the song uri
事实上,若我并没有从共享首选项中检索,而是直接从文件中获取,那个么也并没有例外
根据甲骨文
公共类IllegalArgumentException
扩展运行时异常
抛出以指示已向方法传递非法或不适当的参数
这是原始的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());
}
public void setDataSource(上下文,Uri)
抛出IllegalArgumentException、SecurityException{
if(uri==null){
抛出新的IllegalArgumentException()// 我发现问题在于,如果Uri保存在SharedReferences中而没有读写Uri的权限,则会出现IllegalArgumentException,特别是针对音频文件之类的文件的Uri Iam。因此,该方法适用于以下情况:例如,如果我直接发送文件Uri,如果我保存的文件夹路径包含共享pref中的文件,则提取URI并将其发送到该方法,或者如果我授予这些权限以在shared pref中保存文件,则检索并发送到该方法
因此,我实施了雷克的回答:
首先,我制定了“意向为行动”的开放文件:-
intent.setType("audio/*");
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
在第一次获得意图后,我添加了此部分:-
this.grantUriPermission(this.getPackageName(), data.getData(), Intent.FLAG_GRANT_READ_URI_PERMISSION);
final int takeFlags = data.getFlags()
& (Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION); // Check for the freshest data.
//noinspection WrongConstant
this.getContentResolver().takePersistableUriPermission(data.getData(), takeFlags);
-保存到共享pref.并正常检索。有趣的是,直接来自该文件的Uri如下所示:-content://com.android.externalstorage.documents/document/primary%3ADownload%2FDeath%20Grips%20-%20Get%20Get.mp3
如果未保存在共享优先级中,则获取结果
然而,从新的意图中得到的结果看起来是这样的:-content://com.android.providers.downloads.documents/document/433
可以拯救的人
编辑
此外,文件夹树Uri可以在没有读取Uri权限的情况下保存和检索,只有文件树需要Uri权限。我尝试从Uri树获取文件夹树,但这在获取文件时无效,Uri必须来自Intent。它与路径中的Utf8字符串相关。
因此,在使用它之前,您需要从Utf8解码url。然后它肯定会工作
URLDecoder.decode(video, "UTF-8")
URLDecoder.decode(video, "UTF-8")