List all camera images in Android - android

How do you get a list of all camera images of an Android device?
Is it through the MediaStore? How?

The Gallery app obtains camera images by using a content resolver over Images.Media.EXTERNAL_CONTENT_URI and filtering the results by Media.BUCKET_ID. The bucket identifier is determined with the following code:
public static final String CAMERA_IMAGE_BUCKET_NAME =
Environment.getExternalStorageDirectory().toString()
+ "/DCIM/Camera";
public static final String CAMERA_IMAGE_BUCKET_ID =
getBucketId(CAMERA_IMAGE_BUCKET_NAME);
/**
* Matches code in MediaProvider.computeBucketValues. Should be a common
* function.
*/
public static String getBucketId(String path) {
return String.valueOf(path.toLowerCase().hashCode());
}
Based on that, here's a snippet to get all camera images:
public static List<String> getCameraImages(Context context) {
final String[] projection = { MediaStore.Images.Media.DATA };
final String selection = MediaStore.Images.Media.BUCKET_ID + " = ?";
final String[] selectionArgs = { CAMERA_IMAGE_BUCKET_ID };
final Cursor cursor = context.getContentResolver().query(Images.Media.EXTERNAL_CONTENT_URI,
projection,
selection,
selectionArgs,
null);
ArrayList<String> result = new ArrayList<String>(cursor.getCount());
if (cursor.moveToFirst()) {
final int dataColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
do {
final String data = cursor.getString(dataColumn);
result.add(data);
} while (cursor.moveToNext());
}
cursor.close();
return result;
}
For more info, review the ImageManager and ImageList classes of the Gallery app source code.

Related

Reading images stored in internal storage from another app

I have a simple question.
It's possible to access to DCIM folder (internal storage) from an app and retrieve an image?
I've found solutions that use something like Enviroment.getExternalStoragePublicDirectory but I don't understand why.
Environment.getExternalStorageDirectory().toString()+ "/DCIM/Camera";
or
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath()
Will give you a path for the public directory. This path is required to fetch all files including image. getExternalStorageDirectory() and Environment.getExternalStoragePublicDirectory() is public so you can access them from any installed app.
The following code snippet can be used to list all image file path from "DCIM" folder:
public static List<String> getCameraImages(Context context) {
public final String CAMERA_IMAGE_BUCKET_NAME = Environment.getExternalStorageDirectory().toString()+ "/DCIM/Camera";
public final String CAMERA_IMAGE_BUCKET_ID = String.valueOf(CAMERA_IMAGE_BUCKET_NAME.toLowerCase().hashCode());
final String[] projection = { MediaStore.Images.Media.DATA };
final String selection = MediaStore.Images.Media.BUCKET_ID + " = ?";
final String[] selectionArgs = { CAMERA_IMAGE_BUCKET_ID };
final Cursor cursor = context.getContentResolver().query(Images.Media.EXTERNAL_CONTENT_URI,
projection,
selection,
selectionArgs,
null);
ArrayList<String> result = new ArrayList<String>(cursor.getCount());
if (cursor.moveToFirst()) {
final int dataColumn =
cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
do {
final String data = cursor.getString(dataColumn);
result.add(data);
} while (cursor.moveToNext());
}
cursor.close();
return result;
}

get genre_id and audio_id from audio_genres_map from mediastore

