如何验证图像 URI 在 Android 中是否有效?

发布于 2024-11-29 05:26:28 字数 1043 浏览 3 评论 0原文

我正在构建自己的联系人选择器,因为我需要多选支持。一切工作正常,除了接触图像的一个小问题。

对于没有图像的联系人,我将显示“无图像”图像。这对于手机地址簿中的联系人来说效果很好。然而,当涉及到我的谷歌联系人的图像时,我遇到了问题。

我的大多数谷歌联系人都没有照片。但是,当我查询联系人数据库中的照片时,它仍然返回 content://com.android.contacts/contacts/657/photo 形式的 URI(格式相同)对于确实有照片的联系人,

然后当我尝试将照片分配给 QuickContactBadge 时,使用 bdg.setImageURI(pic);它基本上将其设置为空白图片,并记录一条无声的 INFO 消息,说明:

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

我需要知道如何才能
a) 验证 URI
b) 捕获上面的 INFO 消息
c) 查询图像视图/徽章以查看是否找到有效图像,

以便我可以为这些联系人分配我的“无图像”图像。
我该怎么做呢?

编辑20110812.0044

我尝试按照劳伦斯的建议将其添加到我的代码中(他已将其删除):

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

虽然谷歌联系人现在获取我的“无图像”图像,...所有其他联系人也是如此,包括实际上确实有图像的。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

错々过的事 2024-12-06 05:26:28

好吧,在浏览了 ImageView 源代码后我知道了如何做到这一点。它实际上使用的是 QuickContactBadge 自己的方法,但如果有必要,人们总是可以提取 Badge/ImageView 控件的相关代码位于此处

设置 QCB 的图像后,我检查其可绘制对象是否为空,而不是尝试我自己的图像(根据劳伦斯的建议)。这效果更好,因为 ImageView 小部件实际上使用了大量的检查代码。

这是我的最终代码:

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

这正如我所希望和期望的那样完美地工作。

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.

逆夏时光 2024-12-06 05:26:28

只是回答有关如何检查 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 
}

灵感来自:https://stackoverflow.com/ a/7649784/621690 等。

还有可能会检查的列 SIZEhttp://developer.android.com/reference/android/provider/MediaStore.MediaColumns.html#SIZE
听起来如果没有数据值它应该包含 0。但如果数据是文件路径,我不知道它包含什么。

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.

且行且努力 2024-12-06 05:26:28

可能是图片没有下载。我在使用 Whatsapp 图片时遇到了类似的问题。
解决这个问题的一种方法可能如下所示:

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

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

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"
不再见 2024-12-06 05:26:28

基于代码(http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/widget/ImageView.java)我的检查Uri的解决方案:

public static Uri checkUriExists (Context mContext,Uri mUri) {
    可绘制 d = null;
    if (mUri != null) {
        if ("content".equals(mUri.getScheme())) {
            尝试 {
                d = Drawable.createFromStream(
                        mContext.getContentResolver().openInputStream(mUri),
                        无效的);
            } catch (异常 e) {
                Log.w("checkUriExists", "无法打开内容:" + mUri, e);
                mUri = 空;
            }
        } 别的 {
            d = Drawable.createFromPath(mUri.toString());
        }

        如果(d == null){
            // 无效的uri
            mUri = 空;
        }
    }

    返回 mUri;
}

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;
}
柠栀 2024-12-06 05:26:28

我创建了一个返回布尔值的函数

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

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
    }
}
倾`听者〃 2024-12-06 05:26:28

我将此代码用于具有 file:// 权限的 Uri

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

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文