【问题标题】:Simple way to add contact photo to ImageView?将联系人照片添加到 ImageView 的简单方法?
【发布时间】:2013-01-12 11:23:03
【问题描述】:

我在获取和设置联系人图像作为视图背景时遇到问题,令人惊讶的是,很少有关于如何执行此操作的示例。我正在尝试构建类似于显示大型联系人照片的人脉应用程序。

这就是我现在正在做的事情:

Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.valueOf(id));
InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(), uri);
Bitmap bm = BitmapFactory.decodeStream(input);
Drawable d = new BitmapDrawable(bm);
button.setBackgroundDrawable(drawable);

这可行,但是它使用的 URI 会获取缩略图,因此即使有一张大照片,在缩放以适合 imageView 时,图像看起来也很糟糕。我知道另一种获取实际获取大照片的 URI 的方法是:

final Uri imageUri = Uri.parse(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.PHOTO_URI)));

但是我还没有设法将它放到 imageView 中,也许上面的代码可以调整为使用第二个 uri。如果您知道如何使用第二个 uri,或者如果有比通过 URI 更简单的方法来获取联系人图像,请告诉我。任何信息将不胜感激。

【问题讨论】:

  • 我想这就是你要找的stackoverflow.com/a/8586182/1832000
  • 我一直没能实现。它需要变量 url 和文件 ImageOperations(this,url,filename) 我不知道这些是什么。如果您知道使用什么作为 url 和文件名(如果可行),我会接受您的回答。

标签: java android view


【解决方案1】:

在获取 URI 方面做得很好。你快到了。首先考虑使用 PHOTO_THUMBNAIL_URI 而不是 PHOTO_URI,因为它可能是您需要的大小。

编辑:仅供参考,PHOTO_THUMBNAIL_URI 从 API 11 开始可用。您仍然可以有条件地使用它。

如果你想使用外部库,'Android Universal Image Loader'绝对是你要找的,因为它从几天前的 1.7.1 版本开始,它增加了对内容方案的支持,它非常​​聪明,明智的记忆。它还有很多自定义选项。

编辑:这个库已经死了。请改用Fresco

如果您希望更好地调整最终包的大小并自己编写代码,

您需要获取并解码该内容的输入流;这应该在后台线程上完成。看看这个方便的方法;您使用您的图像视图和您获得的 uri 对其进行初始化,并在您想要加载 ImageView 时启动它。

private class ContactThumbnailTask extends AsyncTask<Void, Void, Bitmap> {

    private WeakReference<ImageView> imageViewWeakReference;
    private Uri uri;
    private String path;
    private Context context;


    public ContactThumbnailTask(ImageView imageView, Uri uri, Context context) {
        this.uri = uri;
        this.imageViewWeakReference = new WeakReference<ImageView>(imageView);
        this.path = (String)imageViewWeakReference.get().getTag(); // to make sure we don't put the wrong image on callback
        this.context = context;
    }

    @Override
    protected Bitmap doInBackground(Void... params) {
        InputStream is = null;
        try {
            is = context.getContentResolver().openInputStream(uri);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        Bitmap image = null;
        if (null!= is)
            image=  BitmapFactory.decodeStream(is);

        return image;
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (imageViewWeakReference != null && imageViewWeakReference.get() != null && ((String)imageViewWeakReference.get().getTag()).equals(path) && null != bitmap)
            imageViewWeakReference.get().setImageBitmap(bitmap);
    }
}

【讨论】:

  • 我之前使用的是 ImageButton。我注意到更改为 ImageView 并使用 setImageUri() 实际上可以很好地设置图像。但是有一个小问题,我不知道为什么,但我在 ImageView 的顶部和底部得到了一个空白区域。如果您知道如何解决它,我会接受答案
  • 我无法实现这个顺便说一句我的所有图像视图中都有空格
  • 使用setImageUri有什么问题吗?使用后台线程会更有效
  • setImageUri 在 UI 线程上进行解码,这会导致延迟打嗝,所以我建议不要这样做。你看过 ImageView 的 scaletype 吗?尺寸是固定的吗?
【解决方案2】:

要做到这一点,您只需添加最后一个参数preferHighres = true:

openContactPhotoInputStream (ContentResolver cr, Uri contactUri, boolean preferHighres)

如果 preferHighres 为真并且联系人有更高分辨率的照片可用,则返回该照片。如果为 false,则此函数总是尝试获取缩略图

     Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.valueOf(id));
     InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(), uri, true);

