i am starting contact app using intent and selecting the contact from the list each time i choose different contact but i am getting the same contact again and again and i also don't know which contact it is? I have no idea what is going on?
Here is my code
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);
and in activity result
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
Cursor c = null;
try
{
if(requestCode == PICK_CONTACT)
{
Uri contactData = data.getData();
c = getContentResolver().query(Phone.CONTENT_URI, null, null, null, null);
if (c.moveToFirst())
{
reciever = c.getString(c.getColumnIndex(Phone.NUMBER));
reciever = Main.removeCharacters(reciever);
int size = reciever.length();
Log.v(TAG, "To send "+reciever);
reciever = reciever.substring(size - 6, size);
}
new UploadPic().execute("");
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
finally
{
if(c != null)
{
c.close();
Log.v(TAG, "Cursor Closed");
}
}
}
You are assigning the contact URI to contactData yet you do not use it. When you call query() pass in contactData for the first argument rather than Phone.CONTENT_URI.
Related
I'm developing an app, and in that app I have one button, named 'choose sound'. When user will click this button, he/she should be asked to choose any audio file from the file manager/memory.
So, I know that for this, I'll have to use Intent.Action_GetData. I'm doing the same:
//code start
Intent intent = new Intent();
intent.setType("audio/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent,1);
#Override
protected void onActivityResult(int requestCode,int resultCode,Intent data){
if(requestCode == 1){
if(resultCode == RESULT_OK){
//the selected audio.
Uri uri = data.getData();
int SoundID=soundPool.Load(uri.toString(), 1);
//SoundPool is already constructed and is working perfectly for the resource files
PlaySound(SoundID);
//PlaySound method is already defined
}
}
super.onActivityResult(requestCode, resultCode, data);
}
//end of code
but it's not working
Now, in OnActivityResult, I'm not getting that how to load the proper URI of the file selected by user, because before Android 4.4, it returns the different URI and after Android 4.4 it returns the different URI on intent.GetData();. Now, what I have to do?
Also, I know that for playing the audio file, I'll have to use SoundPool, and I have the code for that too, in fact it's working fine for the resource/raw/audio files, but how to load/play files in SoundPool from this URI?
In your onActivityResult(), do the following changes:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK && data != null)
{
String realPath = null;
Uri uriFromPath = null;
realPath = getPathForAudio(YourActivity.this, data.getData());
uriFromPath = Uri.fromFile(new File(realPath)); // use this uriFromPath for further operations
}
}
Add this method in your Activity:
public static String getPathForAudio(Context context, Uri uri)
{
String result = null;
Cursor cursor = null;
try {
String[] proj = { MediaStore.Audio.Media.DATA };
cursor = context.getContentResolver().query(uri, proj, null, null, null);
if (cursor == null) {
result = uri.getPath();
} else {
cursor.moveToFirst();
int column_index = cursor.getColumnIndex(MediaStore.Audio.AudioColumns.DATA);
result = cursor.getString(column_index);
cursor.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally {
if (cursor != null) {
cursor.close();
}
}
return result;
}
Hope It will do your job. You can play audio using MediaPlayer class also
You can put below codes in your project when you want to select audio.
Intent intent_upload = new Intent();
intent_upload.setType("audio/*");
intent_upload.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent_upload,1);
And override onActivityResult in the same Activity, as below
#Override
protected void onActivityResult(int requestCode,int resultCode,Intent data){
if(requestCode == 1){
if(resultCode == RESULT_OK){
//the selected audio.
Uri uri = data.getData();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
Try to get the path :
//method to get the file path from uri
public String getPath(Uri uri) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
String document_id = cursor.getString(0);
document_id = document_id.substring(document_id.lastIndexOf(":") + 1);
cursor.close();
cursor = getContentResolver().query(
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null);
cursor.moveToFirst();
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
cursor.close();
return path;
}
then load it :
s2 = soundPool.load(YOU_PATH, PRIORITY);
I my app a user can create or choose like this:
Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
intent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
intent.putExtra(ContactsContract.Intents.Insert.NAME,
user.getName());
intent.putExtra(INTENT_KEY_FINISH_ACTIVITY_ON_SAVE_COMPLETED,
true);
startActivityForResult(intent, ADD_CONTACT);
Then in onActivityResult:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data == null) {
Log.e(TAG, "DATA NULL");
return;
}
if (requestCode == ADD_CONTACT) {
if (resultCode == RESULT_OK) {
//QUESTION HERE
Uri contactData = data.getData();
Cursor c = getContentResolver().query(contactData, null, null,
null, null);
} else {
Log.e(TAG, "RESULT NOT OK!");
}
}
}
Question: Is there any way to decide, if user created or chose an existing contact ? :)
You can get the number of contacts before user action and after it (with this: how many contacts in contact list). Than just compare.
You can keep count of the contacts in case you dont need the information regarding the change/added contact.
In case you need what has changed/added you can check for this answer for observer
Hope this helps
My goal is to only display contacts with phone number to user and let user select few contacts which I want to store locally.
I have used various options in place of ContactsContract.Contacts.CONTENT_URI in below method. But I am getting lot many of the contacts (many are junk with only email ids) displayed.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.contact_selector);
((Button)findViewById(R.id.btnphonecontactlist)).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent contactIntent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(contactIntent, 1);
}
});
}
If I pass ContactsContract.Contacts.CONTENT_URI as parameter for above method and in case of below handler method, the String[] for the query method as projection parameters (which are shown commented), the method fails with java.lang.IllegalArgumentException. If I pass null in below method, then whatever contact I select, I don't find any column related to phone number or email.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(data != null)
{
Uri uri = data.getData();
if(uri != null)
{
Cursor c = null;
try
{
c = getContentResolver().query(uri, null
// new String[] {
//ContactsContract.CommonDataKinds.Phone.NUMBER,
//ContactsContract.CommonDataKinds.Phone.TYPE},
, null, null, null);
if(c != null && c.moveToFirst())
{
String number = c.getString(0);
String type = c.getString(1);
}
}
finally
{
if(c != null && !c.isClosed())
c.close();
}
}
}
}
Is there any way to display only contacts visible to user usually when user goes to phone book and which has phone numbers available?
I tried going through all the threads in stackoverflow and other sites, but could not find any solution which resolve issue around this though many people have posted the issue. I haven't worked much with the Android platform and I might have missed out certain minor details and I believe there must be an easy way to achieve this.
Kindly suggest. Appreciate your help.
Thanks.
Please use below code
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
startActivityForResult(intent, 1);
*-> Add a permission to read contacts data to your application manifest.
<uses-permission android:name="android.permission.READ_CONTACTS"/>
-> Use Intent.ACTION_PICK in your Activity
Intent contactPickerIntent = new Intent(Intent.ACTION_PICK,
ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
startActivityForResult(contactPickerIntent, RESULT_PICK_CONTACT);
-> Then Override the onActivityResult() and retrieve the ID,Phone number and Name in the data.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// check whether the result is ok
if (resultCode == RESULT_OK) {
// Check for the request code, we might be usign multiple startActivityForReslut
switch (requestCode) {
case RESULT_PICK_CONTACT:
Cursor cursor = null;
try {
String phoneNo = null ;
String name = null;
Uri uri = data.getData();
cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
int phoneIndex =cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
phoneNo = cursor.getString(phoneIndex);
textView2.setText(phoneNo);
} catch (Exception e) {
e.printStackTrace();
}
break;
}
} else {
Log.e("MainActivity", "Failed to pick contact");
}
}
This will work check it out*
Following code will do what you want.
Intent intent = new Intent(Intent.ACTION_PICK,ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
startActivityForResult(Intent.createChooser(intent, "Contact"), PICK_CONTACT);
Uri uri = Uri.parse("content://contacts");
Intent intent = new Intent(Intent.ACTION_PICK, uri);
intent.setType(Phone.CONTENT_TYPE);
startActivityForResult(intent, REQUEST_CODE);
Use this:
Intent intent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts/people"));
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
startActivityForResult(intent, 1);
This is my first strange result that I never expected. This is may be lack of skill in that area.
Well I had a button, through which I need to select an image from the phone gallery (probably from sdcard). I used implicit intent to call the phone gallery and got the absolute image path with startActivityForResult(). Immediately am calling another activity putting that path with startActivity().
According to my scenario I wrote the following code in the onClick() of button.
#Override
public void onClick(View v) {
upLoadPhoto();
}
protected void upLoadPhoto() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
intent.setType("image/*");
intent.putExtra("return-data", true);
System.out.println("select image");
startActivityForResult(intent, 1);
startActivity(next);
finish();
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1 && data != null && data.getData() != null){
Uri uri = data.getData();
if (uri != null) {
Cursor cursor = getContentResolver().query(uri, new String[] { android.provider.MediaStore.Images.ImageColumns.DATA }, null, null, null);
cursor.moveToFirst();
final String imageFilePath = cursor.getString(0);
System.out.println("Background : "+imageFilePath);
next.putExtra("backImagePath", imageFilePath);
cursor.close();
super.onActivityResult(requestCode, resultCode, data);
}
}
}
When I click the button, startActivity(next) is called first, then startActivityForResult(intent,1) is called. As am trying to get image path in the second activity through bundle object, am getting NullPointerException because of startActivity(next) is being called first.
I dropped my jaws when I saw my debugging point are not as expected. Hope I get exact reason to this issue.
Thanks
Aswin
What about moving the call to startActivity(next); into onActivityResult()... this way you will navigate to the other activity after getting the path
protected void upLoadPhoto() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
intent.setType("image/*");
intent.putExtra("return-data", true);
System.out.println("select image");
startActivityForResult(intent, 1);
finish();
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1 && data != null && data.getData() != null){
Uri uri = data.getData();
if (uri != null) {
Cursor cursor = getContentResolver().query(uri, new String[] { android.provider.MediaStore.Images.ImageColumns.DATA }, null, null, null);
cursor.moveToFirst();
final String imageFilePath = cursor.getString(0);
System.out.println("Background : "+imageFilePath);
next.putExtra("backImagePath", imageFilePath);
cursor.close();
startActivity(next);
super.onActivityResult(requestCode, resultCode, data);
}
}
}
You have call startActivity() inside onActivityResult() when your image is selected from Gallery successful. Because when startActivityForResult() it is going to Gallery for picking up the image and till then startActivity() is fired and you move to next Activity.
remove that startActivity(next) from that function and put it on onActivityResult after you retrieve your data
remove that startActivity(next) from that function and put it on onActivityResult after get 1 add Your Next Intent
How can I show the list of contacts in phonebook on a click of a button and then select one of the contacts from it and then retrieve its contact number?
I don’t want to make my custom list. Is there a way to use Android's built-in functionality?
TRY THIS-->
setContentView(R.layout.main);
contactNumber = (TextView)findViewById(R.id.contactnumber);
Button buttonPickContact = (Button)findViewById(R.id.pickcontact);
buttonPickContact.setOnClickListener(new Button.OnClickListener(){
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
startActivityForResult(intent, 1);
}});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == RQS_PICK_CONTACT){
if(resultCode == RESULT_OK){
Uri contactData = data.getData();
Cursor cursor = managedQuery(contactData, null, null, null, null);
cursor.moveToFirst();
String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
//contactName.setText(name);
contactNumber.setText(number);
//contactEmail.setText(email);
}
}
}
}
EDIT XML ADDED;
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/pickcontact"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Pick Contact" />
<TextView
android:id="#+id/contactnumber"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
I was doing the same thing in my application, and this is how to start a new intent for showing the list
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);
And this is how to process the result:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_CONTACT) {
if (resultCode == RESULT_OK) {
Uri contactData = data.getData();
String number = "";
Cursor cursor = getContentResolver().query(contactData, null, null, null, null);
cursor.moveToFirst();
String hasPhone = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.HAS_PHONE_NUMBER));
String contactId = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID));
if (hasPhone.equals("1")) {
Cursor phones = getContentResolver().query
(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = " + contactId, null, null);
while (phones.moveToNext()) {
number = phones.getString(phones.getColumnIndex
(ContactsContract.CommonDataKinds.Phone.NUMBER)).replaceAll("[-() ]", "");
}
phones.close();
// Do something with the number
}
else {
Toast.makeText(getApplicationContext(), "This contact has no phone number", Toast.LENGTH_LONG).show();
}
cursor.close();
}
}
}
}
PICK_CONTACT is a constant defined in the class.
Intent i=new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(i, PICK_REQUEST);
The Intent delivered to your onActivityResult() method will contain the Uri of the chosen contact -- you will get this by calling getData() on that Intent.
Here is a sample project that demonstrates this, with the logic being implemented in a retained fragment, so we hang onto the selected contact across configuration changes (e.g., user rotating the screen).
You can also use ACTION_GET_CONTENT for this, and I think that's the more modern pattern, though ACTION_PICK certainly works and is all I have sample code for at the time of this writing. If you are reading this in the future (hi, future!), it's possible that the linked-to sample has been updated to use ACTION_GET_CONTENT.
For Kotlin, the request code for fetching a contact
private val REQUEST_CONTACT = 201
Intent to launch the phone book
private fun fetchPhoneNo() {
val intent = Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI)
startActivityForResult(intent, REQUEST_CONTACT)
}
Get the phone number in onActivityResult
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_CONTACT && data?.data != null) {
val contactUri = data.data;
val crContacts = contentResolver.query(contactUri, null, null, null, null);
crContacts.moveToFirst()
val id = crContacts.getString(crContacts.getColumnIndex(ContactsContract.Contacts._ID));
if (Integer.parseInt(crContacts.getString(crContacts.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
val crPhones =
contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = ?",
arrayOf(id),
null)
crPhones.moveToFirst()
var phoneNo = crPhones.getString(
crPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
crPhones.close()
}
crContacts.close()
}
}
Here is the working code which I tried in API Level 29+
Step 1: Add Permission in AndroidManifest.xml
<uses-permission android:name="android.permission.READ_CONTACTS" />
Step 2: Code to open the contacts dialog on a button click
private static final int REQ_PICK_CONTACT = 3;
private static final int CONTACT_PERMISSION_CODE = 1;
// Onclick handler
public void openContacts(View view) {
if(checkContactPermission()) {
openContactsDialog();
} else {
requestContactPermission();
}
}
// If permission is granted, then open contact box
private void openContactsDialog() {
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, REQ_PICK_CONTACT);
}
// Check if the user has the permission granted
private boolean checkContactPermission() {
boolean result = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED;
return result;
}
// Invoke request permission dialog
private void requestContactPermission() {
String[] permission = {Manifest.permission.READ_CONTACTS};
ActivityCompat.requestPermissions(this, permission, CONTACT_PERMISSION_CODE);
}
// After the permission is granted, open the contact dialog
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == CONTACT_PERMISSION_CODE) {
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
openContactsDialog();
}
}
}
Step 3: Handle contact selection
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQ_PICK_CONTACT) {
if (resultCode == RESULT_OK) {
Cursor cursor1, cursor2;
Uri uri = data.getData();
cursor1 = getContentResolver().query(uri, null, null, null, null);
if(cursor1.moveToFirst()) {
String contactId = cursor1.getString(cursor1.getColumnIndex(ContactsContract.Contacts._ID));
String contactName = cursor1.getString(cursor1.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
String hasNumber = cursor1.getString(cursor1.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
if("1".equals(hasNumber)) {
cursor2 = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId, null, null);
while(cursor2.moveToNext()) {
String contactNumber = cursor2.getString(cursor2.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
// Use contactName and contactNumber for your purposes
}
cursor2.close();
}
}
cursor1.close();
//edtName.setText(contactName);
//edtNumber.setText(number);
}
}
}
Solution courtesy: Pick Contact | Android Studio | Java (no audio whatsoever and very little annotation)
In the Nexus 5X emulator that I tested this with:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
startActivityForResult(intent, 1);
Or:
Uri uri = Uri.parse("content://contacts");
Intent intent = new Intent(Intent.ACTION_PICK, uri);
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
startActivityForResult(intent, 1);
did not work for all contacts. I don't know why. But this works:
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, 1);
Add the PICK_CONTACT field:
private final int PICK_CONTACT = 55;
In onCreate():
viewPhonebook.setOnClickListener(v -> {
try {
Uri uri = Uri.parse("content://contacts");
Intent intent = new Intent(Intent.ACTION_PICK, uri);
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
startActivityForResult(intent, PICK_CONTACT);
}
catch (Exception e) {
e.printStackTrace();
}
});
In onActivityResult():
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case PICK_CONTACT:
Uri contactData = data.getData();
Cursor cursor = managedQuery(contactData, null, null, null, null);
cursor.moveToFirst();
String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
String contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
edtName.setText(contactName);
edtNumber.setText(number);
break;
}
}
}