/*
* Copyright (C) 2011 Virginia Tech Department of Computer Science
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sofia.content;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.provider.MediaStore.MediaColumns;
import java.util.ArrayList;
import java.util.List;
// -------------------------------------------------------------------------
/**
* Utility methods to make working with the built-in Android media gallery
* easier for students.
*
* TODO These might benefit from some refactoring now.
*
* @author Tony Allevato
*/
public class MediaUtils
{
//~ Constructors ..........................................................
// ----------------------------------------------------------
/**
* Prevent instantiation.
*/
private MediaUtils()
{
// Do nothing.
}
//~ Methods ...............................................................
// ----------------------------------------------------------
/**
* <p>
* Gets a list of all external media (stored on the device's SD card) that
* has the specified type. The type can be a complete MIME type (such as
* {@code "image/jpeg"}) or one with a wildcard (such as {@code "image/*"}
* to select all images).
* </p><p>
* The list returned by this method contains {@code Uri} objects; in order
* to get the path that corresponds to that {@code Uri} so that you can
* open the file, pass it to the
* {@link #pathForMediaUri(ContentResolver, Uri)} method.
* </p>
*
* @param resolver the content resolver used to find the content; this can
* be obtained by calling {@code getContentResolver()} from within the
* activity
* @param type the MIME type of the media to list
*
* @return a {@code List} containing the {@code Uri}s of all the matching
* media on the device's external storage
*/
public static List<Uri> getExternalMediaUris(
ContentResolver resolver, String type)
{
final String[] columns = { BaseColumns._ID };
final String selection = MediaColumns.MIME_TYPE + " LIKE ?";
final String[] selectionArgs = { type.replace('*', '%') };
Cursor cursor = resolver.query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
columns, selection, selectionArgs, null);
cursor.moveToFirst();
ArrayList<Uri> uris = new ArrayList<Uri>();
for (int i = 0; i < cursor.getCount(); i++)
{
String id = cursor.getString(0);
Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
.buildUpon().appendPath(id).build();
uris.add(uri);
cursor.moveToNext();
}
cursor.close();
return uris;
}
// ----------------------------------------------------------
/**
* <p><strong>
* Most students will never need to call this method -- it is intended for
* internal and advanced usage.
* </strong></p><p>
* Gets a {@code Uri} that represents a media item with the specified
* filename.
* </p><p>
* No MIME type is required here because the filename of the media (for
* example, "foo.jpg" or "bar.png") would typically also distinguish the
* type. However, if multiple media have the same filename, only the first
* one that is found will be returned, and the ordering of what is "first"
* is entirely dependent on the internal database ordering, and therefore
* should not be relied upon. If this is a problem, use a longer path
* segment than just the filename.
* </p>
*
* @param resolver the content resolver used to find the content; this can
* be obtained by calling {@code getContentResolver()} from within the
* activity
* @param filename the filename of the media to find
*
* @return a {@code Uri} that represents the media being requested, or null
* if no media with that filename could be found
*/
public static Uri uriForMediaWithFilename(
ContentResolver resolver, String filename)
{
final String[] columns = { BaseColumns._ID, MediaColumns.DATA };
final String selection = MediaColumns.DATA + " LIKE ?";
final String[] selectionArgs = { "%" + filename };
Cursor cursor = resolver.query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
columns, selection, selectionArgs, null);
Uri uri = null;
if (cursor.moveToFirst())
{
String id = cursor.getString(0);
uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
.buildUpon().appendPath(id).build();
}
cursor.close();
return uri;
}
// ----------------------------------------------------------
/**
* Converts a media {@code Uri}, such as one received by an activity's
* {@code onActivityResult} method after popping up an image chooser, to
* a path on the device's file system that can be used to open or
* manipulate the media file.
*
* @param resolver the content resolver used to find the content; this can
* be obtained by calling {@code getContentResolver()} from within the
* activity
* @param uri the {@code Uri} that represents the location of the media to
* get the path for
*
* @return the path to the file represented by the media {@code Uri}, or
* null if the {@code Uri} was invalid
*/
public static String pathForMediaUri(ContentResolver resolver, Uri uri)
{
final String[] columns = {
android.provider.MediaStore.MediaColumns.DATA
};
Cursor cursor = resolver.query(uri, columns, null, null, null);
try
{
if (cursor.moveToFirst())
{
return cursor.getString(0);
}
else
{
return null;
}
}
finally
{
cursor.close();
}
}
}