Picasso 自带了对加载显示联系人头像的支持,只要传入联系人头像的 URL,例如
"photo:content://com.android.contacts/contacts/1005/photo", 再调用 Picasso.load(Uri).into(ImageView),即可完成对联系人头像的显示。

但这种用法有个局限:当我们并不知道某个联系人的头像 URL 时,首先得通过名字(或其他,如电话号码)获取到联系人头像的 URL,而这通常是耗时操作(查询数据库),需要异步进行;这样一来,先异步查询出头像 URL,再交给 Picasso 进行异步加载并显示,两级异步显得有点儿鸡肋。所以本文除了简单介绍

  • Picasso 自带对联系人头像的支持

外,还将介绍另一种用法,

  • 使用自定义 RequestHandler

下面,我们以 根据联系人名字获取联系人头像 为例,来讲解这两种用法。

一、使用 Picasso 的内置支持来加载

Picasso(以 2.5.2 版本为例) 总共支持 5 种联系人头像的 URL 格式

  • photo:content://com.android.contacts/contacts/lookup/*/#
  • photo:content://com.android.contacts/contacts/lookup/*
  • photo:content://com.android.contacts/contacts/#/photo
  • photo:content://com.android.contacts/contacts/#
  • photo:content://com.android.contacts/display_photo/#

加载过程分以下几步:

1. 根据名字获取联系人头像的 URL

Uri elvisUrl = getContactPhotoUrl("Elvis");/*** 根据名字获取联系人头像的 URL。* @param contactName 联系人的名字* @return 联系人头像的 URL*/
@Nullable
public static Uri getContactPhotoUrl(Context context, String contactName) {Uri phoneUri = null;Cursor cursor = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,new String[]{ContactsContract.Contacts.PHOTO_URI},ContactsContract.Contacts.DISPLAY_NAME_PRIMARY + " = ?",new String[]{contactName},null);if (cursor != null) {try {if (cursor.moveToFirst()) {String photoUrlString = cursor.getString(0);if (!TextUtils.isEmpty(photoUrlString)) {phoneUri = Uri.parse(photoUrlString);}}} finally {cursor.close();}}return phoneUri;
}

2. 使用 Picasso.load(Uri).into(ImageView) 进行显示

mPicasso.load(elvisUrl).into(imageView);

二、使用自定义 RequestHandler 加载

1. 自定义 RequestHandler

public static final String URL_SCHEMA_CONTACT_PHOTO = "contact.photo";private class CustomRequestHandler extends RequestHandler {@Overridepublic boolean canHandleRequest(Request data) {return URL_SCHEMA_CONTACT_PHOTO.equals(data.uri.getScheme());}/*** 将联系人头像的缩略图数据作为输入流返回。*/@Overridepublic Result load(Request request, int networkPolicy) throws IOException {Uri uri = request.uri;// 从联系人 URL 中解析出联系人名字String contactName = uri.getAuthority();// 根据名字获取联系人的 Contact IDlong contactId = getContactId(mContext, contactName);if (contactId <= 0) {return null;}// 根据联系人的 Contact ID 获取联系人头像的缩略图数据byte[] photoData = loadPhotoData(mContext, contactId);if (photoData == null) {return null;}InputStream photoInputStream = new ByteArrayInputStream(photoData);return new Result(photoInputStream, Picasso.LoadedFrom.DISK);}
}/*** 根据名字获取联系人的 Contact ID。** @param displayName 联系人的名字* @return 联系人的 Contact ID*/
public static long getContactId(Context context, String displayName) {long contactId = 0;ContentResolver contentResolver = context.getContentResolver();Uri uri = ContactsContract.Data.CONTENT_URI;String[] projection = new String[]{ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID};String selection = ContactsContract.Data.MIMETYPE + " = ? AND "+ ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME + " = ?";String[] selectionArguments = {ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE, displayName};Cursor cursor = contentResolver.query(uri, projection, selection, selectionArguments, null);if (cursor != null) {try {if (cursor.moveToFirst()) {contactId = cursor.getLong(0);}} finally {cursor.close();}}return contactId;
}/*** 根据联系人的 Contact ID 获取联系人头像的缩略图数据。** @param contactId 联系人的 Contact ID* @return 联系人头像的缩略图数据*/
public static byte[] loadPhotoData(Context context, long contactId) {byte[] photoData = null;Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);Uri photoUri = Uri.withAppendedPath(contactUri,ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);Cursor cursor = context.getContentResolver().query(photoUri,new String[]{ContactsContract.Contacts.Photo.PHOTO}, null, null, null);if (cursor != null) {try {if (cursor.moveToFirst()) {photoData = cursor.getBlob(0);}} finally {cursor.close();}}return photoData;
}

2. 在初始化 Picasso 时添加自定义的 RequestHandler

mPicasso = new Picasso.Builder(context).addRequestHandler(new CustomRequestHandler())... // 省略其他配置.build();

3. 组装联系人("Elvis")的头像 URL

/*** 获取代表特定联系人头像缩略图的 URL** @param contactName 特定联系人的显示名* @return 代表特定联系人头像缩略图的 URL*/
public static Uri getContactPhotoLoadableUrl(String contactName) {return new Uri.Builder().scheme(URL_SCHEMA_CONTACT_PHOTO).authority(contactName).build();
}Uri elvisUrl = getContactPhotoLoadableUrl("Elvis");

