So I'm having trouble getting the phone number of a contact using its id.
This is the code I'm using to retrieve the number:
public String getNumber(){
//gets numbers by id
if (hasPhoneNumber){
ContentResolver contentResolver=context.getContentResolver();
Cursor cursor=contentResolver.query(
ContactsContract.Contacts.CONTENT_URI,
null,
ContactsContract.Contacts._ID+" = "+id,
null,
null
); //TODO : resolve empty cursor error
//contact seems to have no data available?
if (cursor.moveToFirst()){
cursor.moveToNext();
String contactId=cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
Cursor phones=contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID+" = "+contactId,
null,
null);
if (phones.moveToFirst()){
while (phones.moveToNext()) {
this.number=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
}
phones.close();
} else {
test("cursor error...");
}
cursor.close();
return number;
} else {
return null;
}
}
It works with a few contacts but most show the "cursor error..." Toast (test("cursor error...") )
It's always the
Cursor cursor
that has the error.
My guess is it's empty but I know I have those contacts phone numbers saved. How do I fix this? Are there other values I have to request?
Thanks in advance!
EDIT:
this is how I retrieve ID and Name:
contactCursor=getActivity().getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
new String[]{
ContactsContract.Contacts._ID,//0 - Long
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY,//1 - String
ContactsContract.Contacts.HAS_PHONE_NUMBER,//2 - Integer
},
null,
null,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME+" ASC");
EDIT 2:
I have everything in a github repository: https://github.com/nicolas-d-torres/Syncc
The first block of Code is inside app/src/main/java/gtsarandum/syncc/SynccContact
the second in app/src/main/java/gtsarandum/syncc/ContactFragment
I know this answer is a little late but hopefully it will help someone else with a similiar issue. Both of your cursor queries use the id as a string
ContactsContract.Contacts._ID+" = "+id,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID+" = "+contactId,
should be
ContactsContract.Contacts._ID + " = " + Uri.encode(id),
ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ Uri.encode(contactId),
Related
I have developed a program that shows a list of contacts from my phone book.
For this I use the following code:
ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI,
null,
ContactsContract.Contacts.HAS_PHONE_NUMBER + " = '1'",
null,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
if (cursor != null && cursor.getCount() > 0) {
while (cursor.moveToNext()) {
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, String.valueOf(id));
Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + id,
null,
null);
if (phones != null) {
while (phones.moveToNext()) {
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
contactList.add(new Contact(name, phoneNumber, id));
}
phones.close();
}
}
cursor.close();
}
adapter = new ContactAdapter(contactList, R.layout.contacts_list_item, getApplicationContext());
recyclerView.setAdapter(adapter);
Everything works, and the program displays all contacts from my phone book, but I want a certain number of contacts to be displayed. For example:
I open the program and load the first 50 contacts from the phone book, after scrolling, the next 50 contacts are loaded to the end of the list. and so on
Use below code that has limit cause. Replace your code with below
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI,
null,
ContactsContract.Contacts.HAS_PHONE_NUMBER + " = '1' ",
null,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE LOCALIZED ASC LIMIT 10");
It will get first 10 records. And in pull to refresh implementation, get more records on call back event of pull to refresh. Hope this will help you
I assume the reason you want this is because loading all contacts is very slow.
The reason it's very slow is because you currently have 1 query per contact, so if a user has 500 contacts, you'll need to run 500 queries.
You can reduce the number of queries to just one, then I assume you won't need the limit thing.
String[] projection = { Phone.CONTACT_ID, Phone.DISPLAY_NAME, Phone.NUMBER };
Cursor phones = getContentResolver().query(Phone.CONTENT_URI, projection, null, null, Phone.DISPLAY_NAME + " ASC");
while (phones.moveToNext()) {
String name = phones.getString(1);
String phone = phones.getString(2);
Long id = phones.getLong(0);
contactList.add(new Contact(name, phone, id));
}
phones.close();
If you want to display only one item per contact, and not per phone, you can change your contactList field to be a HashMap<Long, Contact> instead of a List, and add newly found phones to an existing Contact object if it already exists in the Map.
Something like:
Contact contact = allContacts.get(id);
if (contact == null) {
contact = new Contact(name, phone, id);
allContacts.put(id, contact);
} else {
contact.addPhone(phone); // you'll need to implement this
}
I am using the following to fetch a string from my table. The cursor is always returning empty even when I have data in database. Is the query wrong?
public void find(String myNumber){
String[] thecolumns = new String[]{
ID,
FLAG};
cursor = sqlDb.query(MY_TABLE,
thecolumns, NUMBER + "='"
+ myNumber+ "'", null, null, null, null);
if (cursorToFetchAssets != null ) {
cursorToFetchAssets.moveToFirst();{
try{
//code to fetch
}catch{
//return when there are no rows found.
}
}
EDIT: NUMBER is of type string "...+ NUMBER + " TEXT,.. " and myNumber is also a string
FIXED: Issue was on the server side of my code. Not over here..
try this:
cursor = sqlDb.query(
MY_TABLE,
thecolumns,
NUMBER + "=?",
new String[]{String.valueOf(number)},
null, null, null);
The code snippet below returns basic SMS conversation data:
Cursor cursor = activity.getContentResolver().query(Uri.parse( "content://mms-sms/conversations?simple=true"), null, null, null, "normalized_date desc" );
if(cursor.moveToFirst())
String recipient_ids = cursor.getString(3);
My question is that how can I get a phone's contact data given that recipient_ids? In this case I need to retrieve the contact number and contact display_name.
Your help is greatly appreciated. Thanks in advance!
Try this:
public String getContactData(String id){
String number;
Cursor phones = fa.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ id, null, null);
if(phones.moveToFirst()) {
number = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
phones.close();
return number;
}
Hope it helps!
This is, what's working in my app:
private String getContactNumber(final long recipientId) {
String number = null;
Cursor c = getContentResolver().query(ContentUris
.withAppendedId(Uri.parse("content://mms-sms/canonical-address"), recipientId),
null, null, null, null);
if (c.moveToFirst()) {
number = c.getString(0);
}
c.close();
return number;
}
The contact numbers are saved in some table called canonical-address.
It was kind of buggy a few years ago. Updates on the contact did not propagate through this table properly. But I think that's fine now.
You basically need to parse the (list of) ids into single ids. Then query the database for each of them.
You could use one single query for all ids together, though.
Can someone give me a correct example on how to load all MOBILE numbers saved on the phone into a List, Array or whatever is appropriate? All the examples I have found are either depreciated or do not work. Sorry to ask for a freebie like this but I am getting desparate, I can't find anything!
Here's what I have, it doesn't work. The Log.d doesn't happen.
ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, "DISPLAY_NAME = '" + People.NAME + "'", null, null);
if (cursor.moveToFirst()){
Log.d("Number", "Cursor moved");
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
Cursor phones = cr.query(People.CONTENT_URI, new String[]{People.NAME, People.NUMBER}, null, null, People.NAME + " ASC");
while (phones.moveToNext()) {
String number = phones.getString(phones.getColumnIndex(Phone.NUMBER));
int type = phones.getInt(phones.getColumnIndex(Phone.TYPE));
switch (type) {
case Phone.TYPE_MOBILE:
//Add to the list of numbers
Log.d("Number", number);
break;
}
}
}
Thank you!
Joel,
Cursor phones = cr.query( ContactsContract.CommonDataKind.Phone.NUMBER, .... );
And you need to compare with ContactsContract.CommonDataKind.Phone.TYPE = 2.
Thank you.
I'm trying to use the following code to grab a random mobile phone number from the contacts:
ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, "DISPLAY_NAME = '" + "NAME" + "'", null, null);
cursor.moveToFirst();
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
Cursor phones = cr.query(Phone.CONTENT_URI, null, Phone.CONTACT_ID + " = " + contactId, null, null);
List numbers = new ArrayList();
while (phones.moveToNext()) {
String number = phones.getString(phones.getColumnIndex(Phone.NUMBER));
int type = phones.getInt(phones.getColumnIndex(Phone.TYPE));
switch (type) {
case Phone.TYPE_MOBILE:
numbers.add(number);
break;
}
}
Random randGen = new Random();
return (String) numbers.get(randGen.nextInt(numbers.size()));
However, running this code produces a crash on line 4, with a message saying "CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0". The crash seems to be caused by the cursor.getString() method. Does anyone know where I'm going wrong? This is using the ContactsContract in Android 2.1. Eclipse gives no errors.
Thanks!
The moveToFirst() method returns a boolean. It returns true if it was able to move to the first row and false otherwise, indicating that the query returned an empty set.
When using a cursor, you should follow something like:
if (cursor.moveToFirst()) {
do {
// do some stuff
} while (cursor.moveToNext());
}
cursor.close();