I've been trying to retrieve SMS information but have only been to retrieve everything BUT the display name of contacts. strDisplayNameonly shows the numerical value of a particular contact and not the name itself. All other string version of data shows their corresponding information correctly (aside from "date"). I've tried other implementations of getting the display name from other answers, but doing so causes the app to crash when trying to test.
Uri smsData = Uri.parse("content://sms/" + folderName);
String[] id = new String[]
{
"_id", "person", "address",
"body", "date"
};
ContentResolver contentResolver = getContentResolver();
Cursor smsCursor = contentResolver.query(smsData, null, null, null, null);
// Retrieve index of data
int indexContactID = smsCursor.getColumnIndex(id[0]);
int indexDisplayName = smsCursor.getColumnIndex(id[1]);
int indexPhoneNumber = smsCursor.getColumnIndex(id[2]);
int indexMsg = smsCursor.getColumnIndex(id[3]);
int indexDate = smsCursor.getColumnIndex(id[4]);
if (indexMsg < 0 || !smsCursor.moveToFirst())
return;
mCustomAdapter.clear();
while (smsCursor.moveToNext())
{
// Retrieve string version of data
String strContactID = smsCursor.getString(indexContactID);
String strDisplayName = smsCursor.getString(indexDisplayName);
String strContactNumber = smsCursor.getString(indexPhoneNumber);
String strMsg = smsCursor.getString(indexMsg);
String strDate = smsCursor.getString(indexDate);
String[] textMessage = new String[]
{
strContactID, strDisplayName, strContactNumber,
strMsg, strDate
};
// Place collected data into custom adapter
mCustomAdapter.add(textMessage);
}
smsCursor.close();
Who told you "person" is the contact's display-name?
According to the docs:
PERSON
The ID of the sender of the conversation, if present.
This is actually a "sender-id" this is never a contact-id, as an sms can be sent from a contact, a non-contact phone number, a non-phone-number (like GOOGLE or FACEBOOK) and from a group containing two or more of the above types.
If you'd like to get check if this is a contact, and if it is, get the contact's name, you need to pass two steps:
Use the canonical-address table to translate between id and phone-number (address). You can copy and use Android's helper class for this RecipientIdCache
In case the address is a single phone number, use the PHONE_LOOKUP table to look for a contact with that number, this will help: https://stackoverflow.com/a/7967182/819355
Related
I access the contacts list this way:
CursorLoader oCursorLoader = new CursorLoader(MyContext, ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
Cursor oCursor = oCursorLoader.loadInBackground();
int contactId = oCursor.getColumnIndex(ContactsContract.Contacts._ID);
int name = oCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
oCursor.moveToFirst();
if(oCursor.isAfterLast()==false) {
do {
String sId = oCursor.getString(contactId);
String phName = oCursor.getString(name);
...more code...
} while (oCursor.moveToNext());
}
I want to save the ID for a contact in a database to do some processing later on. For example, I want to save latest contacts called.
My question is:
Does the ID for a contact remains the same even if the contact is modified?
For example, if I save in the database the id "44" por user "Boss", does that ID remains the same even if the device is rebooted, or contact is modified (for example its name or phone number or email address)?
I am very new to app development. I am trying to read contact info without having to request permission to contacts (so I am using intents).
I get a URI with the following code in my main activity:
Intent selectContactIntent = new Intent(Intent.ACTION_PICK);
selectContactIntent.setType(ContactsContract.Contacts.CONTENT_TYPE);
if (selectContactIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(selectContactIntent, REQUEST_CODE_SELECT_CONTACT);
}
else {
showContactRequiredMessage(view);
}
In another (sub)activity, I do the following:
contactUri = intent.getParcelableExtra(MainActivity.CONTACT_URI);
String[] projection = new String[] {
ContactsContract.Contacts.Data._ID,
ContactsContract.Contacts.Data.MIMETYPE,
ContactsContract.Contacts.Data.DATA1,
ContactsContract.Contacts.Data.DATA2,
ContactsContract.Contacts.Data.DATA3,
ContactsContract.Contacts.Data.DATA4,
ContactsContract.Contacts.Data.DATA5,
ContactsContract.Contacts.Data.DATA6,
ContactsContract.Contacts.Data.DATA7,
ContactsContract.Contacts.Data.DATA8,
ContactsContract.Contacts.Data.DATA9,
ContactsContract.Contacts.Data.DATA10,
ContactsContract.Contacts.Data.DATA11,
ContactsContract.Contacts.Data.DATA12,
ContactsContract.Contacts.Data.DATA13,
ContactsContract.Contacts.Data.DATA14,
ContactsContract.Contacts.Data.DATA15
};
Cursor contactResults = getContentResolver().query(contactUri, projection, null, null, null);
The last line throws the exception java.lang.IllegalArgumentException: Invalid column <any column after _ID>
My app doesn't require all of the data in reality I just want to see what is available, I will most likely need first name, last name, phone, and email.
My issue is the MIME type that I set on the intent when I request the contact info. The documentation states ContactsContract.Contacts.CONTENT_TYPE should be used. However, if I use, something like ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE, I can get display name and phone number. I am not sure if this means I will need to make multiple queries to get everything (the information shown in the contact picker changes when changing the type requested).
TL;DR: Used the "wrong" content type when creating the intent to select a contact.
As mentioned in my comment to your answer, you should be able to get the information expected without using a specific CONTENT_TYPE like CommonDataKinds.Phone.CONTENT_TYPE.
The problem I see in your code is that you're trying to access Data table info from a Contacts table uri.
The ContactsContract api stored info on 3 main tables: Contacts, RawContacts and Data.
You were given a contactUri which points to an entry in the Contacts table, use the following code to read Data entries related to that contact:
long contactId = ContentUris.parseId(contactUri);
String projection = String[] { Data.MIMETYPE, Data.DISPLAY_NAME, Data.DATA1 };
String selection = Data.CONTACT_ID + " = " + contactId;
Cursor cursor = getContentResolver().query(Data.CONTENT_URI, projection, selection, null, null);
while (cursor != null && cursor.moveToNext()) {
String mime = cursor.getString(0);
String name = cursor.getString(1);
String info = cursor.getString(2);
if (mime.equals(CommonDataKinds.Email.CONTENT_ITEM_TYPE)) {
Log.d(TAG, name + ": email = " + info;
}
if (mime.equals(CommonDataKinds.Phone.CONTENT_ITEM_TYPE)) {
Log.d(TAG, name + ": phone = " + info;
}
// Add more mimetypes here if needed...
}
if (cursor != null) {
cursor.close();
}
I have wrote an android app that uses voice recognition and save voice into a string.Now i can access to different part of this string and for example when i say call dad i need to retrieve dad's number from contacts.
private void call() {
Intent in=new Intent(Intent.ACTION_CALL,Uri.parse("0000000000"));
try{
startActivity(in);
}
catch (android.content.ActivityNotFoundException ex){
Toast.makeText(getApplicationContext(),"yourActivity is not founded",Toast.LENGTH_SHORT).show();
}
}
I know this function but instead of giving Uri.parse the actual number, i need to pass dad's number to it.For example something like Uri.parse(dad.PhoneNumber).How can i retrieve a phone number from contacts by using a name ? Thanks.
You need to obtain the number from a contact you know only the name, so:
// Define the fields that the query will return
String[] PROJECTION = new String[] {
ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER
};
ContentResolver cr = getContentResolver();
// Execute the query and receive the cursor with the results
Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " LIKE ?",
new String[] { "Name of the Contact" },
null );
Change the "Name of the contact" with your contact name...
Now you can get the value from cursor
// First discover the index of the desired field (Number)
final int indexNumber = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
String number = cursor.getString(indexNumber);
Then you can use your intent.
PS: The example uses a LIKE operator, because of this you can find more than one result in the cursor. Adapt to you necessity.
Can somebody help me on how to get all contacts per account? Meaning, I want to put a condition which will determine if the contact is from the phone (created by user) or from google and some other sync sources because as of now I was getting all contacts and its the combination of all sync sources e.g. local contacts, google or even yahoo contacts ?
Can somebody help me on how to get all contacts per account?
You can use next snippet to retrieve contacts for a particular account type:
String where = RawContacts.ACCOUNT_TYPE+ "=?";
String[] args = { accountType };
Cursor contacts = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, where, args, null);
int numberIndex = contacts.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
int displayNameIndex = contacts.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
for (contacts.moveToFirst(); !contacts.isAfterLast(); contacts.moveToNext()) {
String number = contacts.getString(numberIndex);
String displayName = contacts.getString(displayNameIndex);
// do something with account contacts
}
contacts.close();
To filter plain phone contacts (not connected to any account) you can use:
String where = RawContacts.ACCOUNT_TYPE+ " IS NULL";
I query the CallLog.Calls provider in order to retrieve a list of calls from a certain contact, based on the contact's display name. In particular, I use this query:
String selection = CallLog.Calls.CACHED_NAME + "= ?";
String dispName = dataCollector.getDisplayName();
Cursor callCursor =
cr.query(callLogUri, callLogProjection, selection,
new String[] {dispName},CallLog.Calls.DATE + " DESC");
The dataCollector object is used to hold information from queries based on a given contact id.
The problem is that this code only returns one call for the given contact. I can't understand why. Any clues?
int i=0;
while(cursor.moveToNext())
{
Sring id = cursor.getString(cursor.getColumnIndex(CallLog.Calls._ID));
numbersTemp[i]=cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER));
valuesTemp[i]=cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME));
i++;
}