I want to retrieve the mobile number from the contacts (I want to send an sms). Here my code:
//Selecting the contact
Button buttonPickContact = (Button)findViewById(R.id.pickcontact);
buttonPickContact.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, RQS_PICK_CONTACT);
}});
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
Cursor cursor = null;
mName.setText(context.getString(R.string.not_available));
mNumber.setText(context.getString(R.string.not_available));
if(requestCode == RQS_PICK_CONTACT && resultCode == RESULT_OK && data != null){
Log.d(TAG, "requestCode, resultCode, data ok");
Uri uri = data.getData();
try{
String[] projection = new String[] {ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.HAS_PHONE_NUMBER};
// cursor = getContentResolver().query(uri, projection, null, null, null);
cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
Log.d(TAG, "Trying to retrieve the name and the number");
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String hasNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.HAS_PHONE_NUMBER));
Log.d(TAG, "hasNumber "+hasNumber);
mName.setText(name);
if(hasNumber.trim().equals("1")){
Log.d(TAG, "contact has telephone number");
//set name and number
String phoneNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
mNumber.setText(phoneNumber);
}
}catch(Exception ex){
CharSequence text = context.getString(R.string.cannot_choose_contact);
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
if(cursor!= null && !cursor.isClosed()){
cursor.close();
}
}else{
CharSequence text = context.getString(R.string.cannot_choose_contact);
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
}
I am getting: Failed to read row 0, column -1 from CursorWindow...
How do I get the phone number - am I trying to retrieve it from the right column?
Thanks in advance for your answers,
The detailed data for a contact is contained in a separate table from the main contact itself (see the Contacts API guide for more detail). Since you're sending an SMS, it might be more useful to only get the contacts who have a phone number associated, so you might as well go straight for the table which contains phone numbers. For the URI, I use:
CommonDataKinds.Phone.CONTENT_URI
Then you don't have to worry about HAS_PHONE_NUMBER. At a glance, the rest of your code looks right or very close. If you wanted to continue down your original path, you'd have to do a separate query on this table anyway, but provide it the ID of the contact that you initially found.
Use a CursorLoader to do queries. Always. If you continue to do queries on the UI thread, eventually you'll run into a situation where you hang the system and get an ANR.
You're requesting the user to pick contacts from the Contacts table, so you'll get back a URI that points to a contact in Contacts.
A trick for handling this is to strip the contact's LOOKUP_KEY from the returned URI using
Uri.getLastPathSegment(). Then search ContactsContract.Data for the LOOKUP_KEY and the
MIMETYPE value CommonDataKinds.Email.CONTENT_ITEM_TYPE. Based on your code, this would be:
mLookupKey = uri.getLastPathSegment();
String SELECTION = Data.LOOKUP_KEY + " = ? " +
" AND " +
Data.MIMETYPE + " = ?";
String[] selectionArgs = {
mLookupKey,
Email.CONTENT_ITEM_TYPE
};
...
Related
I have created a class to find phone number in my contact.
It looks like this:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if(resultCode == RESULT_OK){
if(requestCode == 1){
Uri returnUri = data.getData();
Cursor cursor = getContentResolver().query(returnUri, null,null,null, null);
if(cursor.moveToNext()){
//get ID
int columnIndex_ID = cursor.getColumnIndex(ContactsContract.Contacts._ID);
String contactID = cursor.getString(columnIndex_ID);
//get name
String contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
name.setText(contactName);
int columnIndex_HASPHONENUMBER = cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER);
String hasPhoneNumber = cursor.getString(columnIndex_HASPHONENUMBER);
if(hasPhoneNumber.equals("1")){
Cursor cursorNum = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactID,
null,
null
);
//get the first phone number
if(cursorNum.moveToNext()){
int columnIndex_number = cursorNum.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
String stringNumber = cursorNum.getString(columnIndex_number);
phoneNumber.setText(stringNumber);
}
}else{
phoneReceiver.setText("No Phone Number");
}
}else{
Toast.makeText(ActivityPager.this,"No Data!", Toast.LENGTH_SHORT).show();
}
}
}
}
but, in my mind, i need to get the currently phone number in currently device that i use.
could i get it?
It's just a suggestion. If you want to get the contact name and details from the device means tou can do the following.
But you need to have stored the phone number on the SIM card, and there´s no other way to get your "own number".
Read the phone number from SIM by using telephones manager.
TelephonyManager tm = (TelephonyManager)this.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
String myPhoneNumber = tm.getLine1Number();
You are reading all the phone numbers from your phone. So compare this and get other details.
I am following this example retrieve list of contacts to retrieve contacts from android device.
It gives all the contacts which includes email contacts and some empty contacts.
I tried modifying ContactsContract like ContactsContract.Contacts.HAS_PHONE_NUMBERin the projection and selection to get mobile contacts but nothing worked out.
String[] PROJECTION = {ContactsContract.Contacts._ID,ContactsContract.Contacts.LOOKUP_KEY,
ContactsContract.Contacts.DISPLAY_NAME,ContactsContract.Contacts._ID,
SORT_ORDER,ContactsContract.Contacts.HAS_PHONE_NUMBER};
String SELECTION =
ContactsContract.Contacts.DISPLAY_NAME +
"<>''" + " AND "ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1";
Any idea to get only contacts which has mobile numbers?
I have created this library to solve all your queries. It will only save contacts with at least one email or phone number. Also it will remove duplicates from emails and phone numbers from same contacts (created by 3rd party apps like whatsapp).
Suggestions are welcome.
Link : https://github.com/raghavsatyadev/ContactFetcher/
You can use this code to get all contact names and numbers
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null);
while (phones.moveToNext())
{
String contactName=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String contactNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
phones.close();
Show only contacts with phone number and open contact list intent:
Intent pickContactIntent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI); // Uri.parse("content://contacts")
// Show only user contacts with phone numbers
pickContactIntent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE); // Show only user contacts with phone numbers
startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
Get the phone number from response/contact:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PICK_CONTACT_REQUEST) {
if (resultCode == RESULT_OK) {
Uri contactUri = data.getData();
String[] projection = {ContactsContract.CommonDataKinds.Phone.NUMBER};
Cursor cursor = getActivity().getContentResolver().query(contactUri, projection, null, null, null);
if (cursor == null) {
// show error msg
return;
}
cursor.moveToFirst();
int column = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
if (column >= 0) {
String phoneNo = cursor.getString(column);
sendSmsMessage(phoneNo);
} else {
// show error msg
}
cursor.close();
}
}
}
Make sure, you also handle runtime permissions in API 23+
android.permission.READ_CONTACTS
I am trying to select contacts available from the phone programmatically and I am using the below code
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
startActivityForResult(intent, 1);
However the question is How can I select multiple contacts at a time by using a checkbox in the contacts page?
You will have to read the Contacts programmatically and display them in a ListView in your Activity. Use CheckBoxs in the ListView items and allow multiple items to be selected. Find a simple example/tutorial for a ListView and start from there.
There are several reasons why it is better to create a custom ListView rather than using Intent(Intent.ACTION_GET_CONTENT);:
There may not be a way to select multiples as you have requested.
Even if you find a way to select multiples, it will be different on
every OS version and device, and might not work on all of them.
If there are multiple applications installed on any device that can
handle ACTION_GET_CONTENT, then a chooser will be presented to the
user and he will have to select one of those. The user's selection
may not support selecting multiple contacts.
Here is an example that reads your system contacts:
Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);
while (cursor.moveToNext()) {
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String hasPhone = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if("1".equals(hasPhone) || Boolean.parseBoolean(hasPhone)) {
// You know it has a number so now query it like this
Cursor phones = myActivity.getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId, null, null);
while (phones.moveToNext()) {
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
int itype = phones.getInt(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
final boolean isMobile =
itype == ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE ||
itype == ContactsContract.CommonDataKinds.Phone.TYPE_WORK_MOBILE;
// Do something here with 'phoneNumber' such as saving into
// the List or Array that will be used in your 'ListView'.
}
phones.close();
}
}
public static final int REQUEST_CODE_PICK_CONTACT = 1;
public static final int MAX_PICK_CONTACT= 10;
private void launchMultiplePhonePicker() {
Intent phonebookIntent = new Intent("intent.action.INTERACTION_TOPMENU");
phonebookIntent.putExtra("additional", "phone-multi");
phonebookIntent.putExtra("maxRecipientCount", MAX_PICK_CONTACT);
phonebookIntent.putExtra("FromMMS", true);
startActivityForResult(phonebookIntent, REQUEST_CODE_PICK_CONTACT);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode==RESULT_OK)
{
if(requestCode == REQUEST_CODE_PICK_CONTACT )
{
Bundle bundle = data.getExtras();
String result= bundle.getString("result");
ArrayList<String> contacts = bundle.getStringArrayList("result");
Log.i(TAG, "launchMultiplePhonePicker bundle.toString()= " + contactsPick.toString() );
}
}
super.onActivityResult(requestCode, resultCode, data);
}
I'm trying to allow a user to select a phone number from a contact using the contact picker. However, right now all the examples I see online show how you can select a contact, but I am hoping to have a second screen then pop up if that contact has multiple phone numbers so you can specify which one you want to select (the way that text message lets you do so when you select a contact).
My question is, do you have to gather all of the numbers and then ask the user to select a number, or is this functionality already built into Android? I'm hoping I just forgot a flag or something.
Alternatively, you can initially display the phone numbers associated with each contact in the Contact Picker and select one that way. Launch contact picker this way (note the different URI than my other answer):
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
startActivityForResult(intent, REQUEST_PICK_CONTACT);
Then, in onActivityResult():
Uri result = data.getData();
Log.v(TAG, "Got a result: " + result.toString());
// get the phone number id from the Uri
String id = result.getLastPathSegment();
// query the phone numbers for the selected phone number id
Cursor c = getContentResolver().query(
Phone.CONTENT_URI, null,
Phone._ID + "=?",
new String[]{id}, null);
int phoneIdx = c.getColumnIndex(Phone.NUMBER);
if(c.getCount() == 1) { // contact has a single phone number
// get the only phone number
if(c.moveToFirst()) {
phone = c.getString(phoneIdx);
Log.v(TAG, "Got phone number: " + phone);
loadContactInfo(phone); // do something with the phone number
} else {
Log.w(TAG, "No results");
}
}
I was able to do this by creating a second dialog which shows all the phone numbers associated with a contact.
First, call this somewhere in your code:
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, REQUEST_PICK_CONTACT);
Then in onActivityResult() use this to decide if the selected contact has multiple phone numbers, and display a dialog if so:
Uri result = data.getData();
Log.v(TAG, "Got a result: " + result.toString());
// get the contact id from the Uri
String id = result.getLastPathSegment();
// query for phone numbers for the selected contact id
c = getContentResolver().query(
Phone.CONTENT_URI, null,
Phone.CONTACT_ID + "=?",
new String[]{id}, null);
int phoneIdx = c.getColumnIndex(Phone.NUMBER);
int phoneType = c.getColumnIndex(Phone.TYPE);
if(c.getCount() > 1) { // contact has multiple phone numbers
final CharSequence[] numbers = new CharSequence[c.getCount()];
int i=0;
if(c.moveToFirst()) {
while(!c.isAfterLast()) { // for each phone number, add it to the numbers array
String type = (String) Phone.getTypeLabel(this.getResources(), c.getInt(phoneType), ""); // insert a type string in front of the number
String number = type + ": " + c.getString(phoneIdx);
numbers[i++] = number;
c.moveToNext();
}
// build and show a simple dialog that allows the user to select a number
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.select_contact_phone_number_and_type);
builder.setItems(numbers, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
String number = (String) numbers[item];
int index = number.indexOf(":");
number = number.substring(index + 2);
loadContactInfo(number); // do something with the selected number
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(this);
alert.show();
} else Log.w(TAG, "No results");
} else if(c.getCount() == 1) {
// contact has a single phone number, so there's no need to display a second dialog
}
I know this is an old question but I hope it helps.
Just in case someone stumbles across this again.
Another alternative to the other answers is the library https://github.com/codinguser/android_contact_picker
Full Disclosure: I am the author of this library
it is simple explained on android developers reference:
https://developer.android.com/training/contacts-provider/modify-data.html#InsertEdit
and simple append code:
String phoneNumber = "+01 123 456 789";
Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
intent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
intent.putExtra(ContactsContract.Intents.Insert.PHONE, phoneNumber);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, REQUEST_CODE_ADD_PHONE_CONTACT);
}
if you needed activity result, you must listen to onActivityResult event on Activity by REQUEST_CODE_ADD_PHONE_CONTACT variable.
I'm trying to call the contact picker, get the persons name, phone and e-mail into strings and send them to another activity using an intent. So far this works:
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, 1);
// ...
#Override
public void onActivityResult(int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
Uri contactData = data.getData();
Cursor c = managedQuery(contactData, null, null, null, null);
if (c.moveToFirst()) {
String name = c.getString(c.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
Intent intent = new Intent(CurrentActivity.this, NewActivity.class);
intent.putExtra("name", name);
startActivityForResult(intent, 0);
}
}
}
But if i add in:
String number = c.getString(c.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
it force closes
Maybe theres another way to get their number?
Phone Numbers
Phone numbers are stored in their own table and need to be queried separately. To query the phone number table use the URI stored in the SDK variable ContactsContract.CommonDataKinds.Phone.CONTENT_URI. Use a WHERE conditional to get the phone numbers for the specified contact.
if (Integer.parseInt(cur.getString(
cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
Cursor pCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",
new String[]{id}, null);
while (pCur.moveToNext()) {
// Do something with phones
}
pCur.close();
}
Perform a second query against the Android contacts SQLite database. The phone numbers are queried against the URI stored in ContactsContract.CommonDataKinds.Phone.CONTENT_URI. The contact ID is stored in the phone table as ContactsContract.CommonDataKinds.Phone.CONTACT_ID and the WHERE clause is used to limit the data returned.
Email Addresses
Querying email addresses is similar to phone numbers. A query must be performed to get email addresses from the database. Query the URI stored in ContactsContract.CommonDataKinds.Email.CONTENT_URI to query the email address table.
Cursor emailCur = cr.query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?",
new String[]{id}, 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));
}
emailCur.close();
As with the phone query the field names for the email table are also stored under ContactsContract.CommonDataKinds. The email query is performed on the URI in ContactsContract.CommonDataKinds.Email.CONTENT_URI and the WHERE clause has to match the ContactsContract.CommonDataKinds.Email.CONTACT_ID field. Since multiple email addresses can be stored loop through the records returned in the Cursor.
More tutorials here
This method requires Android API version 5 or higher.
Building on the accepted answer, if you want to jump straight to the desired email address and not require the contacts permission use something like this:
private static final int REQUEST_CODE_EMAIL = 1;
void startSelectingEmail() {
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Email.CONTENT_URI);
startActivityForResult(intent, REQUEST_CODE_EMAIL);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_EMAIL) {
Uri emailUri = data.getData();
Cursor emailCursor = getContext().getContentResolver().query(emailUri, null, null, null, null);
if (emailCursor != null) {
if (emailCursor.moveToFirst()) {
String email = emailCursor.getString(
emailCursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Email.DATA));
String emailType = emailCursor.getString(
emailCursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Email.TYPE));
Log.d(TAG, "Email: " + emailType + " " + email);
}
emailCursor.close();
}
}
}
This doesn't require the contacts permission to read the email address like the double query methods above. It also makes it so that you do not need to write UI for the user to select the appropriate email address for contacts with multiple emails, the user selects a specific email in the Contacts app so you only get one result.
The cursor comes back with quite a few columns in addition to just email address like display name, though that has only been verified on a Nexus 5 running Android M.