javaandroidandroid-permissionsandroid-fileandroid-fileprovider

How to convert a string to a URI without throwing exceptions


I had to convert a Uri to a string so that I could serialize that Uri.

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

...then on activity result...

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

I closed the app and opened again. When I try to open that Uri with:

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

I get an error:

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

My Manifest has the following permissions:

<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" />

Solution

  • We need to provide persistent Uri permission.


    JAVA

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

    Also, a note worth mentioning is persistent permission is available only to Intent.ACTION_OPEN_DOCUMENT and NOT Intent.ACTION_GET_CONTENT whereas the latter one is like a one-time thing.