How to convert a content Uri into a File

10,253

pass the Uri to another activity and retrieve it

Your other activity does not necessarily have rights to work with the content identified by the Uri. Add FLAG_GRANT_READ_URI_PERMISSION to the Intent used to start that activity, and pass the Uri via the "data" facet of the Intent (setData()), not an extra.

To get the actual Path of the Uri

First, there is no requirement that the Uri that you get back be from the MediaStore.

Second, managedQuery() has been deprecated for six years.

Third, there is no requirement that the path that MediaStore has be one that you can use. For example, the audio file might be on removable storage, and while MediaStore can access it, you cannot.

How to convert a content Uri into a File

On a background thread:

  • Get a ContentResolver by calling getContentResolver() on a Context
  • Call openInputStream() on the ContentResolver, passing in the Uri that you obtained from ACTION_GET_CONTENT, to get an InputStream on the content identified by the Uri
  • Create a FileOutputStream on some File, where you want the content to be stored
  • Use Java I/O to copy the content from the InputStream to the FileOutputStream, closing both streams when you are done
Share:
10,253

Related videos on Youtube

Daniele
Author by

Daniele

I'm a student in computer science in Rome, Italy. I am interested in programming and technology in general! Check out my new Android App: https://play.google.com/store/apps/details?id=com.dancam.chords&hl=it

Updated on June 23, 2022

Comments

  • Daniele
    Daniele about 2 years

    I know there are a ton of questions about this exact topic, but after spending two days reading and trying them, none seamed to fix my problem.

    This is my code:

    I launch the ACTION_GET_CONTENT in my onCreate()

    Intent selectIntent = new Intent(Intent.ACTION_GET_CONTENT);
            selectIntent.setType("audio/*");
            startActivityForResult(selectIntent, AUDIO_REQUEST_CODE);
    

    retrieve the Uri in onActivityResult()

    @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if (requestCode == AUDIO_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
                if ((data != null) && (data.getData() != null)) {
                    audio = data.getData();
                }
            }
        }
    

    pass the Uri to another activity and retrieve it

    Intent debugIntent = new Intent(this, Debug.class);
                Bundle bundle = new Bundle();
                bundle.putString("audio", audio.toString());
                debugIntent.putExtras(bundle);
                startActivity(debugIntent);
    
    Intent intent = this.getIntent();
            Bundle bundle = intent.getExtras();
            audio = Uri.parse((String) bundle.get("audio"));
    

    The I have implemented this method based on another SO answer. To get the actual Path of the Uri

    public static String getRealPathFromUri(Activity activity, Uri contentUri) {
            String[] proj = { MediaStore.Audio.Media.DATA };
            Cursor cursor = activity.managedQuery(contentUri, proj, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        }
    

    and in the Debug activity's onCreate() I try to generate the file:

    File audioFile = new File(getRealPathFromUri(this, audio));
    

    This is how the error looks like:

    Caused by: java.lang.NullPointerException at java.io.File.(File.java:262) at com.dancam.lietome.Debug.onCreate(Debug.java:35)

    When I run the app I get a NPE on this last line. The audio Uri, isn't NULL though so I don't understand from what it is caused.

    I'd really appreciate if you helped me out.

    This is the library I'm trying to work with.

    Note: I know exactly what NPE is, but even debugging I couldn't figure out from what it is caused in this specific case.

    • pskink
      pskink almost 7 years
      simply by using ContentResolver API - it has methods for opening any content:// based Uri
    • pskink
      pskink
      then try to read ContentResolver documentation, but you didnt answer my question: where do you want to use your audio Uri? there is a chance that you can do that even easier...
  • nivesh shastri
    nivesh shastri almost 7 years
    I am checked this code for .doc file format I get real path from this.
  • Daniele
    Daniele almost 7 years
    it returns home:test1.wav that's not the whole path right? Because the file isn't generated correctly
  • nivesh shastri
    nivesh shastri almost 7 years
    you test this in emulator or in real device?
  • nivesh shastri
    nivesh shastri almost 7 years
    I also use this code in OnePlus 3t, I am getting correct path.
  • CommonsWare
    CommonsWare almost 7 years
    This will only work if the scheme is file, which is increasingly uncommon.
  • pskink
    pskink almost 7 years
    but honestly i really doubt OP needs a File - most 3rd party libs when they have File param, they also accept InputStream as their input - infortunately OP didnt want to say where he wants to use it...
  • Declan Nnadozie
    Declan Nnadozie over 3 years
    Hello, i think pdfBytes will be very large for program memory if the pdf is large. What do you think?