package org.freemp.droid; import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.media.RingtoneManager; import android.net.Uri; import android.os.ParcelFileDescriptor; import android.provider.MediaStore; import android.provider.Settings; import android.util.Log; import android.widget.Toast; import java.io.File; import java.io.IOException; /** * Created with IntelliJ IDEA. * User: recoilme * Date: 02/12/13 * Time: 13:54 * To change this template use File | Settings | File Templates. */ public class MediaUtils { public static final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart"); public static final String ALBUM_FOLDER = "albumthumbs"; private static final BitmapFactory.Options sBitmapOptionsCache = new BitmapFactory.Options(); // Get album art for specified album. This method will not try to // fall back to getting empty_artwork directly from the file, nor will // it attempt to repair the database. public static Bitmap getArtworkQuick(Context context, ClsTrack track, int w, int h) { // NOTE: There is in fact a 1 pixel frame in the ImageView used to // display this drawable. Take it into account now, so we don't have to // scale later. Bitmap b = null; if (track == null) return null; String path = MediaUtils.getAlbumPath(context.getApplicationContext().getFilesDir().getAbsolutePath(), track); if (path != null && new File(path).exists()) { File file = new File(path); if (file.exists()) { b = getBitmap(context, file, null, w, h); } } else { final int album_id = track.getAlbumId(); if (album_id != 0) { Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id); if (uri != null) { b = getBitmap(context, null, uri, w, h); } else { b = getArtistQuick(context, track, w, h); } } else { b = getArtistQuick(context, track, w, h); } } return b; } public static Bitmap getArtistQuick(Context context, ClsTrack track, int w, int h) { // NOTE: There is in fact a 1 pixel frame in the ImageView used to // display this drawable. Take it into account now, so we don't have to // scale later. Bitmap b = null; if (track == null) return null; String path = MediaUtils.getArtistPath(context.getApplicationContext().getFilesDir().getAbsolutePath(), track); if (path != null) { File file = new File(path); if (file.exists()) { b = getBitmap(context, file, null, w, h); } } return b; } public static Bitmap getBitmap(Context context, File file, Uri uri, int w, int h) { ParcelFileDescriptor fd = null; Bitmap b = null; try { if (file != null) { fd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); } else { ContentResolver res = context.getContentResolver(); fd = res.openFileDescriptor(uri, "r"); } int sampleSize = 1; // Compute the closest power-of-two scale factor // and pass that to sBitmapOptionsCache.inSampleSize, which will // result in faster decoding and better quality sBitmapOptionsCache.inJustDecodeBounds = true; BitmapFactory.decodeFileDescriptor( fd.getFileDescriptor(), null, sBitmapOptionsCache); int nextWidth = sBitmapOptionsCache.outWidth >> 1; int nextHeight = sBitmapOptionsCache.outHeight >> 1; while (nextWidth > w && nextHeight > h) { sampleSize <<= 1; nextWidth >>= 1; nextHeight >>= 1; } sBitmapOptionsCache.inSampleSize = sampleSize; sBitmapOptionsCache.inJustDecodeBounds = false; b = BitmapFactory.decodeFileDescriptor( fd.getFileDescriptor(), null, sBitmapOptionsCache);//теперь падает тут) if (b != null) { // finally rescale to exactly the size we need if (sBitmapOptionsCache.outWidth != w || sBitmapOptionsCache.outHeight != h) { Bitmap tmp = Bitmap.createScaledBitmap(b, w, h, true); //тут падало с аут оф мемори if (tmp != b) { b.recycle(); } b = tmp; } } } catch (Exception e) { return null; } finally { try { if (fd != null) fd.close(); } catch (IOException e) { } } return b; } public static void setRingtoneWithCoping(Context context, ClsTrack track) { /* http://www.stealthcopter.com/blog/2010/01/android-saving-a-sound-file-to-sd-from-resource-and-setting-as-ringtone/ File path = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_RINGTONES); path.mkdirs(); // Ensure the directory exists File file = new File(path, track.getPath()); try { OutputStream os = new FileOutputStream(file); } catch (FileNotFoundException e) { e.printStackTrace(); } */ } public static void setRingtone(Context context, ClsTrack track) { ContentValues values = new ContentValues(); values.put(MediaStore.MediaColumns.DATA, track.getPath()); values.put(MediaStore.MediaColumns.TITLE, track.getTitle()); //values.put(MediaStore.MediaColumns.SIZE, 1024*1024); values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/*"); values.put(MediaStore.Audio.Media.ARTIST, track.getArtist()); //values.put(MediaStore.Audio.Media.DURATION, 5000); values.put(MediaStore.Audio.Media.IS_RINGTONE, true); values.put(MediaStore.Audio.Media.IS_NOTIFICATION, false); values.put(MediaStore.Audio.Media.IS_ALARM, false); values.put(MediaStore.Audio.Media.IS_MUSIC, true); Uri uri = MediaStore.Audio.Media.getContentUriForPath(track.getPath()); if (uri == null || context.getContentResolver() == null) { Toast.makeText(context, context.getString(R.string.error), Toast.LENGTH_SHORT).show(); return; } /*String ringTonePath = uri.toString(); try { RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE, uri); } catch (Exception e) { Toast.makeText(context, context.getString(R.string.error)+e.toString(), Toast.LENGTH_SHORT).show(); }*/ //TODO check this may be better copy file in ringtone dir before? context.getContentResolver().delete(uri, MediaStore.MediaColumns.DATA + "=\"" + track.getPath() + "\"", null); Uri newUri = context.getContentResolver().insert(uri, values); if (newUri == null) { Toast.makeText(context, context.getString(R.string.error), Toast.LENGTH_SHORT).show(); } else { RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE, newUri); Toast.makeText(context, context.getString(R.string.set_as_ringtone), Toast.LENGTH_SHORT).show(); } } //i steal it from http://www.netmite.com/android/mydroid/packages/apps/Music/src/com/android/music/MusicUtils.java //http://www.lastfm.ru/api/show/album.getInfo static void setRingtone(Context context, long id) { ContentResolver resolver = context.getContentResolver(); // Set the flag in the database to mark this as a ringtone Uri ringUri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id); try { ContentValues values = new ContentValues(2); values.put(MediaStore.Audio.Media.IS_RINGTONE, "1"); values.put(MediaStore.Audio.Media.IS_ALARM, "1"); resolver.update(ringUri, values, null, null); } catch (UnsupportedOperationException ex) { // most likely the card just got unmounted Log.e("e", "couldn't set ringtone flag for id " + id); return; } String[] cols = new String[]{ MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.TITLE }; String where = MediaStore.Audio.Media._ID + "=" + id; Cursor cursor = query(context, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, cols, where, null, null); try { if (cursor != null && cursor.getCount() == 1) { // Set the system setting to make this the current ringtone cursor.moveToFirst(); Settings.System.putString(resolver, Settings.System.RINGTONE, ringUri.toString()); String message = context.getString(R.string.set_as_ringtone) + cursor.getString(2); Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); } } finally { if (cursor != null) { cursor.close(); } } } public static Cursor query(Context context, Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { try { ContentResolver resolver = context.getContentResolver(); if (resolver == null) { return null; } return resolver.query(uri, projection, selection, selectionArgs, sortOrder); } catch (UnsupportedOperationException ex) { return null; } } public static String getAlbumPath(String path, ClsTrack track, boolean withAlbum) { final String directoryPath = path + ALBUM_FOLDER; File directory = new File(directoryPath); boolean success = true; if (!directory.exists()) { success = directory.mkdirs(); } if (!success) { return null; } else { return directoryPath + "/" + StringUtils.getFileName(track, withAlbum) + ".jpg"; } } public static String getAlbumPath(String path, ClsTrack track) { return getAlbumPath(path, track, true); } public static String getArtistPath(String path, ClsTrack track) { return getAlbumPath(path, track, false); } }