有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

向MediaMetadataRetriever中的setDataSource()发送Uri时发生java IllegalArgumentException

我也遇到过类似的问题:-

MediaMetadataRetriever setdatasource IllegalArgumentException

IllegalArgumentException in setDataSource for MediaPlayer

MediaMetadataRetriever setDataSource throws IllegalArgumentException

Log

我建议添加外部存储权限,或者该路径可能错误或无效。setDataSource()方法可以同时采用ContextUri。当我发送它们时,我会收到非法的辩论例外

以下是我发送到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

我确定音频文件在那里,我在另一个应用程序中打开了它

Uri value

我从SharedReference获取Uri,如下所示:-

Uri.parse(pref.getString("gotsong",""))//get the song Uri

我在SharedReference中设置Uri如下:-

editor.putString("gotsong", uri.toString());// save the song uri

事实上,如果我没有从共享首选项中检索并直接从文件中获取,也不例外

根据甲骨文IllegalArgumentException

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


共 (2) 个答案

  1. # 1 楼答案

    它与路径中的Utf8字符串有关。 所以在使用它之前,你需要解码Utf8中的url。那么它肯定会起作用

    URLDecoder.decode(video, "UTF-8")
    
  2. # 2 楼答案

    我发现问题是,如果Uri被保存在SharedReferences中,而没有读写Uri的权限,则会出现IllegalArgumentException,特别是针对音频文件这样的文件的Uri Iam。因此,该方法适用于以下情况:例如,如果我直接发送文件Uri,如果我保存共享pref中包含文件的文件夹路径,然后提取Uri并将其发送到该方法,或者如果我授予这些权限,以便在共享pref中保存文件,然后检索并发送到该方法

    所以我实现了雷克的答案:

    https://stackoverflow.com/a/46506626/7552894

    首先,我制定了“意向为行动”文件:

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

    -保存到共享优先级。恢复正常。有趣的是,直接来自文件的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