I am working on sample of calls log application. In this application my fragment displays Dialed Type calls in a list. here in each list item it shows photo from contacts, Number, name and time. It is working fine but it lags while scrolling.
fragment code:
package com.example.vl.calllogs;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.CallLog;
import android.provider.ContactsContract;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.util.Log;
import android.view.View;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.ResourceCursorAdapter;
import android.widget.TextView;
import org.w3c.dom.Text;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Created by vl on 12/29/2015.
*/
public class TabDialedFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> {
CursorAdapter mAdapter;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setEmptyText("No Dialed Numbers");
mAdapter = new MyCursorAdapter(getActivity(), R.layout.fragment_tab_dialed, null, 0);
setListAdapter(mAdapter);
getLoaderManager().initLoader(0, null, this);
}
private static final String[] PROJECTION = {
CallLog.Calls._ID,
CallLog.Calls.DATE,
CallLog.Calls.CACHED_NAME,
CallLog.Calls.CACHED_PHOTO_ID,
CallLog.Calls.NUMBER,
CallLog.Calls.DURATION
};
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
Uri baseUri = CallLog.Calls.CONTENT_URI;
String selection = CallLog.Calls.TYPE + "= 2";
return new CursorLoader(getActivity(), baseUri, PROJECTION,selection, null, CallLog.Calls.DATE + " DESC" );
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mAdapter.swapCursor(data);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
class MyCursorAdapter extends ResourceCursorAdapter{
MyCursorAdapter(Context context, int layout, Cursor cursor, int flags ){
super(context, layout,cursor,flags);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
TextView name = (TextView) view.findViewById(R.id.name);
String nameString = cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME));
if(nameString == null || "".equals(nameString.trim())){
name.setText("Unknown");
}else{
name.setText(nameString);
}
TextView time = (TextView) view.findViewById(R.id.time);
String timeS = cursor.getString(cursor.getColumnIndex(CallLog.Calls.DATE));
Date callDayTime = new Date(Long.valueOf(timeS));
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm");
String str = simpleDateFormat.format(callDayTime);
String durationS = cursor.getString(cursor.getColumnIndex(CallLog.Calls.DURATION));
time.setText(String.format(getActivity().getResources().getString(R.string.thirdLine), str, durationS));
TextView number = (TextView) view.findViewById(R.id.number);
String numberS = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER));
number.setText(numberS);
int contactID = getContactIDFromNumber(numberS);
ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
imageView.setImageBitmap(getPhoto(contactID+""));
}
public int getContactIDFromNumber(String contactNumber)
{
contactNumber = Uri.encode(contactNumber);
int phoneContactID = -1;
Cursor contactLookupCursor = getActivity().getContentResolver().query(Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,contactNumber),new String[] {ContactsContract.PhoneLookup.DISPLAY_NAME, ContactsContract.PhoneLookup._ID}, null, null, null);
while(contactLookupCursor.moveToNext()){
phoneContactID = contactLookupCursor.getInt(contactLookupCursor.getColumnIndexOrThrow(ContactsContract.PhoneLookup._ID));
}
contactLookupCursor.close();
return phoneContactID;
}
private Bitmap getPhoto(String id){
Bitmap photo = null;
try{
InputStream inputStream = ContactsContract.Contacts.openContactPhotoInputStream(
getActivity().getContentResolver(),
ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, new Long(id).longValue()));
if(inputStream != null)
photo= BitmapFactory.decodeStream(inputStream);
}catch (Exception e){
}
return photo;
}
}
}
I feel it might be the problem of in efficient way of getting photo from Contacts. here I first get the contact_id and then I queried for the photo using contact ID. Is this the correct way?
Last queries are not working asynchronously. To make async what should I do?