I want to retrieve whole audio_genres_map table from mediastore in one query. I have all the audio info and genre info but the missing piece is the mapping. I am able to do it in multiple queries. I want to achieve it one query
managed to solve this using following query
String[] genresProjection = {
Audio.Genres.Members.AUDIO_ID,
Audio.Genres.Members.GENRE_ID
};
context.getContentResolver().query(Uri.parse("content://media/external/audio/genres/all/members"), genresProjection, null, null, null);
Or to retrieve all genres using MediaStore.Audio
public Cursor getGenrecursor(Context context) {
ContentResolver cr = context.getContentResolver();
Uri uri = MediaStore.Audio.Genres.getContentUri("external");
String genre = MediaStore.Audio.Genres.NAME;
final String[] columns = { "_id", genre };
return cr.query(uri, columns, null, null, null);
}
and to expand your question, using the genre_id to bring back further details
public Cursor getgenre_TrackCursor(Context context, long genreID) {
final String track_id = MediaStore.Audio.Genres.Members._ID;
final String track_no = MediaStore.Audio.Genres.Members.TRACK;
final String track_name = MediaStore.Audio.Genres.Members.TITLE;
final String artist = MediaStore.Audio.Genres.Members.ARTIST;
final String duration = MediaStore.Audio.Genres.Members.DURATION;
final String album = MediaStore.Audio.Genres.Members.ALBUM;
final String composer = MediaStore.Audio.Genres.Members.COMPOSER;
final String year = MediaStore.Audio.Genres.Members.YEAR;
final String path = MediaStore.Audio.Genres.Members.DATA;
final ContentResolver resolve = context.getContentResolver();
Uri uri = MediaStore.Audio.Genres.Members.getContentUri("external",
genreID);
final String[] columns = { track_id, track_no, artist, track_name,
album, duration, year };
return resolve.query(uri, columns, null, null, null);
}

Android slow performance for getting contact's details

I want to display contacts, which has phone numbers, but with all assigned numbers. I want to improve the performance. Is there any more effective way to do this? Like obtaining all contacts thumbnails at once? This approach somehow fails for me, as the cursor is not empty, but returns empty(?) uri.
I have done some time tracking and it looks like appendContactNumber() takes to execute from 15 ms (one phone number) up to about 20 ms (three phone numbers).
// List specific variables
private static ArrayList<String> Contacts;
private static ArrayList<String> Numbers;
private static ArrayList<Bitmap> Photo;
// ContentResolver query specific variables
private static final Uri CONTACTS_URI = ContactsContract.Contacts.CONTENT_URI;
private static final String[] CONTACTS_PROJECTION = {
ContactsContract.Contacts._ID,
};
private static final String CONTACTS_SELECTION = ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1";
private static final String CONTACTS_SORT_ORDER = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
private static final Uri PHONES_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
private static final String[] PHONE_PROJECTION = {
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER
};
private static final String PHONE_SELECTION = ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ";
private static final String[] PHOTO_PROJECTION = { ContactsContract.Contacts.Photo.PHOTO };
private Context context;
public ContactsLoader(Context context) {
this.context = context;
}
#Override
public void run()
{
loadContacts();
}
private void loadContacts() {
Contacts = new ArrayList<>();
Numbers = new ArrayList<>();
Photo = new ArrayList<>();
// Retrieve all contacts with phone numbers
Cursor contactsCursor = context.getContentResolver().query(
CONTACTS_URI,
CONTACTS_PROJECTION,
CONTACTS_SELECTION,
null,
CONTACTS_SORT_ORDER
);
if (contactsCursor != null) {
while (contactsCursor.moveToNext()) {
appendContactNumber(contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts._ID)));
}
contactsCursor.close();
}
}
private void appendContactNumber(final String contactId) {
// Retrieve phone numbers for contact specified by id
Cursor numbersCursor = context.getContentResolver().query(
PHONES_URI,
PHONE_PROJECTION,
PHONE_SELECTION + contactId,
null,
null
);
// If phone numbers cursor is not empty
if (numbersCursor != null) {
Bitmap thumbnail = getContactThumb(contactId);
while (numbersCursor.moveToNext()) {
Contacts.add(numbersCursor.getString(numbersCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)));
Numbers.add(numbersCursor.getString(numbersCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
Photo.add(thumbnail);
}
numbersCursor.close();
}
}
private Bitmap getContactThumb(final String contactId) {
// Get contact thumbnail for given contactId
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(contactId));
Uri photoUri = Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
Cursor thumbnailCursor = context.getContentResolver().query(
photoUri,
PHOTO_PROJECTION,
null,
null,
null
);
if (thumbnailCursor != null) {
// If contact thumbnail is not empty
if (thumbnailCursor.moveToFirst()) {
Bitmap contactPhoto = BitmapFactory.decodeStream(new ByteArrayInputStream(thumbnailCursor.getBlob(0)));
thumbnailCursor.close();
return contactPhoto;
}
}
// Default Bitmap
return BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_contact_picture);
}
I did some workaround: rather than query for Bitmap it is faster to get photo URI. Here is my code:
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.util.Log;
import java.util.ArrayList;
public class PhoneContactsLoader extends ContactsLoader {
// Class specific variables
private ArrayList<String> Numbers;
public PhoneContactsLoader(Context context) {
super(context);
// ContentResolver query specific variables
URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI.toString();
PROJECTION = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.Contacts.PHOTO_URI
};
SELECTION = ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1";
SORT_ORDER = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
}
#Override
protected void fetchContacts() {
Contacts = new ArrayList<>();
Numbers = new ArrayList<>();
Photos = new ArrayList<>();
Long timer = System.currentTimeMillis();
// Retrieve all contacts containing phone numbers
Cursor contactsCursor = context.getContentResolver().query(
Uri.parse(URI),
PROJECTION,
SELECTION,
null,
SORT_ORDER
);
if (contactsCursor != null) {
while (contactsCursor.moveToNext()) {
Contacts.add(contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
Numbers.add(contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
String photoUri = contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts.PHOTO_URI));
if (photoUri != null)
Photos.add(photoUri);
else
Photos.add("useDefault");
}
contactsCursor.close();
}
Log.i("PhoneContactsLoader", "Thread execution time: " + (System.currentTimeMillis() - timer) + " ms");
}
#Override
public ArrayList<String> getNumbers() {
return Numbers;
}
}

