eidylon
eidylon

Reputation: 7248

How can I verify image URI is valid in Android?

I am building my own contact picker, because I needed multi-select support. Everything is working fine, except for one small problem with the contact images.

For contacts who don't have images I am showing a "no image" image. This works fine for contacts in the phone's address book. I am having a problem however when it comes to images from my google contacts.

Most of my google contacts do not have photos. However, when i query the Contacts database for photos, it still returns a URI for them of the form of content://com.android.contacts/contacts/657/photo (which is the same format as for contacts who do have a photo.

Then when I try to assign the photo to a QuickContactBadge, using bdg.setImageURI(pic); it sets it to essentially a blank picture, and logs a silent INFO message stating:

INFO/System.out(3968): resolveUri failed on bad bitmap uri: 
content://com.android.contacts/contacts/657/photo

I need to know how I can either
a) validate the URI or
b) catch the INFO message above
c) query the imageview/badge to see if it found a valid image

so that i can assign these contacts my "no image" image.
How can I go about doing this?

EDIT 20110812.0044

I have tried adding this to my code as per Laurence's suggestion (which he's since removed):

// rv is my URI variable
if(rv != null) {
    Drawable d = Drawable.createFromPath(rv.toString());
    if (d == null) rv = null;
}

While the google contacts now get my "no image" image, ... so do all the other contacts, including ones that do in fact have images.

Upvotes: 15

Views: 21674

Answers (6)

Ml Carrier
Ml Carrier

Reputation: 1

I created a function which returns boolean

private fun isUriValid(context: Context,uri: Uri):Boolean{
    val contentResolver = context.contentResolver
    return try {
        contentResolver.openInputStream(uri)?.close()
        true
    } catch (e:Exception){
        return false
    }
}

Upvotes: 0

vareste
vareste

Reputation: 445

I am using this code for Uri that has file:// authority

Uri resimUri = Uri.parse(path_str);
File imgFile = new File(resimUri.getPath());
if (imgFile.exists()) {
    // file exists
}else {
    // file is not there
}

Upvotes: -1

Bharath Kumar
Bharath Kumar

Reputation: 541

It could be that the images are not downloaded. I faced a similar problem with whatsapp images. One way to go about this could be like below:

InputStream is = null;
try {
   is = context.getContentResolver().openInputStream(myuri);
}catch (Exception e){
   Log.d("TAG", "Exception " + e);
}

if(is==null)
    //Assign to "no image"

Upvotes: 3

xnagyg
xnagyg

Reputation: 4931

Based on the code (http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/widget/ImageView.java) my solution for checking Uri:

public static Uri checkUriExists (Context  mContext,Uri mUri) {
    Drawable d = null;
    if (mUri != null) {
        if ("content".equals(mUri.getScheme())) {
            try {
                d = Drawable.createFromStream(
                        mContext.getContentResolver().openInputStream(mUri),
                        null);
            } catch (Exception e) {
                Log.w("checkUriExists", "Unable to open content: " + mUri, e);
                mUri = null;
            }
        } else {
            d = Drawable.createFromPath(mUri.toString());
        }

        if (d == null) {
            // Invalid uri
            mUri = null;
        }
    }

    return mUri;
}

Upvotes: 0

Risadinha
Risadinha

Reputation: 16666

Just to answer the question on how to check the (data) value in the MediaStore:

ContentResolver cr = getContentResolver();
String[] projection = {MediaStore.MediaColumns.DATA}
Cursor cur = cr.query(Uri.parse(contentUri), projection, null, null, null);
if(cur != null) {
    cur.moveToFirst();
    String filePath = cur.getString(0);

    if (filePath == null || filePath.isEmpty()) {
        // data not set
    } else if((new File(filePath)).exists()){
        // do something if it exists
    } else {
        // File was not found
        // this is binary data
    }
} else {
    // content Uri was invalid or some other error occurred 
}

Inspiration taken from: https://stackoverflow.com/a/7649784/621690 and others.

There is also the column SIZE that might be checked: http://developer.android.com/reference/android/provider/MediaStore.MediaColumns.html#SIZE It sounds like it should contain 0 if there is no data value. But I wouldn't know what it contains if data is a file path.

Upvotes: 4

eidylon
eidylon

Reputation: 7248

Okay, I figured out how to do this after poking through the ImageView source code. It is actually using the QuickContactBadge's own methods, but if necessary, one could always extract the relevant code from the Badge/ImageView control here.

After setting the QCB's image, I check to see if its drawable is null, instead of trying my own (as per Laurence's suggestion). This works better, because there is actually a whole slew of checking code the ImageView widget uses.

Here is my final code:

bdg.setImageURI(pic);
if(bdg.getDrawable() == null) bdg.setImageResource(R.drawable.contactg);

This works perfectly as I was hoping and expecting.

Upvotes: 15

Related Questions