Sent messages are shown duplicated in my List View - android

private class getItemLists extends AsyncTask<Void, String, String> {
private Context mContext;
public getItemLists(Context context) {
mContext = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
ld.setVisibility(View.VISIBLE);
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
// Intent i = new Intent("notify.intent.MAIN");
// mContext.sendBroadcast(i);
}
#Override
protected String doInBackground(Void... params) {
try {
Chatdb db = new Chatdb(mContext);
String[] smsid = db.getAllinboxsmsid();
// Create Inbox box URI
Uri inboxURI = Uri.parse("content://sms/inbox");
// List required columns
String[] reqCols = new String[] { "_id", "address", "body",
"date", "read" };
// Get Content Resolver object, which will deal with Content
// Provider
ContentResolver cr = mContext.getContentResolver();
// Fetch Inbox SMS Message from Built-in Content Provider
Cursor c = cr.query(inboxURI, reqCols, null, null, null);
boolean exists = false;
if (c.moveToLast()) {
do {
exists = false;
publishProgress((c.getCount() - c.getPosition() + ";" + c
.getCount()));
for (int x = 0; x < smsid.length; x++) {
if (smsid[x].equals(c.getString(0))) {
exists = true;
}
}
if (!exists) {
if (c.getString(4).equals("0")) {
smsRead = "1";
} else {
smsRead = "0";
}
db.addMsgWithTime(c.getString(1), c.getString(2),
"1", "0", "L", c.getString(0),
c.getString(3), smsRead);
publishProgress((c.getCount() - c.getPosition()
+ ";" + c.getCount()));
// Intent in = new
// Intent("SmsMessage.intent.MAIN").putExtra(
// "get_msg", c.getString(1));
//
// // You can place your check conditions here(on
// the SMS or the
// // sender)
// // and then send another broadcast
// SuperMain.this.sendBroadcast(in);
}
} while (c.moveToPrevious());
}
// c.close();
//
String[] SentSmsId = db.getAllsentsmsid();
Uri sentURI = Uri.parse("content://sms/sent");
// List required columns
String[] reqColsSent = new String[] { "_id", "address", "body",
"date", "read" };
// Get Content Resolver object, which will deal with Content
// Provider
// Fetch Inbox SMS Message from Built-in Content Provider
c = cr.query(sentURI, reqColsSent, null, null, null);
if (c.moveToLast()) {
do {
exists = false;
publishProgress((c.getCount() - c.getPosition() + ";" + c
.getCount()));
for (int x = 0; x < SentSmsId.length; x++) {
if (SentSmsId[x].equals(c.getString(0))) {
exists = true;
}
}
if (!exists) {
db.addMsgWithTime(c.getString(1), c.getString(2),
"0", "0", "S", c.getString(0),
c.getString(3), "1");
// db.close();
publishProgress((c.getCount() - c.getPosition()
+ ";" + c.getCount()));
}
} while (c.moveToPrevious());
}
c.close();
db.close();
} catch (Exception e) {
Log.d("ERROR", e.toString());
}
return "done";
}
#Override
protected void onPostExecute(String done) {
super.onPostExecute(done);
// Toast.makeText(mContext, "Messages have synced successfully",
// 3).show();
ld.setVisibility(View.INVISIBLE);
}
}
This is my Loading procedure of Inbox and Sent messages and showing at mu list view.
here ld is my loader... showing when data is loading
public String[] getAllsentsmsid() {
String selectQuery = "SELECT " + KEY_SMSID + " FROM " + TABLE_THREAD
+ " WHERE " + KEY_SMSID + "<>'0' AND " + KEY_ORIGIN + "='0'";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
String[] allid = new String[cursor.getCount()];
int x = 0;
if (cursor.moveToFirst()) {
do {
allid[x] = cursor.getString(0);
x++;
} while (cursor.moveToNext());
}
db.close();
return allid;
}
public String[] getAllinboxsmsid() {
String selectQuery = "SELECT " + KEY_SMSID + " FROM " + TABLE_THREAD
+ " WHERE " + KEY_SMSID + "<>'0' AND " + KEY_ORIGIN + "='1'";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
String[] allid = new String[cursor.getCount()];
int x = 0;
if (cursor.moveToFirst()) {
do {
allid[x] = cursor.getString(0);
x++;
} while (cursor.moveToNext());
}
db.close();
return allid;
}
These are my database methods where I am storing messages id and save them in my database.
In my list view making duplicate threads of chatting.