4. 使用 Picasso.load(Uri).into(ImageView) 进行显示

mPicasso.load(elvisUrl).into(imageView);

至此,使用 Picasso 加截显示联系人头像的两种方法已介绍完毕。大家可根据自己需求,择其一使用。在联系人头像 URL 未知的情况下,优选第二种方案,这样可以让联系人的头像加载像其他网络图片的加载一样简便。

关于作者
ElvisHew 的开源项目: XLog
ElvisHew 的 Github 主页: https://github.com/elvishew
ElvisHew 的新浪微博:http://weibo.com/elvishew

作者:ElvisHew
链接:https://www.jianshu.com/p/5488e3b7f3bc
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

使用 Picasso 加载显示联系人头像相关推荐

  1. android picasso 显示本地图片,剖析Picasso加载压缩本地图片流程(解决Android 5.0部分机型无法加载本地图片的问题)...

    之前项目中使用Picasso遇到了一个问题:在Android 5.0以上版本的部分手机上使用Picasso加载本地图片会失败.为了解决这个问题,研究了一下Picasso加载和压缩本地图片的流程,才有了 ...

  2. 剖析Picasso加载压缩本地图片流程(解决Android 5.0部分机型无法加载本地图片的问题)

    之前项目中使用Picasso遇到了一个问题:在Android 5.0以上版本的部分手机上使用Picasso加载本地图片会失败.为了解决这个问题,研究了一下Picasso加载和压缩本地图片的流程,才有了 ...

  3. 加载中_GIS地图在项目中的加载显示

    下面我们就来说说如何在应用程序中加载显示GIS地图,首先我们在SuperMap iDesktop 9D(10i)中编辑好我们需要的地图,如下图所示: 如上图所示,这是我编辑好的一幅天河区的地图,下面我 ...

  4. Axure教程:中继器如何加载显示图片

    编辑导语:在原型设计中,很多场景会应用到"中继器"这个元件.那么中继器如何加载显示图片的操作?很多新手都会无从下手.本文作者详细讲解了中继器加载显示图片的方法,供你学习. 一.元件 ...

  5. Android开发必备之Picasso加载图片

    为什么使用Picasso 传统的加载网络图片. public void saveToFile(String destUrl) {FileOutputStream fos = null;Buffered ...

  6. three.js 加载显示文字

    three.js 加载显示文字 代码放到 ./three.js/examples/ 下 <!DOCTYPE html> <html lang="en">&l ...

  7. Android 四大组件之——Acitivity(四) Activity是如何加载显示内容的?

    1. 在Activity调用onCreate()等生命周期之前,Activity会调用attach()方法,而在attach()方法中会调用如下代码 onAttach() {PolicyManager ...

  8. thinkphp+ajax无刷新分页并加载显示图片

    2019独角兽企业重金招聘Python工程师标准>>> 最近自己用thinkphp和bootstrap做一个小站点,在用到ajax与后台数据库交互实现无刷新分页时,因为我需要返回的数 ...

  9. Ionic+Angular+Express实现前后端交互使用HttpClient发送get请求数据并加载显示(附代码下载)

    场景 Ionic介绍以及搭建环境.新建和运行项目: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/106308166 在上面搭建起 ...

最新文章

  1. #时间预测算法_改进的智慧交通系统出行时间预测算法
  2. TortoiseGit 连接oschina不用每次输入username和password的方法
  3. 第十七届全国大学生完全车模组竞速赛方案 - 草案
  4. mysqldump 导出数据库各参数详细说明
  5. 汉中职业技术学院计算机专业,2020年陕西省青年职业技能大赛计算机网络管理员决赛开幕式在汉中职院举行...
  6. 《C++入门经典(第6版)》——1.5 问与答
  7. 统计学习II.7 广义线性模型1 指数分布族
  8. HDU4143-A Simple Question数论题解
  9. K8S 部署rabbitmq集群
  10. m2eclipse简单使用,创建Maven项目 ,运行mvn命令(转)
  11. win10+Ubuntu16.04 LTS双系统完美教程
  12. PetShop的系统架构设计
  13. 17张程序员搞笑图片
  14. ZEMAX | 绘图分辨率结果对光线追迹的影响
  15. 销售管理系统c语言 总结报告,C语言课程设计报告-药品销售管理系统.doc
  16. win10家庭版计算机属性里没有远程桌面,Win10家庭版本系统无法远程桌面连接的完美解决方法...
  17. sql删除元组_SQL笔记
  18. 各种字符编码与Char字符
  19. C#实现向手机发送验证码短信
  20. 读懂Wi-Fi 6:看这本白皮书就够了!(附全文下载)

热门文章

  1. Eclipse的egit插件冲突合并方法(转)
  2. 改变命运的知识,也会改变人工智能的发展轨迹?
  3. 静态链表中指针表示的是() A 内存地址 B下一元素地址 C 下一元素在数组的位置
  4. DELL R730服务器安装centos7.3教程
  5. Mongodb数据导出指定格式
  6. 我的英语学习计划(修订版2006.4.7)
  7. BZOJ1862[Zjoi2006]GameZ游戏排名系统【splay+hash】
  8. 计划任务+批处理 定时自动关机
  9. 关于ActionForward
  10. SpringCloud源码学习笔记之Eureka客户端——DiscoveryClient接口的层级结构