package de.jeisfeld.augendiagnoselib.util.imagefile;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.provider.MediaStore.MediaColumns;
import android.support.annotation.NonNull;
import java.io.File;
import de.jeisfeld.augendiagnoselib.Application;
/**
* Utility class for handling the media store.
*/
public final class MediaStoreUtil {
/**
* The size of a mini thumbnail.
*/
public static final int MINI_THUMB_SIZE = 512;
/**
* Hide default constructor.
*/
private MediaStoreUtil() {
throw new UnsupportedOperationException();
}
/**
* Get a real file path from the URI of the media store.
*
* @param contentUri Thr URI of the media store
* @return the file path.
*/
@SuppressWarnings("static-access")
public static String getRealPathFromUri(@NonNull final Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = {MediaStore.Images.Media.DATA};
cursor = Application.getAppContext().getContentResolver().query(contentUri, proj, null, null, null);
if (cursor == null) {
return null;
}
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(columnIndex);
}
catch (Exception e) {
return null;
}
finally {
if (cursor != null) {
cursor.close();
}
}
}
/**
* Retrieve a the image id of an image in the Mediastore from the path.
*
* @param path The path of the image
* @return the image id.
* @throws ImageNotFoundException thrown if the image is not found in the media store.
*/
@SuppressWarnings("static-access")
private static int getImageId(final String path) throws ImageNotFoundException {
ContentResolver resolver = Application.getAppContext().getContentResolver();
try {
Cursor imagecursor = resolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Images.Media._ID}, MediaStore.Images.Media.DATA + " = ?",
new String[]{path}, MediaStore.Images.Media.DATE_ADDED + " desc");
if (imagecursor == null) {
throw new ImageNotFoundException();
}
imagecursor.moveToFirst();
if (!imagecursor.isAfterLast()) {
int imageId = imagecursor.getInt(imagecursor.getColumnIndex(MediaStore.Images.Media._ID));
imagecursor.close();
return imageId;
}
else {
imagecursor.close();
throw new ImageNotFoundException();
}
}
catch (Exception e) {
throw new ImageNotFoundException(e);
}
}
/**
* Get an Uri from an file path.
*
* @param path The file path.
* @return The Uri.
*/
public static Uri getUriFromFile(final String path) {
ContentResolver resolver = Application.getAppContext().getContentResolver();
Cursor filecursor = resolver.query(MediaStore.Files.getContentUri("external"),
new String[]{BaseColumns._ID}, MediaColumns.DATA + " = ?",
new String[]{path}, MediaColumns.DATE_ADDED + " desc");
if (filecursor == null) {
return null;
}
filecursor.moveToFirst();
if (filecursor.isAfterLast()) {
filecursor.close();
ContentValues values = new ContentValues();
values.put(MediaColumns.DATA, path);
return resolver.insert(MediaStore.Files.getContentUri("external"), values);
}
else {
int imageId = filecursor.getInt(filecursor.getColumnIndex(BaseColumns._ID));
Uri uri = MediaStore.Files.getContentUri("external").buildUpon().appendPath(
Integer.toString(imageId)).build();
filecursor.close();
return uri;
}
}
/**
* Get the Album Id from an Audio file.
*
* @param file The audio file.
* @return The Album ID.
*/
@SuppressWarnings("resource")
public static int getAlbumIdFromAudioFile(@NonNull final File file) {
ContentResolver resolver = Application.getAppContext().getContentResolver();
Cursor cursor = resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Audio.AlbumColumns.ALBUM_ID},
MediaStore.MediaColumns.DATA + "=?",
new String[]{file.getAbsolutePath()}, null);
if (cursor == null || !cursor.moveToFirst()) {
// Entry not available - create entry.
if (cursor != null) {
cursor.close();
}
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, file.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, "{MediaWrite Workaround}");
values.put(MediaStore.MediaColumns.SIZE, file.length());
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mpeg");
values.put(MediaStore.Audio.AudioColumns.IS_MUSIC, true);
resolver.insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, values);
}
cursor = resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Audio.AlbumColumns.ALBUM_ID},
MediaStore.MediaColumns.DATA + "=?",
new String[]{file.getAbsolutePath()}, null);
if (cursor == null) {
return 0;
}
if (!cursor.moveToFirst()) {
cursor.close();
return 0;
}
int albumId = cursor.getInt(0);
cursor.close();
return albumId;
}
/**
* Add a picture to the media store (via scanning).
*
* @param path the path of the image.
*/
public static void addFileToMediaStore(@NonNull final String path) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File file = new File(path);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
Application.getAppContext().sendBroadcast(mediaScanIntent);
}
/**
* Retrieve a thumbnail of a bitmap from the mediastore.
*
* @param path The path of the image
* @param maxSize The maximum size of this bitmap (used for selecting the sample size)
* @return the thumbnail.
*/
public static Bitmap getThumbnailFromPath(final String path, final int maxSize) {
ContentResolver resolver = Application.getAppContext().getContentResolver();
try {
int imageId = getImageId(path);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = MINI_THUMB_SIZE / maxSize;
setDither(options);
return MediaStore.Images.Thumbnails.getThumbnail(resolver, imageId, MediaStore.Images.Thumbnails.MINI_KIND,
options);
}
catch (ImageNotFoundException e) {
return null;
}
}
/**
* Set the BitmapFactory to dither = true. (Deprecated since Android N.)
* @param options The BitmapFactory options.
*/
@SuppressWarnings("deprecation")
private static void setDither(final BitmapFactory.Options options) {
if (Build.VERSION.SDK_INT <= VERSION_CODES.M) {
options.inDither = true;
}
}
/**
* Add a picture to the media store (via scanning).
*
* @param path the path of the image.
*/
public static void addPictureToMediaStore(@NonNull final String path) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File file = new File(path);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
Application.getAppContext().sendBroadcast(mediaScanIntent);
}
/**
* Delete the thumbnail of a bitmap.
*
* @param path The path of the image
*/
public static void deleteThumbnail(final String path) {
ContentResolver resolver = Application.getAppContext().getContentResolver();
try {
int imageId = getImageId(path);
resolver.delete(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
MediaStore.Images.Thumbnails.IMAGE_ID + " = ?", new String[]{"" + imageId});
}
catch (ImageNotFoundException e) {
// ignore
}
}
/**
* Utility exception to be thrown if an image cannot be found.
*/
private static final class ImageNotFoundException extends Exception {
/**
* The default serial version id.
*/
private static final long serialVersionUID = 1L;
private ImageNotFoundException() {
}
private ImageNotFoundException(final Throwable e) {
super(e);
}
}
}