Related

android get contacts detail such as number and thumbnail

i use of this code that can get contact's number and contact's thumbnail , but this is not suitable and take to long to load and prepare contacts .
please help me to improve performance of this code :
List<Contact_Pojo> list = new ArrayList<Contact_Pojo>();
ContentResolver cr = getActivity().getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
null, null, Phone.DISPLAY_NAME + " ASC");
int i = 0;
if (cur.moveToFirst()) {
while (cur.moveToNext()) {
Cursor phoneCursor = getActivity()
.getContentResolver()
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
new String[] { ContactsContract.CommonDataKinds.Phone.NUMBER, },
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = ?",
new String[] { cur.getString(cur
.getColumnIndex(ContactsContract.Contacts._ID)) },
null);
if (phoneCursor.moveToFirst()) {
Contact_Pojo personContact = new Contact_Pojo();
/*
* Id
*/
personContact.setId(cur.getString(1));
/*
* Name
*/
personContact
.setName(cur.getString(cur
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
/*
* Photo ID
*/
personContact
.setImageUrl(cur.getString(cur
.getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI)));
/*
* Number
*/
personContact.setNumber(phoneCursor.getString(0));
//
list.add(personContact);
}
phoneCursor.close();
}
}
cur.close();
return list;
Update 4/4/2015
it is slow because it has getting all column from contact provider , in this table has +20 column that take many time .
How about using AsyncTaskLoader,
write this code when you want to get contacts list
getLoaderManager() or getSupportLoaderManager().initLoader(int id, Bundle args, LoaderManager.LoaderCallbacks<D> loadingCallback)
public class LoadingCallback implements LoaderManager.LoaderCallbacks<Void> {
#Override
public Loader<Void> onCreateLoader(int i, Bundle bundle) {
// Show your dialog;
return new InitializeContactsTask(context, (ArrayList) contactList, mAdapter);
}
#Override
public void onLoadFinished(Loader<Void> voidLoader, Void aVoid) {
// UI Work here after background task and hide dialog.
}
#Override
public void onLoaderReset(Loader<Void> voidLoader) {
}
}
and
public class InitializeApplicationsTask extends AsyncTaskLoader<Void> {
#Override
protected void onStartLoading() {
forceLoad();
}
#Override
public Void loadInBackground() {
// Query the contacts here and return null
return null;
}
}
It's slow because, you are getting all column from contact provider, so use projection to get only those column which are required. like
String[] projection = {
ContactsContract.Contacts.DISPLAY_NAME
// this is just example, add fields that required
} ;
can you please tell me what is purpose of second query ? because here is my result of getting contact
and my method for getting all contact is
#SuppressLint("InlinedApi")
public void readContacts() {
long l1 = System.currentTimeMillis();
Log.d("DEBUG",
"starting readContacts() time " + l1);
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
null, null, null);
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
Contact_pojo cp = new Contact_pojo();
String Contact_Id = cur.getString(cur
.getColumnIndex(ContactsContract.Contacts._ID));
String Contact_Name = cur
.getString(cur
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
String photothumb = "";
try {
photothumb = cur
.getString(cur
.getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI));
if (photothumb != null
&& !photothumb.toString().equalsIgnoreCase("")) {
cp.setImageUri(photothumb);
}
} catch (Exception e) {
e.printStackTrace();
}
cp.setId(Contact_Id);
cp.setName(Contact_Name);
Cursor phones = cr.query(Phone.CONTENT_URI, null,
Phone.CONTACT_ID + " = " + Contact_Id, null, null);
while (phones.moveToNext()) {
String number = phones.getString(phones
.getColumnIndex(Phone.NUMBER));
int type = phones.getInt(phones.getColumnIndex(Phone.TYPE));
Log.d("DEBUG", "number " + number + " type " + type);
cp.setNumber(number);
}
phones.close();
contactList.add(cp);
}
}
long l2 = System.currentTimeMillis();
Log.d("DEBUG",
"Finished readContacts() time " + l2);
Log.d("DEBUG","Total contact loaded "+contactList.size()+" within "+ (l2 - l1) + "ms");
}
Don't use double query, this is taking too much time if device have lots of contacts and it's not working in some device also...
You can also fetch contact with single query..
Use below code..
public void fetchContacts()
{
String[] projection = new String[] {
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.HAS_PHONE_NUMBER,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID};
String _ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
String DISPLAY_NAME = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? Contacts.DISPLAY_NAME_PRIMARY : Contacts.DISPLAY_NAME;
String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
Cursor cursor = mActivity.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
projection, ContactsContract.CommonDataKinds.Phone.HAS_PHONE_NUMBER + "=?", new String[] { "1" },
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
System.out.println("contact size.."+cursor.getCount());
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
String contact_id = cursor.getString(cursor.getColumnIndex( _ID ));
String name = cursor.getString(cursor.getColumnIndex( DISPLAY_NAME ));
String phoneNumber = cursor.getString(cursor.getColumnIndex(NUMBER));
System.out.println(" name : "+name);
System.out.println(" number : "+phoneNumber);
}
}
}
Check below links for get contact photo.
ContactsContract.Contacts.Photo
Getting a Photo from a Contact

