電話で利用可能なすべての連絡先を表示するだけのアプリを作成しました。アプリは正常に動作しています。連絡先の画像とdisplay_nameを取得できます。ただし、リストをスクロールすると、アプリは多少遅れます。このラグを取り除く方法を知りたいです。同時に、連絡先の画像がないときに画像を表示したい。連絡先画像カーソルがnullかどうかを示すブールフラグを作成しようとしました。nullの場合は、フラグ(image_found)をfalseにして、setImageResourceを使用して画像を設定しようとしましたが、機能しませんでした。それでは、画像がない場合にblobオブジェクトがnullになる可能性があると思いましたが、それも機能しました。これがmail_activityの私のコードです。
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;
}
}
そしてここに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;
}
}
ここまで行って本当に嬉しいです。私の冒険を続けるのを手伝ってください。
[編集]提案されたものを実装しましたが、1つの連絡先画像を取得できなくなりました。何が問題なのかわかりません。MyAdapter.javaでのみ変更を加え、そのコードを投稿しています。
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);
}
}
}