Search code examples
androiduri

How to check if resource pointed by Uri is available?


I have resource (music file) pointed by Uri. How can I check if it is available before I try to play it with MediaPlayer?

Its Uri is stored in database, so when the file is deleted or on external storage that is unmounted, then I just get exception when I call MediaPlayer.prepare().

In above situation I would like to play systems default ringtone. I could of course do that after I catch above exception, but maybe there is some more elegant solution?

edit: I forgot to mention that music files Uri's are actually acquired by using RingtonePreference. This means that I can get Uri pointing to ringtone on Internal Storage, External Storage or to default systems ringtone.

Uri's examples are:

  • content://settings/system/ringtone - for choosing default ringtone
  • content://media/internal/audio/media/60 - for ringtone on Internal Storage
  • content://media/external/audio/media/192 - for ringtone on External Storage

I was happy with proposed "new File(path).exists() method, as it saved me from mentioned exception, but after some time I noticed that it returns false for all of my ringtone choices... Any other ideas?


Solution

  • The reason the proposed method doesn't work is because you're using the ContentProvider URI rather than the actual file path. To get the actual file path, you have to use a cursor to get the file.

    Assuming String contentUri is equal to the content URI such as content://media/external/audio/media/192

    ContentResolver cr = getContentResolver();
    String[] projection = {MediaStore.MediaColumns.DATA}
    Cursor cur = cr.query(Uri.parse(contentUri), projection, null, null, null);
    if (cur != null) {
      if (cur.moveToFirst()) {
        String filePath = cur.getString(0);
    
        if (new File(filePath).exists()) {
          // do something if it exists
        } else {
          // File was not found
        }
      } else {
         // Uri was ok but no entry found. 
      }
      cur.close();
    } else {
      // content Uri was invalid or some other error occurred 
    }
    

    I haven't used this method with sound files or internal storage, but it should work. The query should return a single row directly to your file.