I'm saving an image loaded with Picasso to be shared afterwards. This is the code I'm using to save it:
String path = MediaStore.Images.Media.insertImage(
mContext.getContentResolver(), mImageBitmap, "Shared image", null);
return Uri.parse(path);
Now, when the image has been shared, I have to delete it using the URI. I've tried some answers I've seen here but none of them has worked. The image still appears in the gallery. These are the methods I have used:
// Set up the projection (we only need the ID)
String[] projection = { MediaStore.Images.Media._ID };
// Match on the file path
String selection = MediaStore.Images.Media.DATA + " = ?";
String[] selectionArgs = new String[] { new File(mImageUri.toString()).getAbsolutePath() };
// Query for the ID of the media matching the file path
Uri queryUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
ContentResolver contentResolver = getContentResolver();
Cursor c = contentResolver.query(queryUri, projection, selection, selectionArgs, null);
if (c.moveToFirst())
{
// We found the ID. Deleting the item via the content provider will also remove the file
long id = c.getLong(c.getColumnIndexOrThrow(MediaStore.Images.Media._ID));
Uri deleteUri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
contentResolver.delete(deleteUri, null, null);
}
c.close();
File file = new File(mImageUri.toString());
// This returns false
file.delete();
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File(mImageUri.toString()))));
Any idea of what i've done wrong?
Thanks,
Try this for deletion
String[] retCol = { MediaStore.Audio.Media._ID };
Cursor cur = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
retCol,
MediaStore.Images.Media.TITLE + "='"+TEMP_FILE_TITLE+"'", null, null
);
try {
if (cur.getCount() == 0) {
return;
}
cur.moveToFirst();
int id = cur.getInt(cur.getColumnIndex(MediaStore.MediaColumns._ID));
Uri uri = ContentUris.withAppendedId(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id
);
int cnt = context.getContentResolver().delete(uri, null, null);
}finally {
cur.close();
}
In your case replace TEMP_FILE_TITLE = "Shared image"
Related
I have a custom folder in the Pictures directory, like thisPictures/MyFolder. It has images in MyFolder. Here is how to query the images using ContentResolver on MyFolder folder only.
I tried this
Cursor mediaCursor = context.getContentResolver().query(
MediaStore.Files.getContentUri("external"),
null,
MediaStore.MediaColumns.RELATIVE_PATH + " like ? ",
new String[]{"%MyFolder%"},
null);
But it contains other files also. Or is any alternate to content resolver?
You can use the below function to get the images from the folder.
private void getImageFolderList() {
String[] projection = new String[] { MediaStore.Images.Media.DATA,
MediaStore.Images.Media._ID,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
MediaStore.Images.Media.DATE_TAKEN };
Uri images = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
final String orderBy = MediaStore.Images.Media.DATE_TAKEN;
Cursor cur = getContentResolver().query(images, projection, // Which
// columns
// to return
null, // Which rows to return (all rows)
null, // Selection arguments (none)
orderBy + " DESC" // Ordering
);
ArrayList<String> imagePath;
if (cur.moveToFirst()) {
String bucket, date;
int bucketColumn = cur.getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
int dateColumn = cur.getColumnIndex(MediaStore.Images.Media.DATE_TAKEN);
do {
bucket = cur.getString(bucketColumn);
date = cur.getString(dateColumn);
if (!allFolder.contains(bucket)) {
allFolder.add(bucket);
}
imagePath = listImageByFolder.get(bucket);
if (imagePath == null) {
imagePath = new ArrayList<String>();
}
imagePath.add(cur.getString(cur
.getColumnIndex(MediaStore.Images.Media.DATA)));
listImageByFolder.put(bucket, imagePath);
} while (cur.moveToNext());
}
}
I am writing code for setting custom ringtone in android. Took help from other answers in stackoverflow. Here is the code.
private void setContactRingtone(String number) {
final Uri lookupUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
// The columns used for `Contacts.getLookupUri`
final String[] projection = new String[]{
ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY
};
// Build your Cursor
final Cursor data = getContentResolver().query(lookupUri, projection, null, null, null);
data.moveToFirst();
try {
// Get the contact lookup Uri
final long contactId = data.getLong(0);
final String lookupKey = data.getString(1);
final Uri contactUri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
if (contactUri == null) {
// Invalid arguments
return;
}
File file = new File(this.getFilesDir() + File.separator + "ringtone.mp3");
final String value = Uri.fromFile(file).toString();
final ContentValues values = new ContentValues(1);
values.put(ContactsContract.Contacts.CUSTOM_RINGTONE, value);
getContentResolver().update(contactUri, values, null, null);
Toast.makeText(getApplicationContext(), "Done!!!!!!!!!!!", Toast.LENGTH_SHORT).show();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
// Don't forget to close your Cursor
data.close();
}
}
The code is not assigning the user defined ringtone to the contact. There are no exceptions generated.
SO the problem was in android 10 asset folder is accessible through inputstream.Referred this answer
Here we create a temporary file and write to external storage. And then read that file.
I have video path. I am able to load video in video using this path.
Now i want some video info from db but my Cursor is always null.
Below is my code.
String videoPath=Uri.fromFile(new File("/storage/emulated/0/Android/data/files/1483767006415.mp4")
final String[] projection = new String[]{MediaStore.Video.Media._ID, MediaStore.Video.Media.DISPLAY_NAME, MediaStore.Video.Media.DATA,
MediaStore.Video.Media.DURATION};
CursorLoader loader = new CursorLoader(getActivity(), contentUri, projection, null, null, 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);
}
Seems that uri is not proper.
Thanks.
Finally got answer.
Issue was in my URI. Video id was not appended in URI. So i have managed to get video id first and then createdURI. After using this URI, I was able to get all info. Below is code for same.
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);
}
I am working with Android Contact ContentProvider. I have a Phone Number and I need to get the URI of the Photo of the contact associated with this phone number. How can I do it???
I know I can get the raw data of the photo and build an InputStream, but I dont want the input stream, I need the URI.
EDIT: Originally I'm using following code to fetch contact info
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNo));
Cursor cursor = context.getContentResolver().query(uri, details, null, null, null);
To get the conatct id using the phone number use the following code:
import android.provider.ContactsContract.PhoneLookup;
public String fetchContactIdFromPhoneNumber(String phoneNumber) {
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
Uri.encode(phoneNumber));
Cursor cursor = this.getContentResolver().query(uri,
new String[] { PhoneLookup.DISPLAY_NAME, PhoneLookup._ID },
null, null, null);
String contactId = "";
if (cursor.moveToFirst()) {
do {
contactId = cursor.getString(cursor
.getColumnIndex(PhoneLookup._ID));
} while (cursor.moveToNext());
}
return contactId;
}
and use the contact id obtained to get the contatc photo URI. Use the following code for getting photo URI:
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
public Uri getPhotoUri(long contactId) {
ContentResolver contentResolver = getContentResolver();
try {
Cursor cursor = contentResolver
.query(ContactsContract.Data.CONTENT_URI,
null,
ContactsContract.Data.CONTACT_ID
+ "="
+ contactId
+ " AND "
+ ContactsContract.Data.MIMETYPE
+ "='"
+ ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE
+ "'", null, null);
if (cursor != null) {
if (!cursor.moveToFirst()) {
return null; // no photo
}
} else {
return null; // error in cursor process
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
Uri person = ContentUris.withAppendedId(
ContactsContract.Contacts.CONTENT_URI, contactId);
return Uri.withAppendedPath(person,
ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
}
Hope this would help.
This solution demonstrates how to get an image from a user contact and then display it in an ImageView.
ImageView profile = (ImageView)findViewById(R.id.imageView1);
Uri my_contact_Uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, String.valueOf(Contact_Id));
InputStream photo_stream = ContactsContract.Contacts.openContactPhotoInputStream(getContentResolver(),my_contact_Uri);
BufferedInputStream buf =new BufferedInputStream(photo_stream);
Bitmap my_btmp = BitmapFactory.decodeStream(buf);
profile.setImageBitmap(my_btmp);
Here's the code from Android Documentation.
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
return Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
You can get PHOTO_URI by NUMBER just use following code also you can use _ID.
public static String getContactPhoto(Context context, String phoneNumber) {
ContentResolver cr = context.getContentResolver();
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
Cursor cursor = cr.query(uri, new String[]{ContactsContract.PhoneLookup.PHOTO_URI}, null, null, null);
if (cursor == null) {
return null;
}
String contactImage= null;
if (cursor.moveToFirst()) {
contactImage= cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.PHOTO_URI));
}
if (!cursor.isClosed()) {
cursor.close();
}
return contactImage;
}
final boolean IS_HONEYCOMB = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
String phoneNumber = "+1 416 385 7805";
ContentResolver contentResolver = context.getContentResolver();
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
String[] projection = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Contacts.LOOKUP_KEY,
IS_HONEYCOMB ? ContactsContract.Contacts.PHOTO_THUMBNAIL_URI : ContactsContract.Contacts._ID,
};
Cursor cursor =
contentResolver.query(
uri,
projection,
null,
null,
null);
if (cursor != null && cursor.moveToNext()) {
long contactId = cursor.getLong(0);
String lookupKey = cursor.getString(1);
String thumbnailUri = cursor.getString(2);
cursor.close();
}
So now if sdk is honeycomb or higher u have thumbnail uri of the contact.
Or you can construct a lookup uri like this:
Uri uri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
P.S. If you already know contact id and/or lookup key you can construct a Uri from string:
lookup: content://com.android.contacts/contacts/lookup/{lookup key}/{contact id}
thumbnail: content://com.android.contacts/contacts/{contact id}/photo
So it's better to cache these values.
how can I get the actual file path on the SD card where a content:// uri is pointing for an image?
I've adapted the code which #hooked82 linked to:
protected String convertMediaUriToPath(Uri uri) {
String [] proj={MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(uri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String path = cursor.getString(column_index);
cursor.close();
return path;
}
Content URIs have syntax content://authority/path/id, read here.
Parse id from content URI and query MediaStore.Images.Media.EXTERNAL_CONTENT_URI as follows:
long id = ContentUris.parseId(Uri.parse(contentUri));
Cursor cursor = getContentResolver()
.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{ MediaStore.Images.Media.DATA },
MediaStore.Images.Media._ID + " = ?", new String[]{ Long.toString(id) },
null);
if (cursor.moveToNext()) {
path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
}
cursor.close();