How can I read the favorites contacts inside service?

I am looking for a way to get the contacts in the favorites list inside service from phone number or from name it dose not matter. Can any one help me with this?
It's not important to use any code related to this code
I found in the developer.android.com something like this (IN_VISIBLE_GROUP).
How to use this variable in my case?
case (PICK_CONTACT):
if (resultCode == Activity.RESULT_OK) {
Uri contactData = data.getData();
Cursor c = managedQuery(contactData, null, null, null, null);
ContentResolver cr = getContentResolver();
if (c.moveToFirst()) {
String name = c.getString(c.getColumnIndexOrThrow(People.NAME));
String id =c.getString(c.getColumnIndexOrThrow(People._ID));
Cursor phones = cr.query(Phone.CONTENT_URI, null,
Phone.CONTACT_ID + " = " + id, null, null);
}
Lets assume that you are searching a contact by name..
If you want to get Favourite value of all the possible contacts , drop the selection parameter in the given code.
//First get the contact ID from a display name as:-
String displayName = "Albert Einstein";
Uri contacts = ContactsContract.Contacts.CONTENT_URI;
cur = cr.query(contacts, null, ContactsContract.Contacts.DISPLAY_NAME +"="+displayName,null, null);
int contactIdIndex = cur.getColumnIndex(ContactsContract.PhoneLookup._ID);
int contactId = cur.getInt(contactIdIndex);
//Make a query to get the Starred value:-
Cursor starred = cr.query(ContactsContract.Contacts.CONTENT_URI,
new String[] { ContactsContract.Contacts.STARRED },
ContactsContract.Contacts._ID + " = " + contactId,
null, null);
if (starred != null && starred.moveToFirst())
{
int fav = starred.getInt(0);
}
if (starred != null)
starred.close();
}
You can drop the step of getting Contact ID and then querying for Starred value and directly query based on Display name
Something like this?
final private static class DataQuery {
public static final int COLUMN_MIMETYPE = 1;
public static final int COLUMN_PHONE = 2;
public static final int COLUMN_RAWCONTACT_ID = 3;
public static final int COLUMN_PHONE_NUMBER = COLUMN_DATA1;
public static final String[] PROJECTION = new String[] { Data._ID, Data.MIMETYPE, Data.DATA1, Data.RAW_CONTACT_ID };
public static final String SELECTION_PHONE = Data.DATA1 + "=?";
}
long findContact(Context context, String number) {
long rawContactId = -1;
final Cursor cursor = context.getContentResolver().query(Data.CONTENT_URI, DataQuery.PROJECTION, DataQuery.SELECTION_PHONE, new String[] { number }, null);
try {
if (cursor.moveToFirst()) {
rawContactId = cursor.getLong(DataQuery.COLUMN_RAWCONTACT_ID);
}
} finally {
if (cursor != null)
cursor.close();
}
return rawContactId;
}
Ok let's try with this...
private static final Uri DATAGROUP_CONTENT_URI = ContactsContract.Data.CONTENT_URI.buildUpon().appendQueryParameter(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE).build();
public static void querytGroups(Context context) {
final ContentResolver resolver = context.getContentResolver();
long groupid=getGroupId(resolver, "Family");
final Cursor c = resolver.query(DATAGROUP_CONTENT_URI, DataQueryForContactsInGroup.PROJECTION, DataQueryForContactsInGroup.SELECTION, new String[] {ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE, String.valueOf(groupid)}, null);
try {
while (c.moveToNext()) {
final long rawContactId = c.getLong(DataQueryForContactsInGroup.RAW_CONTACT_ID);
//do something
}
}finally {
c.close();
}
}
private static long getGroupId(final ContentResolver resolver, String groupName) {
long groupid = -1;
Cursor cur = null;
try {
cur = resolver.query(Groups.CONTENT_URI, DataQueryForGroup.PROJECTION, DataQueryForGroup.SELECTION, new String[]{"%"+groupName+"%"}, null);
while (cur.moveToNext()) {
return groupid= cur.getLong(DataQueryForGroup.GROUP_ID);
}
}finally {
if (cur!=null) cur.close();
}
return groupid;
}
private interface DataQueryForGroup {
public final static String[] PROJECTION = new String[] {Groups._ID};
public static final String SELECTION = Groups.TITLE+" LIKE ?";
public final static int GROUP_ID = 0;
}
private interface DataQueryForContactsInGroup {
public final static String[] PROJECTION = new String[] { Data.RAW_CONTACT_ID };
public static final String SELECTION = "("+Data.MIMETYPE + "=?) and ("+ ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID+ "=?)";
public final static int RAW_CONTACT_ID = 0;
}
Please consider that if your google account is not English you need to look for the proper group's name