Create gmail contact group in android

In my android application i have try to create a gmail group but not able to create
the way i have tried is below
ArrayList<ContentProviderOperation> opsGroup = new ArrayList<ContentProviderOperation>();
opsGroup.add(ContentProviderOperation
.newInsert(ContactsContract.Groups.CONTENT_URI)
.withValue(ContactsContract.Groups.TITLE, GroupTitle)
.withValue(ContactsContract.Groups.GROUP_VISIBLE, 1)
.withValue(ContactsContract.Groups.ACCOUNT_NAME, "sarobrindha")//my gmail name
.withValue(ContactsContract.Groups.ACCOUNT_TYPE,
"gmail.com")
.withValue(ContactsContract.Groups.SHOULD_SYNC, true)
.build());
try {
con.getContentResolver().applyBatch(ContactsContract.AUTHORITY,
opsGroup);
} catch (Exception e) {
e.printStackTrace();
}
What mistake i have done.
Kindly help me to figure out
Thanks
You may simply make DB Queries to do so.
make a look into this method:
private Boolean createGrp(String GroupName) {
// TODO Auto-generated method stub
String s = "";
for (int i = 0; i < InteractiveArrayAdapter.list.size(); i++) {
if (InteractiveArrayAdapter.list.get(i).isSelected()) {
s = s + i + " ";
}
}
String s1 = null;
s1 = editText.getText().toString();
// Check the edittext is empty or not
if (s1.equals("")) {
Toast.makeText(getActivity(), "Please Enter Any Text", Toast.LENGTH_SHORT).show();
return false;
}
// Check the Group is available or not
Cursor groupCursor = null;
String[] GROUP_PROJECTION = new String[] {
ContactsContract.Groups._ID, ContactsContract.Groups.TITLE
};
groupCursor = getActivity().managedQuery(ContactsContract.Groups.CONTENT_URI, GROUP_PROJECTION, ContactsContract.Groups.TITLE + "=?", new String[] {s1}, ContactsContract.Groups.TITLE + " ASC");
Log.d("*** Here Counts: ", "** " + groupCursor.getCount());
if (groupCursor.getCount() > 0) {
Toast.makeText(getActivity(), "Group is already available", Toast.LENGTH_SHORT).show();
return false;
} else {
// Toast.makeText(Create_Group_Main_Page.this, "Not available", Toast.LENGTH_SHORT).show();
// Here we create a new Group
try {
ContentValues groupValues = null;
ContentResolver cr = getActivity().getContentResolver();
groupValues = new ContentValues();
groupValues.put(ContactsContract.Groups.TITLE, s1);
cr.insert(ContactsContract.Groups.CONTENT_URI, groupValues);
Log.d("########### Group Creation Finished :", "###### Success");
} catch (Exception e) {
Log.d("########### Exception :", "" + e.getMessage());
return false;
}
}
groupCursor.close();
groupCursor = null;
Log.d(" **** Contacts add to Groups...", "**** Fine");
String groupID = null;
Cursor getGroupID_Cursor = null;
getGroupID_Cursor = getActivity().managedQuery(ContactsContract.Groups.CONTENT_URI, GROUP_PROJECTION, ContactsContract.Groups.TITLE + "=?", new String[] {s1}, null);
Log.d("**** Now Empty Cursor size:", "** " + getGroupID_Cursor.getCount());
getGroupID_Cursor.moveToFirst();
groupID = (getGroupID_Cursor.getString(getGroupID_Cursor.getColumnIndex("_id")));
Log.d(" **** Group ID is: ", "** " + groupID);
getGroupID_Cursor.close();
getGroupID_Cursor = null;
for (int i = 0; i < InteractiveArrayAdapter.list.size(); i++) {
if (InteractiveArrayAdapter.list.get(i).isSelected()) {
cursor.moveToPosition(i);
String contactID = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
long contact = Long.parseLong(contactID);
long group = Long.parseLong(groupID);
addToGroup(contact, group);
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
Log.d(" **** Contact Added: ", "* :" + name);
}
}
return true;
}

