Android 在没有联系人图像可用时显示图像
我已经编写了一个应用程序,它可以简单地显示手机上所有可用的联系人。该应用程序运行良好。它可以检索联系人图像并显示联系人姓名。然而,在滚动列表时,应用程序有些滞后。我想知道如何消除这种滞后。同时,我想在没有联系人图像的情况下显示一个图像。我尝试创建一个布尔标志,告诉我联系人图像光标是否为空,如果为空,则我将该标志(image_found)设置为false,然后尝试使用setImageResource设置图像,但它不起作用。嗯,然后我想当没有图像的时候,blob对象可能会得到一个空值,但它也不起作用。这是我的邮件活动代码Android 在没有联系人图像可用时显示图像,android,contact,Android,Contact,我已经编写了一个应用程序,它可以简单地显示手机上所有可用的联系人。该应用程序运行良好。它可以检索联系人图像并显示联系人姓名。然而,在滚动列表时,应用程序有些滞后。我想知道如何消除这种滞后。同时,我想在没有联系人图像的情况下显示一个图像。我尝试创建一个布尔标志,告诉我联系人图像光标是否为空,如果为空,则我将该标志(image_found)设置为false,然后尝试使用setImageResource设置图像,但它不起作用。嗯,然后我想当没有图像的时候,blob对象可能会得到一个空值,但它也不起作用
package legacy_systems.aggregatedcontactlist;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.v4.widget.CursorAdapter;
import android.support.v4.widget.SimpleCursorAdapter;
import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.view.Menu;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends ListActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Cursor c = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
null,
null,
null,
ContactsContract.Contacts.DISPLAY_NAME+" ASC");
ArrayList<String> con_ids = new ArrayList<String>();
if(c!=null)
{
for(c.moveToFirst();!c.isAfterLast();c.moveToNext()){
con_ids.add(c.getString(c.getColumnIndex(ContactsContract.Contacts._ID)));
}
}
ListView ls = getListView();
MyAdapter ada = new MyAdapter(this, R.layout.listview, con_ids);
ls.setAdapter(ada);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
package legacy\u systems.aggregatedcontactlist;
导入java.util.ArrayList;
导入java.util.List;
导入android.os.Bundle;
导入android.provider.contacts合同;
导入android.support.v4.widget.CursorAdapter;
导入android.support.v4.widget.SimpleCursorAdapter;
导入android.app.ListActivity;
导入android.content.Intent;
导入android.database.Cursor;
导入android.view.Menu;
导入android.view.view;
导入android.widget.ArrayAdapter;
导入android.widget.ListView;
导入android.widget.Toast;
公共类MainActivity扩展了ListActivity{
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
游标c=getContentResolver().query(ContactsContract.Contacts.CONTENT\u URI,
无效的
无效的
无效的
Contacts contract.Contacts.DISPLAY_NAME+“ASC”);
ArrayList con_id=新的ArrayList();
如果(c!=null)
{
for(c.moveToFirst();!c.isAfterLast();c.moveToNext()){
con_ID.add(c.getString(c.getColumnIndex(ContactsContract.Contacts._ID));
}
}
ListView ls=getListView();
MyAdapter ada=新的MyAdapter(this,R.layout.listview,con_id);
ls.setAdapter(ada);
}
@凌驾
公共布尔onCreateOptions菜单(菜单){
//为菜单充气;这会将项目添加到操作栏(如果存在)。
getMenuInflater().充气(R.menu.activity\u主菜单);
返回true;
}
}
下面是MyAdapter的代码
package legacy_systems.aggregatedcontactlist;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentUris;
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class MyAdapter extends ArrayAdapter<String>{
Context cont;
boolean image_found = true;
ArrayList<String> ids;
public MyAdapter(Context context, int resource,
ArrayList<String> objects) {
super(context, resource, objects);
cont = context;
ids = objects;
// TODO Auto-generated constructor stub
}
public View getView(int position, View ConvertView, ViewGroup parent){
//For Contact Photo
Bitmap photo=null;
//Inflator Work
LayoutInflater infl = (LayoutInflater)cont.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = infl.inflate(R.layout.list_view, parent, false);
//Retreiving photo and Setting Photo
photo = BitmapFactory.decodeStream(retrievePhoto(ids.get(position)));
ImageView iv = (ImageView)row.findViewById(R.id.listicon);
iv.setImageBitmap(photo);
if(!image_found)
{
iv.setImageResource(R.drawable.person);
}
//Retrieving ContactName
TextView tv =(TextView)row.findViewById(R.id.listtext);
tv.setText(retrieveName(ids.get(position)));
return row;
}
private InputStream retrievePhoto(String Id)
{
Uri ContactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.valueOf(Id));
Uri PhotoUri = Uri.withAppendedPath(ContactUri, Contacts.Photo.CONTENT_DIRECTORY);
Cursor c = cont.getContentResolver().query(PhotoUri, new String[]{Contacts.Photo.PHOTO}, null,null,null);
try
{
if(c.moveToFirst())
{
byte[] data = c.getBlob(0);
if(data!=null)
{
return new ByteArrayInputStream(data);
}
else
{
image_found = false;
}
}
}
finally
{
c.close();
}
return null;
}
private String retrieveName(String Id)
{
Uri ContactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.valueOf(Id));
Cursor c = cont.getContentResolver()
.query(ContactUri,
new String[]{ContactsContract.Contacts.DISPLAY_NAME},
null,
null,
null);
if(c==null)
return null;
try
{
if(c.moveToFirst())
{
String name = c.getString(0);
return name;
}
}
finally
{
c.close();
}
return null;
}
}
package legacy\u systems.aggregatedcontactlist;
导入java.io.ByteArrayInputStream;
导入java.io.InputStream;
导入java.util.ArrayList;
导入java.util.List;
导入android.content.ContentUris;
导入android.content.Context;
导入android.content.pm.PackageManager.NameNotFoundException;
导入android.database.Cursor;
导入android.graphics.Bitmap;
导入android.graphics.BitmapFactory;
导入android.net.Uri;
导入android.provider.contacts合同;
导入android.provider.Contacts contract.Contacts;
导入android.view.LayoutInflater;
导入android.view.view;
导入android.view.ViewGroup;
导入android.widget.ArrayAdapter;
导入android.widget.ImageView;
导入android.widget.TextView;
公共类MyAdapter扩展了ArrayAdapter{
语境控制;
布尔图像_found=true;
数组列表ID;
公共MyAdapter(上下文、int资源、,
ArrayList对象){
超级(上下文、资源、对象);
cont=上下文;
ids=对象;
//TODO自动生成的构造函数存根
}
公共视图getView(int位置、视图转换视图、视图组父视图){
//联系照片
位图照片=空;
//充气机工作
LayoutInflater infl=(LayoutInflater)cont.getSystemService(Context.LAYOUT\u INFLATER\u SERVICE);
视图行=内部充气(R.layout.list\u视图,父视图,false);
//检索照片和设置照片
photo=BitmapFactory.decodeStream(retrievePhoto(id.get(position));
ImageView iv=(ImageView)row.findViewById(R.id.listicon);
iv.设置图像位图(照片);
如果(!找到图像)
{
iv.setImageResource(R.drawable.person);
}
//检索联系人姓名
TextView tv=(TextView)row.findViewById(R.id.listtext);
tv.setText(retrieveName(id.get(position));
返回行;
}
私有InputStream retrievePhoto(字符串Id)
{
Uri ContactUri=ContentUris.withAppendedId(Contacts.CONTENT_Uri,Long.valueOf(Id));
Uri PhotoUri=Uri.withAppendedPath(ContactUri,Contacts.Photo.CONTENT\u目录);
游标c=cont.getContentResolver().query(PhotoUri,新字符串[]{Contacts.Photo.Photo},null,null,null);
尝试
{
if(c.moveToFirst())
{
字节[]数据=c.getBlob(0);
如果(数据!=null)
{
返回新的ByteArrayInputStream(数据);
}
其他的
{
图像_found=false;
}
}
}
最后
{
c、 close();
}
返回null;
}
私有字符串检索名称(字符串Id)
{
Uri ContactUri=ContentUris.withAppendedId(Contacts.CONTENT_Uri,Long.valueOf(Id));
游标c=cont.getContentResolver()
.query(ContactUri,
新字符串[]{Contacts contract.Contacts.DISPLAY_NAME},
无效的
无效的
无效);
如果(c==null)
返回null;
尝试
{
if(c.moveToFirst())
{
String name=c.getString(0);
返回名称;
}
}
最后
{
c、 close();
}
返回null;
}
}
我真的很高兴我走了这么远。请帮我继续我的冒险
[编辑]
我已落实建议的措施
package legacy_systems.aggregatedcontactlist;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentUris;
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class MyAdapter extends ArrayAdapter<String>{
Context cont;
boolean image_found = true;
ArrayList<String> ids;
public MyAdapter(Context context, int resource,
ArrayList<String> objects) {
super(context, resource, objects);
cont = context;
ids = objects;
// TODO Auto-generated constructor stub
}
public View getView(int position, View ConvertView, ViewGroup parent){
View row = ConvertView;
//For Contact Photo
Bitmap photo=null;
//Inflator Work
if(row==null)
{
LayoutInflater infl = (LayoutInflater)cont.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = infl.inflate(R.layout.list_view, parent, false);
}
//Retreiving photo and Setting Photo
ImageView iv = (ImageView)row.findViewById(R.id.listicon);
synchronized (iv) {
Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.valueOf(ids.get(position)));
PhotoLoader loader = new PhotoLoader(iv, contactUri);
loader.execute();
}
//Retrieving ContactName
TextView tv =(TextView)row.findViewById(R.id.listtext);
tv.setText(retrieveName(ids.get(position)));
return row;
}
private String retrieveName(String Id)
{
Uri ContactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.valueOf(Id));
Cursor c = cont.getContentResolver()
.query(ContactUri,
new String[]{ContactsContract.Contacts.DISPLAY_NAME},
null,
null,
null);
if(c==null)
return null;
try
{
if(c.moveToFirst())
{
String name = c.getString(0);
return name;
}
}
finally
{
c.close();
}
return null;
}
class PhotoLoader extends AsyncTask<Void, Void, Bitmap>
{
final WeakReference<ImageView> mView;
final Uri mUri;
public PhotoLoader(ImageView view, Uri uri) {
if(view == null)
{
throw new IllegalArgumentException("View Cannot be null");
}
if(uri == null)
{
throw new IllegalArgumentException("Uri cant be null");
}
mView = new WeakReference<ImageView>(view);
mUri = uri;
}
protected Bitmap doInBackground(Void...args){
Bitmap bitmap;
InputStream in = ContactsContract.Contacts.openContactPhotoInputStream(cont.getContentResolver(), mUri);
bitmap = BitmapFactory.decodeStream(in);
if(bitmap == null)
{ Resources mResources = cont.getResources();
bitmap = BitmapFactory.decodeResource(mResources, R.drawable.person);
}
return bitmap;
}
}
}
package legacy_systems.aggregatedcontactlist;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentUris;
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class MyAdapter extends ArrayAdapter<String>{
Context cont;
boolean image_found = true;
ArrayList<String> ids;
ImageView iv;
public MyAdapter(Context context, int resource,
ArrayList<String> objects) {
super(context, resource, objects);
cont = context;
ids = objects;
// TODO Auto-generated constructor stub
}
public View getView(int position, View ConvertView, ViewGroup parent){
View row = ConvertView;
//For Contact Photo
//Inflator Work
if(row==null)
{
LayoutInflater infl = (LayoutInflater)cont.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = infl.inflate(R.layout.list_view, parent, false);
}
//Retreiving photo and Setting Photo
iv = (ImageView)row.findViewById(R.id.listicon);
synchronized (this) {
Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.valueOf(ids.get(position)));
PhotoLoader loader = new PhotoLoader(iv, contactUri);
loader.execute();
}
//Retrieving ContactName
TextView tv =(TextView)row.findViewById(R.id.listtext);
tv.setText(retrieveName(ids.get(position)));
return row;
}
private String retrieveName(String Id)
{
Uri ContactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.valueOf(Id));
Cursor c = cont.getContentResolver()
.query(ContactUri,
new String[]{ContactsContract.Contacts.DISPLAY_NAME},
null,
null,
null);
if(c==null)
return null;
try
{
if(c.moveToFirst())
{
String name = c.getString(0);
return name;
}
}
finally
{
c.close();
}
return null;
}
class PhotoLoader extends AsyncTask<Void, Void, Bitmap>
{
final WeakReference<ImageView> mView;
final Uri mUri;
public PhotoLoader(ImageView view, Uri uri) {
if(view == null)
{
throw new IllegalArgumentException("View Cannot be null");
}
if(uri == null)
{
throw new IllegalArgumentException("Uri cant be null");
}
mView = new WeakReference<ImageView>(view);
mUri = uri;
}
protected Bitmap doInBackground(Void...args){
Bitmap bitmap;
InputStream in = ContactsContract.Contacts.openContactPhotoInputStream(cont.getContentResolver(), mUri);
bitmap = BitmapFactory.decodeStream(in);
return bitmap;
}
protected void onPostExecute(Bitmap bitmap)
{
if(bitmap == null)
{ Resources mResources = cont.getResources();
bitmap = BitmapFactory.decodeResource(mResources, R.drawable.person);
iv.setImageBitmap(bitmap);
return;
}
iv.setImageBitmap(bitmap);
}
}
}
class PhotoLoader extends AsyncTask<Void, Void, Bitmap> {
final WeakReference<ImageView> mView;
final Uri mUri;
PhotoLoader(ImageView view, Uri uri) {
if (view == null) {
throw new IllegalArgumentException("View cannot be null!");
}
if (uri == null) {
throw new IllegalArgumentException("Uri cannot be null!");
}
mView = new WeakReference<ImageView>(view);
mUri = uri;
}
@Override
protected Bitmap doInBackground(Void... args) {
// use the uri passed to the constructor
InputStream is = Contacts.openContactPhotoInputStream(mResolver,
mUri);
Bitmap bm = BitmapFactory.decodeStream(is);
// load custom resource image if contact has no photo
if (bm == null) {
bm = BitmapFactory.decodeResource(mResources,
R.drawable.ic_contact);
}
return bm;
}
@Override
protected void onPostExecute(Bitmap result) {
// use a transition drawable for nice fade effect
Drawable[] layers = new Drawable[2];
layers[0] = mResources.getDrawable(android.R.color.transparent);
layers[1] = new BitmapDrawable(mResources, result);
TransitionDrawable t = new TransitionDrawable(layers);
t.setCrossFadeEnabled(true);
ImageView view = mView.get();
if(view != null) {
view.setImageDrawable(t);
t.startTransition(mShortAnimation);
}
synchronized (mPhotoCache) {
// store bitmap in LruCache for later use...
mPhotoCache.put(mUri.toString(), result);
}
}
}
synchronized (mPhotoCache) {
Bitmap b = mPhotoCache.get(key);
if (b != null) {
imageView.setImageBitmap(b);
} else {
imageView.setImageResource(android.R.color.transparent);
PhotoLoader loader = new PhotoLoader(imageView, uri);
loader.execute();
}
}
package com.example.contact;
import java.io.InputStream;
import java.util.ArrayList;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.support.v4.util.LruCache;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.View;
import android.widget.ImageView;
public class MyAdapter extends SimpleCursorAdapter{
private Cursor cursor;
private static int con_id_index;
private static Drawable person;
private Context context;
private static LruCache<Long, Bitmap> cache;
long con_id;
private ArrayList<Long> id_list = new ArrayList<Long>();
public MyAdapter(Context context, int layout, Cursor c, String[] from,
int[] to, int flags) {
super(context, layout, c, from, to, flags);
this.cursor = c;
con_id_index = cursor.getColumnIndex(ContactsContract.Contacts._ID);
person = context.getResources().getDrawable(R.drawable.person);
this.context = context;
final int maxMem = (int)Runtime.getRuntime().maxMemory()/1024;
final int cacheSize = maxMem/8;
cache = new LruCache<Long, Bitmap>(cacheSize);
id_list.clear();
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
Object tag;
// TODO Auto-generated method stub
super.bindView(view, context, cursor);
con_id = cursor.getLong(con_id_index);
if(!id_list.contains(Long.valueOf(con_id)))
{
id_list.add(con_id);
}
Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, con_id);
ImageView con_image = (ImageView) view.findViewById(R.id.contact_iamge);
tag = con_id;
con_image.setImageDrawable(person);
con_image.setTag(tag);
if(getBitmapFromCache(con_id)!=null)
{
con_image.setImageBitmap(getBitmapFromCache(con_id));
}
else
{
ImageLoader loader = new ImageLoader(con_image, contactUri, con_id);
loader.execute();
}
}
class ImageLoader extends AsyncTask<Void, Void, Bitmap>
{
private ImageView mView;
private Uri mUri;
private Object tag;
private long position;
public ImageLoader(ImageView view, Uri uri, long position) {
if(view == null)
{
throw new IllegalArgumentException("View Cannot be null");
}
if(uri == null)
{
throw new IllegalArgumentException("Uri cant be null");
}
mView = view;
tag = mView.getTag();
this.position = position;
mUri = uri;
}
protected Bitmap doInBackground(Void...args){
Bitmap bitmap;
//Load image from the Content Provider
InputStream in = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(), mUri);
bitmap = BitmapFactory.decodeStream(in);
return bitmap;
}
protected void onPostExecute(Bitmap bitmap)
{
//If is in somewhere else, do not temper
if(!mView.getTag().equals(tag))
return;
//If no image was there and do not put it to cache
if(bitmap!= null)
{
mView.setImageBitmap(bitmap);
addBitmapToCache(position, bitmap);
return;
}
//Otherwise, welcome to cache
return;
}
}
/**Add image to cache*/
private void addBitmapToCache(Long key, Bitmap bitmap)
{
if(getBitmapFromCache(key)==null)
{
cache.put(key, bitmap);
}
}
/**Retrive image from cache*/
private Bitmap getBitmapFromCache(Long key)
{
return cache.get(key);
}
public ArrayList<Long> getIDList()
{
return id_list;
}
}