怎样获取android手机联系人并按字母展示(三)
假设获取contact的头像信息并展示:
怎样依据photoId来获取bitmap:
public static Bitmap getContactPhoto(Context context, long photoId, BitmapFactory.Options options) {
if (photoId < 0) {
return null;
}
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(
ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, photoId),
new String[] { Photo.PHOTO }, null, null, null);
if (cursor != null && cursor.moveToFirst() && !cursor.isNull(0)) {
byte[] photoData = cursor.getBlob(0);
if (options == null) {
options = new BitmapFactory.Options();
}
options.inTempStorage = new byte[16 * 1024];
options.inSampleSize = 2;
return BitmapFactory.decodeByteArray(photoData, 0, photoData.length, options);
}
} catch (java.lang.Throwable error) {
} finally {
if (cursor != null) {
cursor.close();
}
}
return null;
}
在bindView中增加:
protected void setContactPhoto(Cursor cursor, final ImageView viewToUse, int column) {
long photoId = 0;
if (!cursor.isNull(column)) {
photoId = cursor.getLong(column);
}
final int position = cursor.getPosition();
viewToUse.setTag(new PhotoInfo(position, photoId));
if (photoId == 0) {
viewToUse.setImageResource(R.drawable.avatar);
} else {
Bitmap photo = null;
SoftReference<Bitmap> ref = mBitmapCache.get(photoId);
if (ref != null) {
photo = ref.get();
if (photo == null) {
mBitmapCache.remove(photoId);
}
}
if (photo != null) {
viewToUse.setImageBitmap(photo);
} else {
viewToUse.setImageResource(R.drawable.avatar);
mItemsMissingImages.add(viewToUse);
if (mScrollState != OnScrollListener.SCROLL_STATE_FLING) {
sendFetchImageMessage(viewToUse);
}
}
}
}
获取的头像的方法:
private class ImageLoaderHandler extends Handler {
@Override
public void handleMessage(Message message) {
if (isFinishing()) {
return;
}
switch (message.what) {
case FETCH_IMAGE_MSG: {
final ImageView imageView = (ImageView) message.obj;
if (imageView == null) {
break;
}
final PhotoInfo info = (PhotoInfo) imageView.getTag();
if (info == null) {
break;
}
final long photoId = info.photoId;
if (photoId == 0) {
break;
}
SoftReference<Bitmap> photoRef = mBitmapCache.get(photoId);
if (photoRef == null) {
break;
}
Bitmap photo = photoRef.get();
if (photo == null) {
mBitmapCache.remove(photoId);
break;
}
synchronized (imageView) {
final PhotoInfo updatedInfo = (PhotoInfo) imageView
.getTag();
long currentPhotoId = updatedInfo.photoId;
if (currentPhotoId == photoId) {
imageView.setImageBitmap(photo);
mItemsMissingImages.remove(imageView);
} else {
}
}
break;
}
}
}
public void clearImageFecthing() {
removeMessages(FETCH_IMAGE_MSG);
}
}
private class ImageLoader implements Runnable {
long mPhotoId;
private ImageView mImageView;
public ImageLoader(long photoId, ImageView imageView) {
this.mPhotoId = photoId;
this.mImageView = imageView;
}
public void run() {
if (isFinishing()) {
return;
}
if (Thread.interrupted()) {
return;
}
if (mPhotoId < 0) {
return;
}
Bitmap photo = ContactsUtils.getContactPhoto(getBaseContext(),
mPhotoId, null);
if (photo == null) {
return;
}
mBitmapCache.put(mPhotoId, new SoftReference<Bitmap>(photo));
if (Thread.interrupted()) {
return;
}
Message msg = new Message();
msg.what = FETCH_IMAGE_MSG;
msg.obj = mImageView;
mHandler.sendMessage(msg);
}
}
下载头像能够起线程池:
private void processMissingImageItems(AbsListView view) {
for (ImageView iv : mItemsMissingImages) {
sendFetchImageMessage(iv);
}
}
protected void sendFetchImageMessage(ImageView view) {
final PhotoInfo info = (PhotoInfo) view.getTag();
if (info == null) {
return;
}
final long photoId = info.photoId;
if (photoId == 0) {
return;
}
mImageFetcher = new ImageLoader(photoId, view);
synchronized (ContactsList.this) {
if (sImageFetchThreadPool == null) {
sImageFetchThreadPool = Executors.newFixedThreadPool(3);
}
sImageFetchThreadPool.execute(mImageFetcher);
}
}
public void clearImageFetching() {
synchronized (ContactsList.this) {
if (sImageFetchThreadPool != null) {
sImageFetchThreadPool.shutdownNow();
sImageFetchThreadPool = null;
}
}
mHandler.clearImageFecthing();
}
我们能够对下载做优化,在列表精巧的时候才去下,这个我们让adatper继承OnScrollListener,这样有两个重载函数:
<span style="white-space:pre"> </span>@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (SCROLL_STATE_TOUCH_SCROLL == scrollState) {
View currentFocus = getCurrentFocus();
if (currentFocus != null) {
currentFocus.clearFocus();
}
} mScrollState = scrollState;
if (scrollState == OnScrollListener.SCROLL_STATE_FLING) {
clearImageFetching();
} else {
processMissingImageItems(view);
}
} @Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) { }
在activity销毁的时候,我们得去释放资源:
@Override
protected void onDestroy() {
super.onDestroy(); if (mQueryHandler != null) {
mQueryHandler.cancelOperation(QUERY_TOKEN);
mQueryHandler = null;
} if (mAdapter != null && mAdapter.mItemsMissingImages != null) {
mAdapter.mItemsMissingImages.clear();
mAdapter.clearMessages();
} // Workaround for Android Issue 8488
// http://code.google.com/p/android/issues/detail?id=8488
if (mAdapter != null && mAdapter.mBitmapCache != null) {
for (SoftReference<Bitmap> bitmap : mAdapter.mBitmapCache.values()) {
if (bitmap != null && bitmap.get() != null) {
bitmap.get().recycle();
bitmap = null;
}
}
mAdapter.mBitmapCache.clear();
} }
怎样获取android手机联系人并按字母展示(三)的更多相关文章
- 怎样获取android手机联系人并按字母展示(一)
android提供了本地数据库的查询uri,能够查询出数据: 採用一个AsyncQueryHandler来进行查询, AsyncQueryHandler自己开启了线程来进行数据查询,非常方便 prot ...
- 获取android手机联系人信息
package com.yarin.android.Examples_04_04; import android.app.Activity; import android.database.Curso ...
- 获取Android 手机屏幕宽度和高度以及获取Android手机序列号
1.获取Android 手机屏幕宽度 1 DisplayMetrics dm = new DisplayMetrics(); 2 this.getWindowManager().getDefaultD ...
- 关于Android的Build类——获取Android手机设备各种信息
经常遇到要获取Android手机设备的相关信息,来进行业务的开发,比如经常会遇到要获取CPU的类型来进行so库的动态的下载.而这些都是在Android的Build类里面.相关信息如下: private ...
- Pyqt adb 获取Android手机屏幕
adb的全称为Android Debug Bridge,就是起到调试桥的作用.adb的工作方式比较特殊,采用监听Socket TCP 5554等端口的方式让IDE和Qemu通讯,默认情况下adb会da ...
- 获取android手机基本信息
/** * 获取android当前可用内存大小 */ private String getAvailMemory() {// 获取android当前可用内存大小 ActivityManager am ...
- 如何获取Android手机的唯一标识
有很多场景和需求你需要用到手机设备的唯一标识符. 在Android中,有以下几种方法获取这样的ID. 1. The IMEI: 仅仅只对Android手机有效: 1 2 TelephonyManage ...
- (转)获取android手机内部存储空间和外部存储空间的参数 && 如何决定一个apk的安装位置
转:http://blog.csdn.net/zhandoushi1982/article/details/8560233 获取android文件系统的信息,需要Environment类和StatFs ...
- 如何获得android手机通讯录的字母显示(两)
随后的写如何使各第一字母显示相同的分类触点: 于adapter implement SectionIndexer 这项adapter必须在下面可以实现3接口: @Override public Obj ...
随机推荐
- 如何在anaconda中切换python2
如果你不切换可能是默认的python3环境. 下面是在python27版本下下载qt5
- JS学习笔记 - 自定义右键菜单、文本框只能输入数字
<script> // 事件总共有2个部分, //1.点击鼠标右键的表现 oncontextmenu 2.点击鼠标左键的表现(即普通点击onclick) // 点击右键,div位置定位到鼠 ...
- 【Codeforces Round #432 (Div. 1) B】Arpa and a list of numbers
[链接]h在这里写链接 [题意] 定义bad list是一个非空的.最大公约数为1的序列.给定一个序列,有两种操作:花费x将一个元素删除.花费y将一个元素加1,问你将这个序列变为good list所需 ...
- 怎样用Adobe Acrobat 7 Pro把PDF文档拆分成多个啊?
这个pdf文档里有多篇文章,我想把他们分开并分别保存在独立的pdf文档.怎么操作?我的电脑基础不太好,麻烦说得详细一些. Adobe Acrobat 7 Pro拆分PDF文档的方法: 1.点左边的“书 ...
- 火狐与IE的7个JavaScript差异
作者注:本篇文章发表于2009.04.27,是一篇关于讨论Javascript在IE6.IE7和FF2+.FF3.0之间的存在的问题的文章. 虽然须要用冗长的JavaScript代码去识别特定的浏览器 ...
- SpringMVC实战(三种控制器方式)
1.前言 上篇博客着重说了一下SpringMVC中几种处理映射的方式,这篇博客来说一下SpringMVC中几种经常使用的控制器. 2.经常使用控制器 2.1 ParameterizableViewC ...
- mysql数据库各存储引擎比較
mysql数据库差别于其它数据库的最重要的一个特点是其插件式的表存储引擎,存储引擎是基于表的.而不是数据库 InnoDB存储引擎: 支持事务,其设计目标主要面向在线事务处理(OLTP)的 ...
- 关于db2的一点记录
近期听搞db2的兄弟说:db2数据库软件的license 不区分平台(os). 先记下来.像db2这么高大上的软件,接触的机会是比較少的. 另外:db2 的license是须要打的,不打的话,超过一段 ...
- 幻灯展示jQuery插件supersized
主要特性: 能够自动修改图片大小适合浏览器的页面大小 通过幻灯展示的循环背景可以动态加载并且可以设置变化方式 核心版本可以支持仅仅需要背景变化大小的需要 键盘导航 整合Flickr - 可以从用户,组 ...
- js课程 3-9 js内置对象定时器和超时器怎么使用
js课程 3-9 js内置对象定时器和超时器怎么使用 一.总结 一句话总结:定时器: 1.定义 sobj=setInterval(func,1000); 2.清除 cl ...