怎样获取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 ...
随机推荐
- Android底层开发之Linux输入子系统要不要推断系统休眠状态上报键值
Android底层开发之Linux输入子系统要不要推断系统休眠状态上报键值 题外话:一个问题研究到最后,那边记录文档的前半部分基本上都是没用的,甚至是错误的. 重点在最后,前边不过一些假想猜測. ht ...
- HttpClient FormUrlEncodedContent System.UriFormatException: 无效的 URI: URI 字符串太长问题解决方案
1.问题描述: HttpClint 使用FormUrlEncodedContent 调用接口时 报错 System.UriFormatException: 无效的 URI: URI 字符串太长: 2. ...
- Undo表空间数据文件损坏
UNDO表空间数据文件和system表空间数据文件都是数据库的关键数据文件,如果损坏会导致sql执行失败,用户无法登录,甚至实例崩溃等.同样恢复UNDO表空间数据文件也必须在数据库mount状态 ...
- loadrunne-- Analysis 分析器
本文转自:https://www.cnblogs.com/Chilam007/p/6445165.html Analysis简介 分析器就是对测试结果数据进行分析的组件,它是LR三大组件之一,保存着大 ...
- 【Codeforces Round #443 (Div. 2) B】Table Tennis
[链接] 我是链接,点我呀:) [题意] n个人站在一排. 每次第一个人和第二个人打架. 输的人跑到队列的尾巴去. 然后赢的人继续在队首.和第三个人打. 谁会先赢K次. [题解] 会发现,一轮之后就一 ...
- HDU 2587 - 很O_O的汉诺塔
看题传送门 吐槽题目 叫什么很O_O的汉诺塔我还@.@呢. 本来是想过一段时间在来写题解的,不过有人找我要. 本来排名是第8的.然后搞了半天,弄到了第五.不过代码最短~ 截止目前就9个ID过,小小的成 ...
- [TypeScript] Using Interfaces to Describe Types in TypeScript
It’s easy to pass the wrong value to a function. Typescript interfaces are great because they catch ...
- mysql快速入门 分类: B6_MYSQL 2015-04-28 14:31 284人阅读 评论(0) 收藏
debian方式: apt-get install mysql-server-5.5 mysql -u root -p redhat安装方式 一.下载并解压 $ wget http://cdn ...
- PatentTips - SNMP firewall
BACKGROUND OF THE INVENTION [0001] The present invention relates to communications and, more particu ...
- ArcGIS Spatial Query
Creates a spatial query which performs a spatial search for features in the supplied feature class a ...