android - how to pull images from DCIM/CAMERA by sampling thumbnails

Hi I am trying ot load images stored on the card and figured that its better to load the bitmaps, but I want to have both full path and thumbnail path. How do I do that? I would like my adapter to show me the list of thumbnails but when I click I need to redirect to a preview so I also need a full path. So if my object is Image, I need to have imagePath and imageThumbPath loaded at the same time.
Here is how I load them now:
new Image(data) where data is the path to the actual image. How do I load thumb path simultaneously into same object?
public static List<Image> getCameraImages(Context context) {
final String[] projection = { MediaStore.Images.Media.DATA };
final String selection = MediaStore.Images.Media.BUCKET_ID + " = ?";
final String[] selectionArgs = { CAMERA_IMAGE_BUCKET_ID };
final Cursor cursor = context.getContentResolver().query(Images.Media.EXTERNAL_CONTENT_URI,
projection,
selection,
selectionArgs,
null);
List<Image> result = new ArrayList<Image>(cursor.getCount());
if (cursor.moveToFirst()) {
final int dataColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
do {
final String data = cursor.getString(dataColumn);
result.add(new Image(data));
} while (cursor.moveToNext());
}
cursor.close();
return result;
}
public static final String CAMERA_IMAGE_BUCKET_NAME =
Environment.getExternalStorageDirectory().toString()
+ "/DCIM/Camera";
public static final String CAMERA_IMAGE_BUCKET_ID = getBucketId(CAMERA_IMAGE_BUCKET_NAME);
public static String getBucketId(String path) {
return String.valueOf(path.toLowerCase().hashCode());
}
and I found how to do hat ONLY to find out that the thumbs are all same size as originals!!! Horrible!

Categories

Resources