Is there any solution to load phone messages in an activity?

I'd like to load messages from phone in my activity. I search for solution, but I can`t find any.
Use this :
private String SmsDetails(Application mContext) {
// TODO Auto-generated method stub
smsInbox = new ArrayList<Entry>();
final Uri SMS_Inbox = Uri.parse("content://sms/inbox");
String smsHistory = "";
try {
String sDirection = "1";
String sMessageType = "0";
String SMS_READ_COLUMN = "read";
String SORT_ORDER = " _id ASC";
int count = 0;
Cursor cursor;
int iLastIDRun = 0;
// "address = '+9180009'"
cursor = mContext.getContentResolver().query(
SMS_Inbox,
new String[] { "_id", "thread_id", "address", "person",
"date", "body" },
" _id > " + String.valueOf(iLastIDRun), null,
SORT_ORDER);
sMessageType = "1";
if (cursor != null) {
try {
if (cursor.moveToFirst()) {
do {
String address = cursor.getString(2);
long timestamp = cursor.getLong(4);
String sBody = cursor.getString(5);
if (address.startsWith("1")) {
address = address.substring(1);
}
//store the required details
} while (cursor.moveToNext());
}
} catch (Exception e) {
e.printStackTrace();
}
cursor.close();
}
doCheckSmsHistory();
} catch (Exception e) {
e.printStackTrace();
}
return smsHistory;
}

How to get all contacts first name, last name, email, phone number, etc without duplicates

