I have an app that among other things is trying to set a specific sound to an individual contact. Everything works, it shows the sound as the ringtone for the contact when you view the contact info but when the contact calls, the default ringtone rings. Can anyone shed any light on what's wrong?
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case CONTACT_PICKER_RESULT:
Uri contactData = data.getData();
String contactId = contactData.getLastPathSegment();
Cursor localCursor = managedQuery(contactData, null, null, null, null);
localCursor.moveToFirst();
String str1 = localCursor.getString(localCursor.getColumnIndexOrThrow("_id"));
String str2 = localCursor.getString(localCursor.getColumnIndexOrThrow("display_name"));
Uri localUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, str1);
ContentValues localContentValues = new ContentValues();
localContentValues.put(ContactsContract.Data.RAW_CONTACT_ID, contactId);
localContentValues.put(ContactsContract.Data.CUSTOM_RINGTONE, ringtonePath);
getContentResolver().update(localUri, localContentValues, null, null);
Toast.makeText(this, "Ringtone assigned to: " + str2, 0).show();
break;
}
In case anybody stumbles across this wondering how to achieve this, I used parts of the ringdroid library to assign a tone to a contact
https://github.com/google/ringdroid
Related
My purpose is to set a list that comes from API which includes phonenumbers of the users of my app. So i only need to see contact that are in this list. But I dont know how set below code to do this. I mean in the below it opens contacts with all of the contact that are in the phone. I dont need to see the all the contacts but the ones that are in the given list
Intent contactPickerIntent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(contactPickerIntent,1);
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode){
case 1 :
if (resultCode == Activity.RESULT_OK) {
Uri contactData = data.getData();
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(contactData, null, null, null, null);
if (cur.getCount() > 0) {// thats mean some resutl has been found
if(cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
Log.e("Names", name);
if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0)
{
// Query phone here. Covered next
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ id,null, null);
while (phones.moveToNext()) {
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.e("Number", phoneNumber);
}
phones.close();
}
}
}
cur.close();
}
break;
}
}
Consider you already have a list which has data from API, and create new list which will have common elements from API list and ContentResolver, now to add elements to your desired list, in ContentResolver check if the PhoneNumber is in API list before adding it to output.
ArrayList<String> apiPhoneNumbers;// this data is populated by API
ArrayList<String> commonPhoneNumbers = new ArrayList<>();
//inside onActivityResult
if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0){
// Query phone here. Covered next
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ id,null, null);
while (phones.moveToNext()) {
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.e("Number", phoneNumber);
if(apiPhoneNumbers.contains(phoneNumber)){//add to output only if it is in API list
commonPhoneNumbers.add(phoneNumber);
}
}
phones.close();
}
For instance, when I want to attach an image to a text message in the stock Messages app, I get a familiar system dialog presenting the Camera, Gallery, and other image Content Providers.
I want to use this in my own app. I see plenty of libraries that allow the user to choose between Gallery and Camera, but I want all of the user's installed Image source to appear.
Is the system dialog from Messages (and other stock apps, such as Mail) really custom for those apps? Do we really need to build our own? Storage Access Framework does not appear to be the right solution since it bypasses the camera (or other image sources that I haven't thought of but may be present on a user's device).
I would suggest Intent.ACTION_PICK
private void selectFileFromGallery() {
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), requestGallery);
}
It will open a dialog like this that contains all of users app that can be used as an image picker :
And then when user chosses image:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == requestGallery) {
onSelectFromGalleryResult(data);
}
}
#SuppressWarnings("deprecation")
private void onSelectFromGalleryResult(Intent data) {
Uri uri = data.getData();
if (!uri.toString().contains("file")) {
if (uri.toString().contains("external")) {//chosen from external storage
photoUri = Uri.parse("file://" + getRealPathFromURI(uri));
} else {
photoUri = Uri.parse("file://" + (Build.VERSION.SDK_INT <= 18
? getRealPathFromURI_API11to18(getActivity(), uri) :
getRealPathFromURI_API19(getActivity(), uri)));
}
}
#SuppressLint("NewApi")
private String getRealPathFromURI_API19(Context context, Uri uri) {
return RealPathUtil.INSTANCE.getRealPathFromURI_API19(context, uri);
}
public String getRealPathFromURI(Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = getActivity().managedQuery(contentUri, proj, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
#SuppressLint("NewApi")
private String getRealPathFromURI_API11to18(Context context, Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
String result = null;
CursorLoader cursorLoader = new CursorLoader(
context,
contentUri, proj, null, null, null);
Cursor cursor = cursorLoader.loadInBackground();
if (cursor != null) {
int column_index =
cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
result = cursor.getString(column_index);
}
return result;
}
The thing you are asking for can be done using System Access Frame work.
Add Storage Permissions inside the manifest file, and then check if the permission is accepted or not. Then you can open open document choose to let the user choose the image.
Code
Inside some onClick
Intent i = new Intent(Intent.ACTION_OPEN_DOCUMENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
startActivityForResult(i, 41);
This will open file chooser activity for image files only.
Then you can get back the results inside:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK){
if (requestCode == 41) {
if (data != null) {
Uri uri = data.getData();
//This is the uri to the file
//To get the file use the uri
}
}
}
}
Still you have to create the BottomSheetDialog on your own, but your job will be drastically reduced as there will be only 2 options : 1. Camera app ,2. File chooser. You will have to handle the camera event on your own and get the image uri.
I suggest using android image Android-Image-Cropper by ArthurHub
It gives you all the options you are looking for
I'm developing an app in which one of its features is to allow the user to input a phone number or select one from the phones contacts.
The activity has 3 EditTexts along with 3 Buttons each on the side, and the buttons open the Contacts Activity and return the selected phone number and sets the EditText accordingly.
I have tried setting separate cursors for each button.
I have also tried using different intent variables.
My problem: When the user selects the contact to get data from, the cursor returns a different number. Either it returns the contact next to it or the contact previously selected.
The OnClick method for the 3 buttons with startActivityForResult.
//The intent
i = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
public void onClick(View v) {
switch (v.getId()){
case (R.id.button1):
startActivityForResult(i, 0);
break;
//I know it's an ImageView
case (R.id.imageView1):
startActivityForResult(i, 1);
break;
case (R.id.imageView2):
startActivityForResult(i, 2);
break;
}
}
The OnActivityResult
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
switch (requestCode){
case (0) :
if (resultCode == Activity.RESULT_OK) {
Cursor c = getContentResolver().query(Phone.CONTENT_URI, null, null, null, null);
c.moveToFirst();
contact1 = c.getString(c.getColumnIndex(Phone.NUMBER));
et.setText(contact1);
}
break;
case (1) :
if (resultCode == Activity.RESULT_OK) {
Cursor c1 = getContentResolver().query(Phone.CONTENT_URI, null, null, null, null);
c1.moveToFirst();
contact2 = c1.getString(c1.getColumnIndex(Phone.NUMBER));
et2.setText(contact2);
}
break;
case (2) :
if (resultCode == Activity.RESULT_OK) {
Cursor c2 = getContentResolver().query(Phone.CONTENT_URI, null, null, null, null);
c2.moveToFirst();
contact3 = c2.getString(c2.getColumnIndex(Phone.NUMBER));
et3.setText(contact3);
}
break;
}
}
change Phone.CONTENT_URI to intent.getData();
Uri contactData = intent.getData();
Cursor c = getContentResolver().query(contactData, null, null, null, null);
what you are doing wrong is querying each time the exact same query without regard to the intent result...so of course you will get the same result each time
Also because you want to get the phone number add a projection value:
String[] projection = {Phone.NUMBER};
getContentResolver().query(contactData, projection, null, null, null);
to better understand please read how to get contact phone number
When I tried to call multiple startactivityforResult in Android, it only called the first declared on startactivityforResult, I resolved this issue by making a function with startActivityforResult and passing the intent and requestcode to the function that contained startActivityForResult.
I'm using a contact picker as such:
startActivityForResult(
new Intent(
Intent.ACTION_PICK,
Phone.CONTENT_URI
), CONTACT_PICKER_RESULT //1001
);
This type of contact picker picks out a specific phone number that a contact has.
I then get an ID for this contact with:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode != CONTACT_PICKER_RESULT || resultCode != RESULT_OK)
return;
String id = data.getData.getLastPathSegment();
}
However, when I use a PhoneLookup query, such as:
Cursor cur = getContentResolver().query(
Uri.withAppendedPath(
PhoneLookup.CONTENT_FILTER_URI,
Uri.encode(...) //phone number of contact is filled in
),
new String[] {
PhoneLookup.DISPLAY_NAME,
Phone._ID
}, null, null, null
);
if (!cur.moveToFirst())
return;
String id = cur.getString(
cur.getColumnIndex(Phone._ID)
);
The ID I get from the PhoneLookup is different from the onActivityResult. For example, the contact picker returns 1408 while the cursor returns 444.
How can I get:
data.getData().getLastPathSegment() equal to cur.getColumnIndex(...)?
You can't use a PhoneLookup in this case. You need to query Phone.CONTENT_URI to obtain the ID that matches up with the contact picker. The following code below does exactly this.
Cursor cur = getContentResolver().query(
Phone.CONTENT_URI,
new String[] {
Phone.DISPLAY_NAME,
Phone._ID
},
Phone.NORMALIZED_NUMBER + "=?",
new String[] {
... //phone number placed here
}, null);
if (!cur.moveToFirst())
return;
String id = cur.getString(cur.getColumnIndex(Phone._ID)));
Want to set the value RESULT from the following part and should retrieve it in the onActivityResult...
Following is the code.
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
System.out.println("Select Display Picture, but");
intent.putExtra("RESULT", "RESULT");
activity.startActivityForResult(
Intent.createChooser(intent, "Select Display Picture"),
Credentials.BROWSE_PIC);
activity.setResult(Credentials.BROWSE_PIC, intent);
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == Credentials.BROWSE_PIC
&& resultCode == Activity.RESULT_OK && null != data) {
//returning null always here..
System.out.println("OnActivityResult came in::: "
+ data.getStringExtra("RESULT"));
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
}
You are using implicit Intent, you can not put anything in this intent because every implicit intent is defined by others.
If you want to add something then you can use your own Global Bundle object for the same.
Here are important link for you:
You can see answer By Lavekush Agrawer for using Global Bundle Object. here access the variable in activity in another class
Android Intents - Tutorial