I am using the below code in my app to fetch contacts in the listview but its displaying the same contact two times.
Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");
while (phones.moveToNext())
{
String name1=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
// System.out.println(".................."+name1);
}
I think its getting the sim + internal contacts. Is there any way to get contacts through internal storage only?
I used this method, and it show only one time
// declear two array list
List<String> name1 = new ArrayList<String>();
List<String> phno1 = new ArrayList<String>();
getAllContacts(this.getContentResolver());
// call this where you want to get contacts and give permission in mainfest
public void getAllContacts(ContentResolver cr) {
Cursor phones = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
null, null);
while (phones.moveToNext()) {
String name = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
// Bitmap bitmap=-
// phones.getBlob(ContactsContract.CommonDataKinds.Phone.)
System.out.println("" + phoneNumber);
name1.add(name);
phno1.add(phoneNumber);
}
phones.close();
}
// set in adaptr like this
class MyAdapter extends BaseAdapter {
LayoutInflater mInflater;
TextView tv1, tv;
CheckBox cb;
MyAdapter() {
mInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return name1.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView,
ViewGroup parent) {
View vi = convertView;
if (convertView == null)
vi = mInflater.inflate(R.layout.friends_addmobile_contacts,
null);
TextView tv = (TextView) vi.findViewById(R.id.tvMcontactname);
tv1 = (TextView) vi.findViewById(R.id.tvMcontactphoneno);
tv.setText("" + name1.get(position));
tv1.setText("" + phno1.get(position));
// tv1.setText("Phone No :" + phno1.get(position));
return vi;
}
}
// call this method
MyAdapter ma = new MyAdapter();
lvmobilecontacts.setAdapter(ma);
Related
I need to get all contacts that have at least a phone number. Android contacts may be picked from many accounts like gmail,skype,vibe etc. I made the classes i need to get the contacts i need. My problem that it gets anyway contacts that don't have at least 1 phone number and shows just their name and avatar. Can any1 say what I am doing wrong in my code? My code source is shared below.
ContactsActivity.class
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
selectionString = edtSearch.getText().toString();
String[] selectionArgs = {"%" + selectionString + "%", selectionString + "%", "%" + selectionString};
String selection = ContactsContract.Contacts.DISPLAY_NAME + " LIKE ? OR "
+ ContactsContract.Contacts.DISPLAY_NAME + " LIKE ? OR "
+ ContactsContract.Contacts.DISPLAY_NAME + " LIKE ? AND "
+ ContactsContract.Contacts.HAS_PHONE_NUMBER + "=='1'";
return new CursorLoader(this,
ContactsContract.Contacts.CONTENT_URI, // URI
null, // projection fields
selection, // the selection criteria
selectionArgs, // the selection args
ContactsContract.Contacts.DISPLAY_NAME + " ASC" // the sort order
);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
ContactsAdapter.createCheckedContacts(data.getCount());
contactsAdapter.setCursor(data);
contactsAdapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
contactsAdapter.swapCursor(null);
}
ContactsAdapter.class
public class ContactsAdapter extends CursorAdapter {
static boolean status = true;
private static boolean[] checkedContacts;
private static Context context;
private static Cursor cursor;
public ContactsAdapter(Context context, Cursor c) {
super(context, c, 0);
this.context = context;
}
public static void setCursor(Cursor cursor) {
ContactsAdapter.cursor = cursor;
}
public static void createCheckedContacts(int count) {
checkedContacts = new boolean[count];
}
public static void saveSelectedContacts(ClientDao contactDao) {
for (int i = 0; i < checkedContacts.length; i++) {
if (checkedContacts[i]) {
cursor.moveToPosition(i);
DatabaseHelper.getInstance().saveClient(ContactUtils.cursorToContact(cursor, context), status);
status = !status;
}
}
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View convertView = ((Activity) context).getLayoutInflater().inflate(R.layout.contact_item, parent, false);
ViewHolder holder = new ViewHolder(convertView);
convertView.setTag(holder);
return convertView;
}
#Override
public void bindView(View convertView, final Context context, final Cursor cursor) {
final ViewHolder holder = (ViewHolder) convertView.getTag();
final Contact contact = ContactUtils.cursorToContact(cursor, context);
holder.tvName.setText(contact.getDisplayName());
if (isFirst(cursor)) {
holder.tvLetter.setVisibility(View.VISIBLE);
String letter = String.valueOf(Character.toUpperCase(contact.getDisplayName().charAt(0)));
holder.tvLetter.setText(letter);
} else {
holder.tvLetter.setVisibility(View.INVISIBLE);
}
convertView.setTag(convertView.getId(), contact);
if (!TextUtils.isEmpty(contact.getPhotoUri())) {
new ImageLoaderUtils.ContactImage(contact, convertView, holder.ivUserImage, context).execute();
} else {
holder.ivUserImage.setImageResource(R.drawable.ic_profile);
}
holder.inviteBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, ContactInvitationActivity_.class);
intent.putExtra("contact", contact);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
context.startActivity(intent);
}
});
}
private boolean isFirst(Cursor cursor) {
Contact c1 = ContactUtils.cursorToContact(cursor, context);
if (cursor.getPosition() == 0)
return true;
cursor.moveToPrevious();
Contact c2 = ContactUtils.cursorToContact(cursor, context);
if (c1.getDisplayName() == null || c2.getDisplayName() == null)
return false;
if (Character.toUpperCase(c1.getDisplayName().charAt(0)) != Character.toUpperCase(c2.getDisplayName().charAt(0)))
return true;
return false;
}
private static class ViewHolder {
TextView tvName;
TextView tvLetter;
ImageView ivUserImage;
Button inviteBtn;
RelativeLayout rlContact;
private ViewHolder(View convertView) {
tvName = (TextView) convertView.findViewById(R.id.tvContactsName);
tvLetter = (TextView) convertView.findViewById(R.id.tvLetter);
ivUserImage = (ImageView) convertView.findViewById(R.id.ivUserIcon);
inviteBtn = (Button) convertView.findViewById(R.id.inviteBtn);
rlContact = (RelativeLayout) convertView.findViewById(R.id.rlContact);
}
}
}
ContactUtil.class
public class ContactUtils {
public static Contact cursorToContact(Cursor c, Context context) {
if (c == null || c.getPosition() < 0) return null;
Contact contactObj = new Contact();
try {
contactObj.setID(c.getString(c.getColumnIndex(ContactsContract.Contacts._ID)));
contactObj.setDisplayName(c.getString(c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
contactObj.setPhotoUri(c.getString(c.getColumnIndex(ContactsContract.Contacts.PHOTO_URI)));
contactObj.setPhoneNumber("");
contactObj.setEmail("");
setPhoneNumber(c, contactObj, context);
setEmail(contactObj, context);
} catch (Exception e) {
e.printStackTrace();
}
return contactObj;
}
public static void setPhoneNumber(Cursor c, Contact contactObj, Context context) {
if (Integer.parseInt(c.getString(c.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
// Query phone here. Covered next
Cursor phones = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactObj.getID(), null, null);
phones.moveToFirst();
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.i("Number", phoneNumber);
contactObj.setPhoneNumber(phoneNumber);
phones.close();
}
}
public static void setEmail(Contact contactObj, Context context) {
Cursor emailCur = context.getContentResolver().query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?",
new String[]{contactObj.getID()}, null);
while (emailCur.moveToNext()) {
// This would allow you get several email addresses
// if the email addresses were stored in an array
String email = emailCur.getString(
emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
String emailType = emailCur.getString(
emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));
contactObj.setEmail(email);
}
emailCur.close();
}
}
Application need to read the phonebook contacts and show it to the user, have more than 8000 contacts on the phone.
Problem is it stuck for very long time while rendering all contacts on the screen.
Please suggest best way to accomplish this task. thanks
Main Method:
Cursor contactsCursor = getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
LogUtils.d("### cursorCount" + contactsCursor.getCount());
contacts = new ArrayList<ImportContactModel>();
importContactList = new ArrayList<ImportContactModel>();
showProgressDialog();
asyncLoader = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
fetchContacts();
return null;
}
protected void onPostExecute(Void result) {
// create an array of Strings, that will be put to our
// ListActivity
adapter = new ImportContactArrayAdapter(
ImportContactSelection.this, contacts);
contactList.setAdapter(adapter);
contactList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
initSearch();
dismissProgressDialog();
};
}.execute();
Class to get Data:
public void fetchContacts() {
String phoneNumber = null;
String email = null;
Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;
String _ID = ContactsContract.Contacts._ID;
String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;
String PROFILE_PIC = ContactsContract.CommonDataKinds.Phone.PHOTO_URI;
Uri PhoneCONTENT_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String Phone_CONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
Uri EMAIL_CONTENT_URI = ContactsContract.CommonDataKinds.Email.CONTENT_URI;
String EMAIL_CONTACT_ID = ContactsContract.CommonDataKinds.Email.CONTACT_ID;
String EMAIL = ContactsContract.CommonDataKinds.Email.DATA;
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(CONTENT_URI, null, null, null,
null);
// Loop for every contact in the phone
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
ImportContactModel tempContact = new ImportContactModel();
String contact_id = cursor
.getString(cursor.getColumnIndex(_ID));
String name = cursor.getString(cursor
.getColumnIndex(DISPLAY_NAME));
String image_uri = cursor.getString(cursor
.getColumnIndex(PROFILE_PIC));
int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor
.getColumnIndex(HAS_PHONE_NUMBER)));
if (hasPhoneNumber > 0) {
tempContact.setId(contact_id);
if (image_uri != null)
tempContact.setProfilePic(cursor.getString(cursor
.getColumnIndex(PROFILE_PIC)));
else
tempContact.setProfilePic("");
tempContact.setContactName(name);
// Query and loop for every phone number of the contact
Cursor phoneCursor = contentResolver.query(
PhoneCONTENT_URI, null, Phone_CONTACT_ID + " = ?",
new String[] { contact_id }, null);
// Get All Phone Numbers
while (phoneCursor.moveToNext()) {
phoneNumber = phoneCursor.getString(phoneCursor
.getColumnIndex(NUMBER));
tempContact.setContactNo(phoneNumber);
break;
}
phoneCursor.close();
Cursor emailCursor = contentResolver.query(
EMAIL_CONTENT_URI, null, EMAIL_CONTACT_ID + "=?",
new String[] { contact_id }, null);
while (emailCursor.moveToNext()) {
String contactId = emailCursor.getString(emailCursor
.getColumnIndex(EMAIL_CONTACT_ID));
email = emailCursor.getString(emailCursor
.getColumnIndex(EMAIL));
tempContact.setEmail(email);
break;
}
emailCursor.close();
contacts.add(tempContact);
}
}
}
}
Adapter Class
public class ImportContactArrayAdapter extends ArrayAdapter<ImportContactModel> {
private final List<ImportContactModel> list;
private final Activity context;
private ImageLoader mImageLoader;
public ImportContactArrayAdapter(Activity context, List<ImportContactModel> list) {
super(context, R.layout.item_task_contact_select, list);
this.context = context;
this.list = list;
this.mImageLoader = ImageLoader.getInstance();
}
static class ViewHolder {
protected ImageView profilePic;
protected TextView contactName;
protected TextView contactNo;
protected CheckBox checkbox;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.item_task_contact_select, null);
final ViewHolder viewHolder = new ViewHolder();
//viewHolder.profilePic = (ImageView) view.findViewById(R.id.img_import_profilePic);
viewHolder.contactName = (TextView) view.findViewById(R.id.name_text);
viewHolder.contactNo = (TextView)view.findViewById(R.id.tag_text_1);
viewHolder.contactNo.setVisibility(View.VISIBLE);
viewHolder.contactNo.setTextSize(11);
viewHolder.checkbox = (CheckBox) view.findViewById(R.id.select_checkbox);
viewHolder.checkbox.setClickable(true);
viewHolder.checkbox
.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
ImportContactModel element = (ImportContactModel) viewHolder.checkbox
.getTag();
element.setSelected(buttonView.isChecked());
}
});
view.setTag(viewHolder);
viewHolder.checkbox.setTag(list.get(position));
} else {
view = convertView;
((ViewHolder) view.getTag()).checkbox.setTag(list.get(position));
}
ViewHolder holder = (ViewHolder) view.getTag();
ImageView avatar = (ImageView) view.findViewById(R.id.img_avatar);
ImageView avatarBorder = (ImageView) view.findViewById(R.id.img_avatar_overlay);
ProgressBar avatarProgress = (ProgressBar) view.findViewById(R.id.img_avatar_progress);
if(!list.get(position).equals(""))
//holder.profilePic.setImageURI(Uri.parse(list.get(position).getProfilePic()));
mImageLoader.displayImage(list.get(position).getProfilePic(), avatar, new AvatarsImageLoadingListener(avatarProgress, avatarBorder, R.drawable.bg_nophoto));
holder.contactName.setText(list.get(position).getContactName());
holder.contactNo.setText(list.get(position).getContactNo());
holder.checkbox.setChecked(list.get(position).isSelected());
return view;
}
public ArrayList<ImportContactModel> getCheckList(){
ArrayList<ImportContactModel> tempList = new ArrayList<ImportContactModel>();
for(int i=0;i<list.size();i++){
if(list.get(i).isSelected()){
tempList.add(list.get(i));
LogUtils.d(""+list.get(i).getContactName());
}
}
return tempList;
}
}
So it just shows Loading screen for huge amount of time..
You don't have to fetch all contacts to display them. AsyncTask has publishProgress method. I'm not experienced with Cursor class, since I prefer ORM for that, so I'll write in pseudo code, you'll have to adapt it yourself.
//in AsyncTask
protected Void doInBackground(params){
while(cursor.moveToNext()){
contactInfo = createContact(currentCursorValue);
publishProgress(contactInfo);
}
}
onProgressUpdate(contactInfo){
if(adapter==null){
//first time adapter setup
}
adapter.add(contactInfo);
adapter.notifyDataSetChanged();
}
This way, every time you pull a record from Db, you publish it, and items are added continuously. User won't notice any delay, unless he tries searching for not yet existing items, or you want to implement that big pop up letter for fast scroll. Still, above code is not very effective, since publishing the progress every .001 second or so, is not very smart, so you can either publish every 20 results, or publish them every second, up to you.
I want to get conctacts on a listView and I want too reutilitzate one code of SocialAuth.
In this code i can get ContactList on the LogCat but not in the listView and I don't know how to do this. This listView is on other XML.
I'm goggling and more but I don't Know how to adapt the code
public void Events(String provider) {
setContentView(R.layout.contact_list);
List < Contact > contactsList = adapter.getContactList();
if (contactsList != null && contactsList.size() > 0) {
for (Contact p: contactsList) {
if (TextUtils.isEmpty(p.getFirstName()) && TextUtils.isEmpty(p.getLastName())) {
p.setFirstName(p.getDisplayName());
}
Log.d("Custom-UI", "Display Name = " + p.getDisplayName());
String ContactNAme = p.getDisplayName();
//ContactName = new String[] {p.getDisplayName()};
//mapTo = new int[] {android.R.id.text1};
Log.d("Custom-UI", "First Name = " + p.getFirstName());
String ContactFisrtName = p.getFirstName();
Log.d("Custom-UI", "Last Name = " + p.getLastName());
String ContactLastName = p.getLastName();
Log.d("Custom-UI", "Contact ID = " + p.getId());
String ContactId = p.getId();
Log.d("Custom-UI", "Profile URL = " + p.getProfileUrl());
String ContactProfileUrl = p.getProfileUrl();
}
// Log.d("ContactList",mAdapter.toString());
}
Toast.makeText(CustomUI.this, "View Logcat for Contacts Information", Toast.LENGTH_SHORT).show();
}
I think that the problem is the cursor because I don't have anyone, I have this function that I think that works likes cursor
public List<Contact> getContactList()
{
try
{
contactsList = new contactTask().execute().get();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
catch (ExecutionException e)
{
e.printStackTrace();
}
return contactsList;
}
So if someone can help me please, Thanks so much.
Please have a look at the below link
http://developer.android.com/tools/samples/index.html
This is having the sample example in Android SDK. where you can get the desired result.
You need to write a custom adapter for you list view.
here is a good example
http://android.vexedlogic.com/2011/04/02/android-lists-listactivity-and-listview-ii-%E2%80%93-custom-adapter-and-list-item-view/
// Call contact thread
contact_thread = new Contact_thread();
contact_thread.start();
private Cursor getContacts() {
// Run query
Uri uri = ContactsContract.Contacts.CONTENT_URI;
String[] projection = new String[] { ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME };
String[] selectionArgs = null;
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME
+ " COLLATE LOCALIZED ASC";
return managedQuery(uri, projection, null, selectionArgs, sortOrder);
}
class Contact_thread extends Thread {
#Override
public void run() {
// TODO Auto-generated method stub
// Build adapter with contact entries
Cursor cursor = getContacts();
cursor.moveToFirst();
contactName = new String[cursor.getCount()];
contactNo = new String[cursor.getCount()];
checkedPosition = new boolean[cursor.getCount()];
ContentResolver contect_resolver = getContentResolver();
int i = 0;
if (cursor.getCount() > 0) {
do {
String id = cursor
.getString(cursor
.getColumnIndexOrThrow(ContactsContract.Contacts._ID));
Cursor phoneCur = contect_resolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = ?", new String[] { id }, null);
if (phoneCur.moveToFirst()) {
contactName[i] = phoneCur
.getString(phoneCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
contactNo[i] = phoneCur
.getString(phoneCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
if (contactName[i] == null) {
contactName[i] = "Unknown";
}
} else {
contactName[i] = "Unknown";
contactNo[i] = "";
}
db.AddContact(contactName[i], contactNo[i]);
i++;
phoneCur.close();
} while (cursor.moveToNext());
}
cursor.close();
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
// mContactList.setAdapter(cursorAdapter);
mContactList.setAdapter(new ContactAdapter(
ContactManager.this, R.layout.contact_entry));
}
});
}
}
private class ContactAdapter extends ArrayAdapter<String> implements
Filterable {
public ContactAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
// TODO Auto-generated constructor stub
}
public int getCount() {
return contactName.length;
}
public String getItem(int position) {
return contactName[position];
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View v;
if (convertView == null) {
LayoutInflater li = getLayoutInflater();
v = li.inflate(R.layout.contact_entry, null);
} else {
v = convertView;
}
CheckedTextView text = (CheckedTextView) v.findViewById(R.id.text1);
text.setText(contactName[position] + " (" + contactNo[position]
+ ") ");
text.setChecked(checkedPosition[position]);
return v;
}
}
contact_entry.xml
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/text1"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:background="#AA0114"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
android:gravity="center_vertical"
android:paddingLeft="6dip"
android:paddingRight="6dip"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textStyle="bold" />
I am trying to implement a custom AutoCompleteTextView for choosing a contact's phone number from a list of suggestions that display the contact name, phone number type, and phone number. I created a custom CursorAdapter that defines and sets my Layout and TextViews for each suggestion and queries contacts based on the user-entered text via runQueryOnBackgroundThread. I'm running into an issue where the suggestions seem correct for the first two values entered (e.g. "ab" suggests "abcd" and "abyz") but not for anything beyond that (e.g. "abc" suggests "abyz"). For the latter, when the "abyz" suggestion is selected, the values for "abcd" are returned.
Code for the main activity:
final ContactInfo cont = new ContactInfo(ctx);
Cursor contacts = cont.getContacts2(null);
startManagingCursor(contacts);
ContactsAutoCompleteCursorAdapter adapter = new ContactsAutoCompleteCursorAdapter(this, contacts);
mPersonText.setAdapter(adapter);
mPersonText.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Cursor cursor = (Cursor) arg0.getItemAtPosition(arg2);
String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
mPersonNum.setText(number);
}
});
Code for my contacts class that returns a cursor for all contacts:
public Cursor getContacts2(String where)
{
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String[] projection = new String[] {
ContactsContract.CommonDataKinds.Phone._ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.TYPE,
ContactsContract.CommonDataKinds.Phone.NUMBER};
Cursor people = ctx.getContentResolver().query(uri, projection, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
return people;
}
Code for my CursorAdapter:
public class ContactsAutoCompleteCursorAdapter extends CursorAdapter implements Filterable {
private TextView mName, mType, mNumber;
private ContentResolver mContent;
public ContactsAutoCompleteCursorAdapter(Context context, Cursor c) {
super(context, c);
mContent = context.getContentResolver();
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final LayoutInflater mInflater = LayoutInflater.from(context);
final View ret = mInflater.inflate(R.layout.contacts_auto_list, null);
mName = (TextView) ret.findViewById(R.id.name);
mType = (TextView) ret.findViewById(R.id.phonetype);
mNumber = (TextView) ret.findViewById(R.id.phonenum);
return ret;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
int nameIdx = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int typeIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
int numberIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
String name = cursor.getString(nameIdx);
int type = cursor.getInt(typeIdx);
String number = cursor.getString(numberIdx);
mName.setText(name);
if (type == 1) {mType.setText("Home");}
else if (type == 2) {mType.setText("Mobile");}
else if (type == 3) {mType.setText("Work");}
else {mType.setText("Other");}
mNumber.setText(number);
}
#Override
public String convertToString(Cursor cursor) {
int nameCol = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
String name = cursor.getString(nameCol);
return name;
}
#Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
// this is how you query for suggestions
// notice it is just a StringBuilder building the WHERE clause of a cursor which is the used to query for results
if (getFilterQueryProvider() != null) { return getFilterQueryProvider().runQuery(constraint); }
String[] projection = new String[] {
ContactsContract.CommonDataKinds.Phone._ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.TYPE,
ContactsContract.CommonDataKinds.Phone.NUMBER};
return mContent.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection,
"UPPER(" + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + ") LIKE '" + constraint.toString().toUpperCase() + "%'", null,
ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
}
}
As I said above, when the user enters "ab" into the AutoCompleteTextView the suggestions are "abcd" and "abyz", however when the user types "abc" the suggestion is just "abyz". When the user selects "abyz" in that case, the values for "abcd" are returned. Here are two screenshots that show what I'm trying to describe:
I've read every question I could find here and elsewhere but can't seem to figure this out. I'm fairly new to Android development so I apologize in advance if my mistake is a simple one. Thanks in advance!
I seem to have answered my own question after more research. Moving the setting of the views for my textViews from the newView function to the bindView function seems to have done the trick, which I think makes sense...
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final LayoutInflater mInflater = LayoutInflater.from(context);
final View ret = mInflater.inflate(R.layout.contacts_auto_list, null);
return ret;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
int nameIdx = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int typeIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
int numberIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
String name = cursor.getString(nameIdx);
int type = cursor.getInt(typeIdx);
String number = cursor.getString(numberIdx);
mName = (TextView) view.findViewById(R.id.name);
mType = (TextView) view.findViewById(R.id.phonetype);
mNumber = (TextView) view.findViewById(R.id.phonenum);
mName.setText(name);
if (type == 1) {mType.setText("Home");}
else if (type == 2) {mType.setText("Mobile");}
else if (type == 3) {mType.setText("Work");}
else {mType.setText("Other");}
mNumber.setText(number);
}
you have already public Cursor runQueryOnBackgroundThread function in your adapter so you do not need call second time cursor in activity
you do not need to use getContacts2 function
Activity
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sms_send);
Cursor contacts = null;
mAdapter= new ContactsAutoCompleteCursorAdapter(this, contacts);
mTxtPhoneNo = (AutoCompleteTextView) findViewById(R.id.mmWhoNo);
mTxtPhoneNo.setAdapter(mAdapter);
mTxtPhoneNo.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
Cursor cursor = (Cursor) arg0.getItemAtPosition(arg2);
String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
mTxtPhoneNo.setText(number);
}
});
}
Adapter
public class ContactsAutoCompleteCursorAdapter extends CursorAdapter implements Filterable {
private TextView mName, mType, mNumber;
private ContentResolver mContent;
public ContactsAutoCompleteCursorAdapter(Context context, Cursor c) {
super(context, c);
mContent = context.getContentResolver();
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final LayoutInflater mInflater = LayoutInflater.from(context);
final View ret = mInflater.inflate(R.layout.custcontview, null);
return ret;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
int nameIdx = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int typeIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
int numberIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
String name = cursor.getString(nameIdx);
int type = cursor.getInt(typeIdx);
String number = cursor.getString(numberIdx);
mName = (TextView) view.findViewById(R.id.ccontName);
mType = (TextView) view.findViewById(R.id.ccontType);
mNumber = (TextView) view.findViewById(R.id.ccontNo);
mName.setText(name);
if (type == 1) {mType.setText("Home");}
else if (type == 2) {mType.setText("Mobile");}
else if (type == 3) {mType.setText("Work");}
else {mType.setText("Other");}
mNumber.setText(number);
}
#Override
public String convertToString(Cursor cursor) {
int nameCol = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
String name = cursor.getString(nameCol);
return name;
}
#Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
// this is how you query for suggestions
// notice it is just a StringBuilder building the WHERE clause of a cursor which is the used to query for results
if (constraint==null)
return null;
if (getFilterQueryProvider() != null) { return getFilterQueryProvider().runQuery(constraint); }
String[] projection = new String[] {
ContactsContract.CommonDataKinds.Phone._ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.TYPE,
ContactsContract.CommonDataKinds.Phone.NUMBER};
return mContent.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection,
"UPPER(" + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + ") LIKE '%" + constraint.toString().toUpperCase() + "%' or UPPER(" + ContactsContract.CommonDataKinds.Phone.NUMBER + ") LIKE '%" + constraint.toString().toUpperCase() + "%' ", null,
ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
}
}
i also add query for phone number search in query
When we click on albums than it should display list of songs in album, I try like this but it displays all the songs in SD card.
private OnItemClickListener musicgridlistener1 = new OnItemClickListener(){
public void onItemClick(AdapterView parent, View v, int position,long id)
{
System.gc();
album_column_index1 = musiccursor
.getColumnIndexOrThrow(MediaStore.Audio.AlbumColumns.ALBUM_ART);
musiccursor.moveToPosition(position);
MUSICfilename = musiccursor.getString(album_column_index1);
Log.i("=======this is file name of album========",""+musiccursor.getCount()+" "+MUSICfilename+" "+position);
String[] ablummusicproj = {MediaStore.Audio.Media.DATA,
MediaStore.Audio.AlbumColumns.ALBUM,
MediaStore.Audio.AlbumColumns.ARTIST,
MediaStore.Audio.Media.DISPLAY_NAME};
final String sortOrder = MediaStore.Audio.Media.ALBUM_KEY + " COLLATE LOCALIZED ASC";
//final String sortOrder= MediaStore.Audio.Media.ALBUM_KEY + " ASC, "
// + MediaStore.Audio.Media.TRACK + " ASC, "
// + MediaStore.Audio.Media.TITLE_KEY + " ASC";
Uri uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
musicAlbum = getBaseContext().getContentResolver().query(uri, ablummusicproj, null, null, sortOrder);
count = musicAlbum.getCount();
Log.i("++++++++++ value of album cursor is ",""+count);
gridmusic = (GridView) findViewById(R.id.gridmusic);
madAdapter_internal = new MusicalbumAdapter_internal(getApplicationContext());
gridmusic.setAdapter(madAdapter_internal);
gridmusic.setOnItemClickListener(musicgridlistener);
musiccursor=musicAlbum;
}
};
MusicalbumAdapter_internal Class
public class MusicalbumAdapter_internal extends BaseAdapter {
private Context maContext;
public MusicalbumAdapter_internal(Context c) {
maContext = c;
Log.i("++++++++++++++++++", "this is context");
}
public int getCount() {
return count;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
System.gc();
TextView tv1 = new TextView(maContext.getApplicationContext());
String id = null;
if (convertView == null) {
music_column_index = musicAlbum.getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.DISPLAY_NAME);
musicAlbum.moveToPosition(position);
id = musicAlbum.getString(music_column_index);
//music_column_index = musiccursor
//.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE);
musicAlbum.moveToPosition(position);
//id += " Size(KB):" + musiccursor.getString(music_column_index);
tv1.setLayoutParams(new GridView.LayoutParams(100, 100));
tv1.setText(id);
} else
tv1 = (TextView) convertView;
return tv1;
}
}
you would have to store the album_key when u get the albums.
mediaStoreURI = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.Audio.Media.ALBUM_KEY + "=?";
String[] projection = new String[] { MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.ALBUM_ID, MediaStore.Audio.Media.ARTIST,
"strftime(\"%H-%M-%S\", (" + MediaStore.Audio.Media.DURATION + "/1000), \"unixepoch\") as time" };
String[] selectionArgs = new String[] { ((MediaContainerUSB) currentMediaObject).getUSBGroupingKey() };
String sortOrder = MediaStore.Audio.Media.TRACK;
the album_key is generated for ever album in the sdcard and stored in a different table as well.