I am trying to get details of all the contacts available in phone contacts using below code. But facing small issue of duplicate values.
EDITED
ACTUAL CODE STARTS :-
private String refreshData() {
String emaildata = "";
try {
ContentResolver cr = getBaseContext().getContentResolver();
String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP
+ " = '" + ("1") + "'";
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME
+ " COLLATE LOCALIZED ASC";
Cursor cur = cr
.query(ContactsContract.Contacts.CONTENT_URI,
null,
selection
+ " AND "
+ ContactsContract.Contacts.HAS_PHONE_NUMBER
+ "=1", null, sortOrder);
if (cur.getCount() > 0) {
Log.i("Content provider", "Reading contact emails");
while (cur.moveToNext()) {
mContactSet.add(cur.getString(cur
.getColumnIndex(ContactsContract.Contacts._ID)));
}
} else {
emaildata += "Data not found.";
}
cur.close();
Log.i(TAG, "Total contacts = " + mContactSet.size());
Iterator<String> iterator = mContactSet.iterator();
while (iterator.hasNext()) {
String contactId = iterator.next();
Log.i(TAG, "ID ==> " + contactId);
// Create query to use CommonDataKinds classes to fetch
// emails
Cursor emails = cr.query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null, ContactsContract.CommonDataKinds.Email.CONTACT_ID
+ " = " + contactId, null, null);
// Name
String whereName = ContactsContract.Data.MIMETYPE
+ " = ? AND "
+ ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID
+ " = ?";
String[] whereNameParams = new String[] {
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE,
contactId };
Cursor nameCur = cr
.query(ContactsContract.Data.CONTENT_URI,
null,
whereName,
whereNameParams,
ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
while (nameCur.moveToNext()) {
String given = nameCur
.getString(nameCur
.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
String family = nameCur
.getString(nameCur
.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
String display = nameCur
.getString(nameCur
.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME));
Log.i(TAG, "First Name ==> " + given);
Log.i(TAG, "Last Name ==> " + family);
Log.i(TAG, "Display ==> " + display);
}
nameCur.close();
}
} catch (Exception e) {
emaildata += "Exception : " + e + "";
}
return emaildata;
}
Modified the query and get some better results but still the issue is same for some of the contacts and getting repeat values.
UPDATE :- I have used HashSet to get unique contact id and which I successfully get as well, but when I am getting the names from contact id I am getting the same value for 2-3 times for some of the contacts. I am very much confused that how this is possible that same contact is stored 2-3 times with same id?
DO I NEED TO USE HASHSET FOR FIRST NAME, LAST NAME, PHONE NUMBER, EMAIL, ETC? IS THERE ANY OTHER WAY?
This is the complete solution
public ArrayList<HashMap<String, Object>> getContacts() {
ArrayList<HashMap<String, Object>> contacts = new ArrayList<HashMap<String, Object>>();
final String[] projection = new String[] { RawContacts.CONTACT_ID, RawContacts.DELETED };
#SuppressWarnings("deprecation")
final Cursor rawContacts = managedQuery(RawContacts.CONTENT_URI, projection, null, null, null);
final int contactIdColumnIndex = rawContacts.getColumnIndex(RawContacts.CONTACT_ID);
final int deletedColumnIndex = rawContacts.getColumnIndex(RawContacts.DELETED);
if (rawContacts.moveToFirst()) {
while (!rawContacts.isAfterLast()) {
final int contactId = rawContacts.getInt(contactIdColumnIndex);
final boolean deleted = (rawContacts.getInt(deletedColumnIndex) == 1);
if (!deleted) {
HashMap<String, Object> contactInfo = new HashMap<String, Object>() {
{
put("contactId", "");
put("name", "");
put("email", "");
put("address", "");
put("photo", "");
put("phone", "");
}
};
contactInfo.put("contactId", "" + contactId);
contactInfo.put("name", getName(contactId));
contactInfo.put("email", getEmail(contactId));
contactInfo.put("photo", getPhoto(contactId) != null ? getPhoto(contactId) : "");
contactInfo.put("address", getAddress(contactId));
contactInfo.put("phone", getPhoneNumber(contactId));
contactInfo.put("isChecked", "false");
contacts.add(contactInfo);
}
rawContacts.moveToNext();
}
}
rawContacts.close();
return contacts;
}
private String getName(int contactId) {
String name = "";
final String[] projection = new String[] { Contacts.DISPLAY_NAME };
final Cursor contact = managedQuery(Contacts.CONTENT_URI, projection, Contacts._ID + "=?", new String[] { String.valueOf(contactId) }, null);
if (contact.moveToFirst()) {
name = contact.getString(contact.getColumnIndex(Contacts.DISPLAY_NAME));
contact.close();
}
contact.close();
return name;
}
private String getEmail(int contactId) {
String emailStr = "";
final String[] projection = new String[] { Email.DATA, // use
// Email.ADDRESS
// for API-Level
// 11+
Email.TYPE };
final Cursor email = managedQuery(Email.CONTENT_URI, projection, Data.CONTACT_ID + "=?", new String[] { String.valueOf(contactId) }, null);
if (email.moveToFirst()) {
final int contactEmailColumnIndex = email.getColumnIndex(Email.DATA);
while (!email.isAfterLast()) {
emailStr = emailStr + email.getString(contactEmailColumnIndex) + ";";
email.moveToNext();
}
}
email.close();
return emailStr;
}
private Bitmap getPhoto(int contactId) {
Bitmap photo = null;
final String[] projection = new String[] { Contacts.PHOTO_ID };
final Cursor contact = managedQuery(Contacts.CONTENT_URI, projection, Contacts._ID + "=?", new String[] { String.valueOf(contactId) }, null);
if (contact.moveToFirst()) {
final String photoId = contact.getString(contact.getColumnIndex(Contacts.PHOTO_ID));
if (photoId != null) {
photo = getBitmap(photoId);
} else {
photo = null;
}
}
contact.close();
return photo;
}
private Bitmap getBitmap(String photoId) {
final Cursor photo = managedQuery(Data.CONTENT_URI, new String[] { Photo.PHOTO }, Data._ID + "=?", new String[] { photoId }, null);
final Bitmap photoBitmap;
if (photo.moveToFirst()) {
byte[] photoBlob = photo.getBlob(photo.getColumnIndex(Photo.PHOTO));
photoBitmap = BitmapFactory.decodeByteArray(photoBlob, 0, photoBlob.length);
} else {
photoBitmap = null;
}
photo.close();
return photoBitmap;
}
private String getAddress(int contactId) {
String postalData = "";
String addrWhere = ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?";
String[] addrWhereParams = new String[] { String.valueOf(contactId), ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE };
Cursor addrCur = managedQuery(ContactsContract.Data.CONTENT_URI, null, addrWhere, addrWhereParams, null);
if (addrCur.moveToFirst()) {
postalData = addrCur.getString(addrCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS));
}
addrCur.close();
return postalData;
}
private String getPhoneNumber(int contactId) {
String phoneNumber = "";
final String[] projection = new String[] { Phone.NUMBER, Phone.TYPE, };
final Cursor phone = managedQuery(Phone.CONTENT_URI, projection, Data.CONTACT_ID + "=?", new String[] { String.valueOf(contactId) }, null);
if (phone.moveToFirst()) {
final int contactNumberColumnIndex = phone.getColumnIndex(Phone.DATA);
while (!phone.isAfterLast()) {
phoneNumber = phoneNumber + phone.getString(contactNumberColumnIndex) + ";";
phone.moveToNext();
}
}
phone.close();
return phoneNumber;
}
How to use?
ArrayList<HashMap<String, Object>> contactList = getContacts();
System.out.println("Contact List : " +contactList);
Output:
[
{
phone=992-561-1618;848-807-4440;,
contactId=1,
photo=android.graphics.Bitmap#44f40aa0,
address=Zalavadia Strret
Manavadar, Gujarat 362630
India,
email=birajzalavadia#gmail.com;biraj#tasolglobal.com;,
name=Biraj Zalavadia
},
{
phone=992-511-1418;842-827-4450;,
contactId=2,
photo=android.graphics.Bitmap#44f40aa0,
address=Makadiya Strret
Junagadh, Gujarat 364890
India,
email=niles#gmail.com;niles#tasolglobal.com;,
name=Niles patel
}
.......
]
NOTE:
You will get phone and email semicolon(;) separated if its more than one.

