如何将字符串转换为URI而不抛出异常

4
我需要将一个Uri转换为字符串,以便我可以序列化该Uri。
Intent openFileIntent = new Intent(Intent.ACTION_GET_CONTENT);
openFileIntent.addCategory(Intent.CATEGORY_OPENABLE);
openFileIntent.setType("audio/mpeg");
startActivityForResult(openFileIntent, PICK_MP3_FILE);

...然后在活动结果上...

public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == PICK_MP3_FILE)
        {
            if (resultCode == RESULT_OK)
            {
                try
                {
                    if (data != null)
                    {
                        Uri mp3AudioFile;
                        if ((mp3AudioFile = data.getData()) != null)
                        {
                            myObject.setMp3Path(mp3AudioFile.getPath());
                            myObject.Save();

                        }
                    }
                } catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        }
    }

我关闭了应用程序并重新打开。当我尝试使用以下方式打开该Uri时:

Uri uri = Uri.parse(myObject.getMp3Path();

我遇到了一个错误:

java.lang.SecurityException: Permission Denial: reading com.android.providers.downloads.DownloadStorageProvider uri content://com.android.providers.downloads.documents/document/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2Faudio.mp3 from pid=601, uid=10107 requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs

我的清单文件具有以下权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
3个回答

3

我们需要提供持久的Uri权限。


JAVA

 Intent openFileIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
 openFileIntent.addCategory(Intent.CATEGORY_OPENABLE);
 openFileIntent.setType("audio/mpeg");
 startActivityForResult(openFileIntent, PICK_MP3_FILE);

同样值得一提的是,持久权限仅适用于 Intent.ACTION_OPEN_DOCUMENT ,而不适用于 Intent.ACTION_GET_CONTENT,后者只能使用一次。

顺便说一下,这个问题又出现了。如果我保存文件名并重新启动手机,我会失去该文件的权限。有人可以帮忙吗?是否有一种方法可以永久授予下载或其他文件夹中的mp3文件访问权限? - DevJayJay
我本来想回答这个问题的。看起来根据错误代码是很常见的,但我从未实现过这种类型的意图,所以我放弃了... - Nate T
@DevJayJay。你是否不知情地使用了Intent.ACTION_GET_DOCUMENT?为了确保,请全局搜索一下。 - Akin Okegbile
2
没事了,我已经弄清楚问题所在了。我需要使用takePersistableUriPermission()和Intent.FLAG_GRANT_READ_URI_PERMISSION来持久化权限。实际上这在文档中有提到,但我不确定自己是否在正确的过程中操作。如果有人想要在重启后保留权限,请记得使用takePersistableUriPersmission()! - DevJayJay
看看编辑历史记录...这是在原始答案中:p。下次提醒我坚持自己的想法,哈哈 - Akin Okegbile
显示剩余3条评论

1
为了做到这一点,我使用了getPath()。 你应该使用toString()代替。
 String scheme = uri.toString();

 Uri uri = Uri.parse(scheme);

我确实使用了toString。抱歉,我已经编辑了问题。 - DevJayJay

0

在收到URI的第一时间,需要解决权限拒绝问题。

    private val pickImage = registerForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) { result: ActivityResult ->
        if (result.resultCode == Activity.RESULT_OK) {
            //  you will get result here in result.data
            val uri = result.data?.data!!
            requireActivity().contentResolver.takePersistableUriPermission(
                uri,
                Intent.FLAG_GRANT_READ_URI_PERMISSION
            )
            // Do something else with the URI. E.g, save the URI as a string in the database
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接