所有图像可能都有不同的尺寸。为了调整它们的大小,我使用下一个代码:

    Bitmap bm = BitmapFactory.decodeStream(input);
    bm = Bitmap.createScaledBitmap(photo, contactImageWidth, contactImageheight, false);
    Drawable d = new BitmapDrawable(getContext(), bm);
    button.setBackgroundDrawable(d);

【讨论】:

    【解决方案3】:

    您可以使用以下方法轻松地将联系人照片设置为图像视图。

    public String getImageUriString(String phoneNumber)
    {
        ContentResolver resolver = context.getContentResolver();
        Cursor names = resolver.query(
                Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber)),
                null, null, null, null);
    
        names.moveToFirst();
        String name = "";
        if(!names.isAfterLast())
        {
            name = names.getString(names.getColumnIndex(ContactsContract.PhoneLookup.PHOTO_URI));
    
        }
        else
        {
            name = null;
        }
    
        names.close();
    
        return name;
    }
    
    
    
    
    
    public void setImageView(ImageView contactPhoto) {
    
    String photoUriString = di.getImageUriString(contactNumber);
            if(photoUriString != null) {
                Uri photoUri = Uri.parse(photoUriString);
                contactPhoto.setImageURI(photoUri);
            } else {
                contactPhoto.setImageResource(R.drawable.icon_contact);
            }
    }
    

    在您的班级中,使用从上述方法获取的 uri 设置图像视图。

    【讨论】:

      【解决方案4】:

      这是建议。首先要知道一件事。

      当您设置联系人图像时。首先 Android 显示该图像的裁剪活动。喜欢

      ****仔细看上面的图片。 Android 将图像裁剪为方形。并将方形图像作为 Blob 存储在联系人中。(它不是单个图像。它是 Blob。)
      您从编码中获得图像视图的方形图像。所以顶部和底部只显示黑色。因为你的手机是矩形的。****

      如果要显示全屏图像。请以编程方式为联系人设置大图像。互联网上有很多例子。

      一切顺利。如果您有任何疑问。请提供cmets。

      【讨论】:

        【解决方案5】:

        使用外部库为您执行此操作。或者浏览代码并按照自己的方式制作类似的东西。

        这是我在自己的几个应用中使用的一个:UrlImageViewHelper

        代码如下:

        Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.valueOf(id));  
        UrlImageViewHelper.setUrlDrawable(button, uri.toString(), R.drawable.dummy_contact_photo); 
        

        【讨论】:

          【解决方案6】:

          这可能会对您有所帮助(联系人由 getId() 标识):

          /**
           * @return the photo URI
           */
          
          public Uri getPhotoUri() {
              try {
                  Cursor cur = this.ctx.getContentResolver().query(
                          ContactsContract.Data.CONTENT_URI,
                          null,
                          ContactsContract.Data.CONTACT_ID + "=" + this.getId() + " AND "
                                  + ContactsContract.Data.MIMETYPE + "='"
                                  + ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'", null,
                          null);
                  if (cur != null) {
                      if (!cur.moveToFirst()) {
                          return null; // no photo
                      }
                  } else {
                      return null; // error in cursor process
                  }
              } catch (Exception e) {
                  e.printStackTrace();
                  return null;
              }
              Uri person = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long
                      .parseLong(getId()));
              return Uri.withAppendedPath(person, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
          }
          

          用法是:

          Uri u = objItem.getPhotoUri();
          if (u != null) {
                  mPhotoView.setImageURI(u);
          } else {
                  mPhotoView.setImageResource(R.drawable.ic_contact_picture_2);
          }
          

          【讨论】:

            【解决方案7】:

            您可以尝试使用 SmartImageView:http://loopj.com/android-smart-image-view/ 扩展 imageview 并异步加载图像。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-01-05
              • 1970-01-01
              相关资源
              最近更新 更多