Context:
I wrote a small easy dialer for android which dials telephone numbers
for contacts.
I use Intent.ACTION_CALL and pass in "tel:" for contacts with just one tel number or with a preferred default number
Within the app I have the contact's lookup_key so that I can access the contact
Question:
I want to initiate a call to a Contact not to a number so that Android:
if contact has 2+ numbers: will fire up a phone number selection dialog and then initiate the call
if the contact has just 1 number: just initiate the call
I could of course implement a popup from scratch but I'd prefer to delegate to a standard action so that the user has the very same UX as using the standard dialer.
You can use something like this to prompt the user to choose the contact, then which phone number to call (if there is more than one)... than pass that to the intent to make the call:
Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
startActivityForResult(intent, 1);
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
Uri contactData = data.getData();
String theID = contactData.toString());
//MAKE YOUR CALL .. do whatever... example:
ContentResolver contentResolver = getContentResolver();
Uri contactData = Uri.parse(theID);
Cursor cur = contentResolver.query(contactData, null, null, null, null);
String theNumber = cur.getString(cur.getColumnIndex("data4"));
cur.close();
Intent my_callIntent = new Intent(Intent.ACTION_CALL);
my_callIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK );
my_callIntent.setData(Uri.parse("tel:" + theNumber));
startActivity(my_callIntent);
}
}
Its not pretty or perfect, probably needs some modifications, just kinda going off the top of my head but hopefully you get the idea.
Related
I can easily get a list of every email address for every Contact using the following example snippets:
//...
private val getPerson = registerForActivityResult(PickContact()) {
it?.also { contactUri ->
val personDetails = ContactForPerson("", "", "")
val projection = arrayOf(
ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY, //String
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY,//String
ContactsContract.CommonDataKinds.Email.ADDRESS, //String
)
context?.contentResolver?.query(contactUri, projection, null, null, null)?.apply {
moveToFirst()
personDetails.apply {
uri = getStringOrNull(0)
name = getString(1)
email = getStringOrNull(2)
}
close()
}
}
}
//...
fab.setOnClickListener {
//...
getPerson.launch(0)
//...
}
//...
class PickContact : ActivityResultContract<Int, Uri?>() {
override fun createIntent(context: Context, input: Int?) =
Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI).also {
it.type = ContactsContract.CommonDataKinds.Email.CONTENT_TYPE
}
override fun parseResult(resultCode: Int, intent: Intent?): Uri? =
if (resultCode == RESULT_OK) intent?.data else null
}
The question is, since I already have some information about a Contact, is there a way for me to filter the giant list of every email address for every Contact to only show me the email addresses for a single Contact?
I noticed Get specific contact information from URI returned from Intent.ACTION_PICK, but the information is rather dated and it's not clear if the READ_CONTACTS permission is required, which is not desired.
Thank you.
It seems you're calling an EMAIL-PICKER and not a CONTACT-PICKER, by setting the intent type to Email.CONTENT_TYPE.
This means the user will be choosing a specific email in the device's default contacts app.
The result you're then getting from the picker is not a contactUri, rather a dataUri - i.e. a uri that points to a specific row in the Data table, which only allows you to get info about that specific row, in this case it must be an email row.
This also means your projection is a bit funny by using fields under CommonDataKinds.Phone.X, this doesn't matter too much as these fields are inherited from Data.CONTENT_URI, but to prevent confusion you should probably replace these with:
Data.LOOKUP_KEY,
Data.DISPLAY_NAME_PRIMARY,
Email.ADDRESS,
Now, if you want all the contact's email rather then a single one, you should not set the intent type - this will launch a contact picker which will allow you to get the contact's emails + phones + name by retrieving the Entity as shown here.
I want to read all contacts and use those in my application. i read all related topics but my implementation is very ِdifferent...
i want to Achieve this form :
see Image
1-user can choose specific contacts
2- Theirs information must add in application listview
3-and user can Choose silent/Normal status for contacts that he choosen.
How i can get contact based on this scenario ?
use explicit intent and startActivityForResult() for getting contacts
static final int PICK_CONTACT_REQUEST = 1; // The request code
...
private void pickContact() {
Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
}
===============================
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check which request it is that we're responding to
if (requestCode == PICK_CONTACT_REQUEST) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// Get the URI that points to the selected contact
Uri contactUri = data.getData();
// We only need the NUMBER column, because there will be only one row in the result
String[] projection = {Phone.NUMBER};
// Perform the query on the contact to get the NUMBER column
// We don't need a selection or sort order (there's only one result for the given URI)
// CAUTION: The query() method should be called from a separate thread to avoid blocking
// your app's UI thread. (For simplicity of the sample, this code doesn't do that.)
// Consider using CursorLoader to perform the query.
Cursor cursor = getContentResolver()
.query(contactUri, projection, null, null, null);
cursor.moveToFirst();
// Retrieve the phone number from the NUMBER column
int column = cursor.getColumnIndex(Phone.NUMBER);
String number = cursor.getString(column);
// Do something with the phone number...
}
}
}
Then add details to your applications listview.do as you need to
Don't know if you figure this out after a year but here's step 1:
private static final int CONTACT_PICKER_RESULT = 1001;
...
public void methodname() {
// By using ContactsContract.CommonDataKinds.Phone.CONTENT_URI, the user is
// presented with a list of contacts, with one entry per phone number.
// The selected contact is guaranteed to have a name and phone number.
Intent contactPickerIntent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
startActivityForResult(contactPickerIntent, CONTACT_PICKER_RESULT);
return true;
}
I want to open Contacts pick activity from my application with search field should be filled programmatically.
Can anyone suggest what URI shoud i use or anything to put in intent's extra?
private static final int PICK_CONTACT_SUBACTIVITY = 2;
private void startContactActivity() {
Uri uri = Uri.parse("content://contacts/people");
// Here in this normally we pass number e.g. Uri.encode("987") but i want to pass name as filter is it possible?
// I have also tried
//uri = Uri.withAppendedPath(android.provider.ContactsContract.Contacts.CONTENT_FILTER_URI, Uri.encode("pra"));
//uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode("pra"));
uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI, Uri.encode("pra"));
Intent intent = new Intent(Intent.ACTION_PICK, uri);
startActivityForResult(intent, PICK_CONTACT_SUBACTIVITY);
}
Can anyone suggest how can i achieve this?
You can follow :
how-to-pick-contact-number-from-phone-book-of-android-in-to-my-application
or
developer.android.com/training/contacts-provider/modify-data
It seems that it is not possible to specify a filter programmatically.
The Android SDK documentation states (in the chapter "Retrieval and modification with intents") that for ACTION_PICK you can only use one of
Contacts.CONTENT_URI, Phone.CONTENT_URI, StructuredPostal.CONTENT_URI, Email.CONTENT_URI. This is indirectly a filter (all contacts, all with phone numbers, all with postal address, or all with email), but it is limited to this.
I am trying to access the contact details of a person which i selected from contact picker intent.
here is what my contact looks like:
Here is the code which i am using to open the contact picker:
Intent pickContactIntent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
Now, i am able to get Phone number and email using following API's:
android.provider.ContactsContract.CommonDataKinds.Email;
android.provider.ContactsContract.CommonDataKinds.Phone;
but i am not able to get the address which is stored. I want to get both the address value and custom tag associated with it.
Any help is appreciated.
if You have a contact ID and you want to fetch the Postal Address then use this :
Uri postal_uri = ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI;
Cursor postal_cursor = getContentResolver().query(postal_uri,null, ContactsContract.Data.CONTACT_ID + "="+contactId.toString(), null,null);
while(postal_cursor.moveToNext())
{
String Strt = postal_cursor.getString(postal_cursor.getColumnIndex(StructuredPostal.STREET));
String Cty = postal_cursor.getString(postal_cursor.getColumnIndex(StructuredPostal.CITY));
String cntry = postal_cursor.getString(postal_cursor.getColumnIndex(StructuredPostal.COUNTRY));
}
postal_cursor.close();
http://gabrielaradu.com/?p=367
https://stackoverflow.com/a/13471370/2480911
I want to display the phone's contact log directly inside my application on a button click, in order to select a contact and its number. Can anybody help me with this?
I got the answer. :)
String myData = "content://contacts/people/";
Intent myActivity2 = newIntent(Intent.ACTION_VIEW, Uri.parse( myData) );
startActivity(myActivity2);
or we can use
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
startActivityForResult(intent, 2);