I want to custom search in contacts in android.
For example, i want contacts that each contact number end with 555 so how can i do that?
Get all contacts and search manually using code.
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
String phone = null;
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
String id = cur.getString(cur .getColumnIndex(ContactsContract.Contacts._ID));
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()) {
phone = pCur .getString(pCur .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
if(phone.endsWith( "555")
// store the number and id of the contact
}
pCur.close();
}
/*** Store id and phone in another variable(eg ArrayList,etc) so that it does not get lost in another iteration of while loop***/
}
}
Also Android contacts are formatted with spaces,- and (). it may be better to remove them before checking. Using
phone.replace("-", "").replace("(", "").replace(")", "").replace(".", "").replace(" ", "");
Also see here.
Related
I have created a functional image gallery that takes photos from a user's phone and displays it on a recyclerview. Everything works, however, it seems as though the method I have used to retrieve this data is limited to API level 29. The app is meant to work on devices API 21 and up. How can I adjust this code to accommodate this?
RetrieveImgaes.java
public class SelectImagesGallery {
public static ArrayList < String > listOfImages(Context context) {
Uri uri;
Cursor cursor;
int column_index_data, column_index_folder_name;
ArrayList < String > listOfAllImages = new ArrayList < > ();
String absolutePathOfImage;
uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] projection = {
MediaStore.MediaColumns.DATA,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME
};
String orderBy = MediaStore.Video.Media.DATE_TAKEN;
cursor = context.getContentResolver().query(uri, projection, null, null, orderBy + " DESC");
column_index_data = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
// Get folder name
// column_index_folder_name = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
while (cursor.moveToNext()) {
absolutePathOfImage = cursor.getString(column_index_data);
listOfAllImages.add(absolutePathOfImage);
}
return listOfAllImages;
}
I want to get all videos from a specific location(Folder) using MediaStore with
1. Full Video Path
2. Video Thumbnail
3. Video Duration
if anyone has an idea about how can I get all the above things then give your suggestion & help
Thanks in advance.
Uri mainUri;
Cursor cursor1 = getContentResolver().query(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Video.Media._ID},
MediaStore.Video.Media.DATA + "=? ",
new String[]{pathMain}, null);
if (cursor1 != null && cursor1.moveToFirst()) {
int id = cursor1.getInt(cursor1.getColumnIndex(MediaStore.MediaColumns._ID));
cursor1.close();
mainUri = Uri.withAppendedPath(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, "" + id);
} else {
ContentValues values = new ContentValues();
values.put(MediaStore.Video.Media.DATA, pathMain);
mainUri = getContentResolver().insert(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
}
final String[] projection = new String[]{MediaStore.Video.Media._ID, MediaStore.Video.Media.DISPLAY_NAME, MediaStore.Video.Media.DATA,
MediaStore.Video.Media.DURATION};
String selection = MediaStore.Video.Media.DATA + "=?";
String selectionArgs[] = {pathMain};
CursorLoader loader = new CursorLoader(getActivity(), mainUri, projection, selection, selectionArgs, null);
Cursor cursor = loader.loadInBackground();
if (cursor != null && cursor.moveToFirst()) {
long id = cursor.getLong(cursor.getColumnIndex(projection[0]));
String name = cursor.getString(cursor.getColumnIndex(projection[1]));
String path = cursor.getString(cursor.getColumnIndex(projection[2]));
long duration = cursor.getLong(cursor.getColumnIndex(projection[3]));
cursor.close();
return new ImageObject(id, name, path, false, MEDIA_TYPE_VIDEO, duration);
}
Sorry for the bad english!
I want to scan all contacts 's phone number and prefix them. However my code is not useful. It missed a lot of phone numbers when reading contacts. Help me plz!
`
String[] columns = {ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Contacts.HAS_PHONE_NUMBER};
ContentResolver cr =getContentResolver();
Cursor cursor=cr.query(ContactsContract.Contacts.CONTENT_URI, columns,null,null,null);
cursor.moveToFirst();
while(cursor.moveToNext())
{
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
if(!(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)).endsWith("0")) )
{
Cursor phones = cr.query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null, null);
if(phones.getCount() > 0)
while (phones.moveToNext())
{
String number = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)).replaceAll("[ \\-().]", ""); //this is phone number
int type = phones.getInt(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
String idIndex = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID));
switch (type)
{
case ContactsContract.CommonDataKinds.Phone.TYPE_HOME:
//prefix number function and write contacts here.
break;
case ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE:
//prefix number function and write contacts here.
break;
case ContactsContract.CommonDataKinds.Phone.TYPE_WORK:
//prefix number function and write contacts here.
break;
//some other type here...
}
}
phones.close();
}
}
cursor.close();`
No need for a loop-within-loop here, just one query that goes over all numbers in the Contacts DB:
String[] projection = new String[] { Phone.NUMBER, Phone.TYPE, Phone._ID };
Cursor phones = cr.query(Phone.CONTENT_URI, null, null, null, null);
while (phones.moveToNext()) {
String number = phones.getString(0).replaceAll("[ \\-().]", ""); //you can instead use Phone.NORMALIZED_NUMBER if you're using a high-enough API level
int type = phones.getInt(1);
long id = cursor.getLong(2);
Log.v("LOG", "got phone: " + id + ", " + number + ", " + type);
prefixNumber(id, number, type);
}
phones.close();
`sssss
public void updatePhoneNumber(ContentResolver contentResolver, long rawContactId, int phoneType, String PhoneNumber) {
// Create content values object.
ContentValues contentValues = new ContentValues();
// Put new phone number value.
contentValues.put(ContactsContract.CommonDataKinds.Phone.NUMBER, PhoneNumber);
// Create query condition, query with the raw contact id.
StringBuffer whereClauseBuf = new StringBuffer();
// Specify the update contact id.
whereClauseBuf.append(ContactsContract.Data.RAW_CONTACT_ID);
whereClauseBuf.append("=");
whereClauseBuf.append(rawContactId);
// Specify the row data mimetype to phone mimetype( vnd.android.cursor.item/phone_v2 )
whereClauseBuf.append(" and ");
whereClauseBuf.append(ContactsContract.Data.MIMETYPE);
whereClauseBuf.append(" = '");
String mimetype = ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE;
whereClauseBuf.append(mimetype);
whereClauseBuf.append("'");
// Specify phone type.
whereClauseBuf.append(" and ");
whereClauseBuf.append(ContactsContract.CommonDataKinds.Phone.TYPE);
whereClauseBuf.append(" = ");
whereClauseBuf.append(phoneType);
// Update phone info through Data uri.Otherwise it may throw java.lang.UnsupportedOperationException.
Uri dataUri = ContactsContract.Data.CONTENT_URI;
// Get update data count.
int updateCount = contentResolver.update(dataUri, contentValues, whereClauseBuf.toString(), null);
}`
I wrote the following function in order to retrieve one single phone number that belongs to the contact with id "contactID".
The function which is to retrieve the phone number:
private String getContactPhone(String contactID) {
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String[] projection = null;
String where = ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?";
String[] selectionArgs = new String[] { contactID };
String sortOrder = null;
Cursor result = managedQuery(uri, projection, where, selectionArgs, sortOrder);
if (result.moveToFirst()) {
String phone = result.getString(result.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
if (phone == null) {
result.close();
return null;
}
result.close();
return phone;
}
result.close();
return null;
}
How this function is called:
ArrayList<Contact> resultContacts = new ArrayList<Contact>();
Cursor result = null;
Uri uri = ContactsContract.Data.CONTENT_URI;
String[] projection = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Event.CONTACT_ID,
ContactsContract.CommonDataKinds.Event.START_DATE,
};
String where = ContactsContract.Data.MIMETYPE+" = ? AND "+ContactsContract.CommonDataKinds.Event.TYPE+" = "+ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY;
String[] selectionArgs = new String[] {ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE};
String sortOrder = null;
result = managedQuery(uri, projection, where, selectionArgs, sortOrder);
while (result.moveToNext()) {
Long id = result.getLong(result.getColumnIndex(ContactsContract.Contacts._ID));
String phone = getContactPhone(String.valueOf(id));
...
}
...
Unfortunately, it doesn't work. I get null if I call this function with the value that I got from "ContactsContract.Contacts._ID". Why is this so? What is wrong?
Edit: I used to map Contacts._ID to CommonDataKinds.Phone.CONTACT_ID - which didn't work. But now I map Contacts.DISPLAY_NAME to CommonDataKinds.Phone.DISPLAY_NAME and it works suddenly - strange, isn't it? But I would rather like to map the IDs instead of the display names. So the question is still topical. Could this be due to different IDs in those tables? Isn't this why there are lookup IDs?
To get the contact id in the first part, you should use:
ContactsContract.Data.CONTACT_ID
instead of:
ContactsContract.Contacts._ID
So the projection should be:
String[] projection = new String[] {
ContactsContract.Data.CONTACT_ID,
ContactsContract.CommonDataKinds.Event.CONTACT_ID,
ContactsContract.CommonDataKinds.Event.START_DATE,
};
And then of course get the correct row:
Long id = result.getLong(result.getColumnIndex(ContactsContract.Data.CONTACT_ID));
You are getting null because you have set your projection to null. The projection is basically the list of columns that you want returned e.g.
String[] projection = {ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Contacts.HAS_PHONE_NUMBER};
Usually, when you find the contact, they may have a list of phone numbers, so you have to use another cursor to iterate through the phone numbers, e.g.
Cursor phones = mContext.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId, null, null);
while (phones.moveToNext())
{
phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DATA));
}
Hope this helps.
Your code for getContactPhone() works fine on my end. I tested by launching a contact picker, selecting a contact, then using the ID that was returned and passed that into your method.
So I suspect you are indeed passing in an invalid ID. Can you post the full stack trace for the null pointer exception?
Yes, lookup keys are available because _IDs are not guaranteed to stay the same since syncs and contact aggregation changes them.
For example, I want to retrieve a list of all .mp3 files on the internal AND external storage. I would also like the path (String) of each .mp3 file for reference (store them in a List?) How could I do this? Is this a relatively expensive operation? If so, should it be put on a thread and while that is running, present the user with a "Loading" ProgressDialog?
Please find the function below . It will get all the mp3 files stored in external and Internal memory .
public void getAllSongs() {
Uri allsongsuri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
cursor = managedQuery(allsongsuri, STAR, selection, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
song_name = cursor
.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME));
int song_id = cursor.getInt(cursor
.getColumnIndex(MediaStore.Audio.Media._ID));
String fullpath = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.DATA));
fullsongpath.add(fullpath);
album_name = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.ALBUM));
int album_id = cursor.getInt(cursor
.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
artist_name = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.ARTIST));
int artist_id = cursor.getInt(cursor
.getColumnIndex(MediaStore.Audio.Media.ARTIST_ID));
} while (cursor.moveToNext());
}
cursor.close();
db.closeDatabase();
}
}