Fetching contacts in android is very slow

I had written a code to fetch contact name, phone number and image from Contacts and to display it on a listview in android. It's working fine but taking more time to load. I had tried to use multi-threading in some parts of the code. But the loading time is not decreased.
Here is the onCreate() method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lvDetail = (ListView) findViewById(R.id.listView1);
fetchcontacts();
lvDetail.setAdapter(new MyBaseAdapter(context, myList));
}
Here is the code for fetch contacts:
private void fetchcontacts() {
// TODO Auto-generated method stub
Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null,
null, null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");
int count = cursor.getCount();
if (count > 0) {
Toast.makeText(context, "count >0", Toast.LENGTH_SHORT).show();
while (cursor.moveToNext()) {
String columnId = ContactsContract.Contacts._ID;
int cursorIndex = cursor.getColumnIndex(columnId);
String id = cursor.getString(cursorIndex);
name = cursor.getString(cursor
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
Toast.makeText(context, "Toast 1", Toast.LENGTH_SHORT).show();
int numCount = Integer.parseInt(cursor.getString(cursor
.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)));
if (numCount > 0) {
Toast.makeText(context, "Toast 2", Toast.LENGTH_SHORT).show();
Cursor phoneCursor = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,
CommonDataKinds.Phone.CONTACT_ID+" = ?", new String[] { id
}, ContactsContract.Contacts.DISPLAY_NAME + " ASC");
while (phoneCursor.moveToNext()) {
Toast.makeText(context, "Toast 3", Toast.LENGTH_SHORT).show();
phoneNo = phoneCursor.getString(phoneCursor
.getColumnIndex(ContactsContract.CommonDataKinds.
Phone.NUMBER));
String image_uri = phoneCursor
.getString(phoneCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
if (image_uri != null) {
Toast.makeText(context, "Toast 4", Toast.LENGTH_SHORT).show();
System.out.println(Uri.parse(image_uri));
try {
bitmap = MediaStore.Images.Media
.getBitmap(this.getContentResolver(),
Uri.parse(image_uri));
// sb.append("\n Image in Bitmap:" + bitmap);
// System.out.println(bitmap);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Toast.makeText(context, name, Toast.LENGTH_SHORT).show();
getDataInList(name,phoneNo,bitmap);
name=null;
phoneNo=null;
Drawable myDrawable = getResources().getDrawable(R.drawable.star1);
bitmap = ((BitmapDrawable) myDrawable).getBitmap();
}
phoneCursor.close();
}
}
}
Here the setAdapter() function of the listview is working after fetching all the contacts to an ArrayList. do anyone have idea about how to display the contacts during fetching contacts? any sample code?
1.Read the Columns from the Cursor which you required only ,According to your requirement you just need _ID,HAS_PHONE_NUMBER,DISPLAY_NAME ,so change the Cursor reading
Cursor cursor = getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI,
new String[] { ContactsContract.Contacts._ID,
ContactsContract.Contacts.HAS_PHONE_NUMBER,
ContactsContract.Contacts.DISPLAY_NAME }, null, null,
ContactsContract.Contacts.DISPLAY_NAME + " ASC");
2.Dont do the time taking process in the UI thread..Use AsyncTask instead
Note : This two steps will resolve to some extent..but not completely
I made it by reduce repeated query wich is expensive. Best of my solution is that method found all mobile phones and email for each contact and insert to list for every contact values. It is fast as storm now :)
//contact entity
public class MobileContact {
public String name;
public String contact;
public Type type;
public MobileContact(String contact, Type type) {
name = "";
this.contact = contact;
this.type = type;
}
public MobileContact(String name, String contact, Type type) {
this.name = name;
this.contact = contact;
this.type = type;
}
public enum Type {
EMAIL, PHONE
}
#Override
public String toString() {
return "MobileContact{" +
"name='" + name + '\'' +
", contact='" + contact + '\'' +
", type=" + type +
'}';
}
}
// method for collect contacts
public List<MobileContact> getAllContacts() {
log.debug("get all contacts");
List<MobileContact> mobileContacts = new ArrayList<>();
ContentResolver contentResolver = context.getContentResolver();
// add all mobiles contact
Cursor phonesCursor = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.CONTACT_ID}, null, null, null);
while (phonesCursor != null && phonesCursor.moveToNext()) {
String contactId = phonesCursor.getString(phonesCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
String phoneNumber = phonesCursor.getString(phonesCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)).replace(" ", "");
mobileContacts.add(new MobileContact(contactId, phoneNumber, MobileContact.Type.PHONE));
}
if (phonesCursor != null) {
phonesCursor.close();
}
// add all email contact
Cursor emailCursor = contentResolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, new String[]{ContactsContract.CommonDataKinds.Email.DATA, ContactsContract.CommonDataKinds.Email.CONTACT_ID}, null, null, null);
while (emailCursor != null && emailCursor.moveToNext()) {
String contactId = emailCursor.getString(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.CONTACT_ID));
String email = emailCursor.getString(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
mobileContacts.add(new MobileContact(contactId, email, MobileContact.Type.EMAIL));
}
if (emailCursor != null) {
emailCursor.close();
}
// get contact name map
Map<String, String> contactMap = new HashMap<>();
Cursor contactsCursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Contacts.HAS_PHONE_NUMBER}, null, null, ContactsContract.Contacts.DISPLAY_NAME);
while (contactsCursor != null && contactsCursor.moveToNext()) {
String contactId = contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts._ID));
String contactName = contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
contactMap.put(contactId, contactName);
}
if (phonesCursor != null) {
phonesCursor.close();
}
// replace contactId to display name
for (MobileContact mobileContact : mobileContacts) {
String displayName = contactMap.get(mobileContact.name);
mobileContact.name = displayName != null ? displayName : "";
}
// sort list by name
Collections.sort(mobileContacts, new Comparator<MobileContact>() {
#Override
public int compare(MobileContact c1, MobileContact c2) {
return c1.name.compareTo(c2.name);
}
});
return mobileContacts;
}
The contacts in larse size use in backround task.
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number[i]));
ContentResolver contentResolver = getContentResolver();
Cursor search = contentResolver.query(uri, new String[]{ContactsContract.PhoneLookup._ID,
ContactsContract.PhoneLookup.DISPLAY_NAME}, null, null, null);
try {
if (search != null && search.getCount() > 0) {
search.moveToNext();
name = search.getString(search.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
id = search.getString(search.getColumnIndex(ContactsContract.Data._ID));
System.out.println("name" + name + "id" + id);
/* tv_name.setText(name);
tv_id.setText(id);
tv_phone.setText(number);*/
}
} finally {
if (search != null) {
search.close();
}
}
Fastest way for me soo far .
ContentResolver cr = mContext.getContentResolver(); Cursor cursor= mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, PROJECTION, "HAS_PHONE_NUMBER <> 0", null, null); if (cursor!= null) { final int displayNameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); final int numberIndex = cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER); final int idIndex= cursor.getColumnIndex(ContactsContract.Contacts._ID); String displayName, number = null, idValue; while (cursor.moveToNext()) {
displayName = cursor.getString(displayNameIndex);
idValue= cursor.getString(idIndex);
Cursor phones = mContext.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, "contact_id = '" + idValue + "'", null, null);
phones.moveToFirst();
try {
number = phones.getString(phones.getColumnIndex("data1"));
}
catch (CursorIndexOutOfBoundsException e)
{`
}
phones.close();
userList.add(new ContactModel(displayName , number , null , }

Categories

Resources