package com.android.music;
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Arrays;
-import java.util.Formatter;
-import java.util.HashMap;
-import java.util.Locale;
-
import android.app.Activity;
-import android.app.ExpandableListActivity;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
-import android.media.MediaFile;
-import android.media.MediaScanner;
import android.net.Uri;
-import android.os.RemoteException;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
import android.provider.MediaStore;
import android.provider.Settings;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Formatter;
+import java.util.HashMap;
+import java.util.Locale;
+
public class MusicUtils {
private static final String TAG = "MusicUtils";
}
private static int sArtId = -2;
- private static byte [] mCachedArt;
private static Bitmap mCachedBit = null;
private static final BitmapFactory.Options sBitmapOptionsCache = new BitmapFactory.Options();
private static final BitmapFactory.Options sBitmapOptions = new BitmapFactory.Options();
/** Get album art for specified album. You should not pass in the album id
* for the "unknown" album here (use -1 instead)
*/
- public static Bitmap getArtwork(Context context, int album_id) {
- return getArtwork(context, album_id, true);
- }
-
- /** Get album art for specified album. You should not pass in the album id
- * for the "unknown" album here (use -1 instead)
- */
- public static Bitmap getArtwork(Context context, int album_id, boolean allowDefault) {
+ public static Bitmap getArtwork(Context context, int song_id, int album_id) {
if (album_id < 0) {
// This is something that is not in the database, so get the album art directly
// from the file.
- Bitmap bm = getArtworkFromFile(context, null, -1);
- if (bm != null) {
- return bm;
- }
- if (allowDefault) {
- return getDefaultArtwork(context);
- } else {
- return null;
+ if (song_id >= 0) {
+ Bitmap bm = getArtworkFromFile(context, song_id, -1);
+ if (bm != null) {
+ return bm;
+ }
}
+ return getDefaultArtwork(context);
}
ContentResolver res = context.getContentResolver();
} catch (FileNotFoundException ex) {
// The album art thumbnail does not actually exist. Maybe the user deleted it, or
// maybe it never existed to begin with.
- Bitmap bm = getArtworkFromFile(context, null, album_id);
+ Bitmap bm = getArtworkFromFile(context, song_id, album_id);
if (bm != null) {
if (bm.getConfig() == null) {
bm = bm.copy(Bitmap.Config.RGB_565, false);
if (bm == null) {
- if (allowDefault) {
- return getDefaultArtwork(context);
- } else {
- return null;
- }
- }
- }
- // Put the newly found artwork in the database.
- // Note that this shouldn't be done for the "unknown" album,
- // but if this method is called correctly, that won't happen.
-
- // first write it somewhere
- String file = Environment.getExternalStorageDirectory()
- + "/albumthumbs/" + String.valueOf(System.currentTimeMillis());
- if (ensureFileExists(file)) {
- try {
- OutputStream outstream = new FileOutputStream(file);
- boolean success = bm.compress(Bitmap.CompressFormat.JPEG, 75, outstream);
- outstream.close();
- if (success) {
- ContentValues values = new ContentValues();
- values.put("album_id", album_id);
- values.put("_data", file);
- Uri newuri = res.insert(sArtworkUri, values);
- if (newuri == null) {
- // Failed to insert in to the database. The most likely
- // cause of this is that the item already existed in the
- // database, and the most likely cause of that is that
- // the album was scanned before, but the user deleted the
- // album art from the sd card.
- // We can ignore that case here, since the media provider
- // will regenerate the album art for those entries when
- // it detects this.
- success = false;
- }
- }
- if (!success) {
- File f = new File(file);
- f.delete();
- }
- } catch (FileNotFoundException e) {
- Log.e(TAG, "error creating file", e);
- } catch (IOException e) {
- Log.e(TAG, "error creating file", e);
+ return getDefaultArtwork(context);
}
}
- } else if (allowDefault) {
- bm = getDefaultArtwork(context);
} else {
- bm = null;
+ bm = getDefaultArtwork(context);
}
return bm;
} finally {
return null;
}
-
- // copied from MediaProvider
- private static boolean ensureFileExists(String path) {
- File file = new File(path);
- if (file.exists()) {
- return true;
- } else {
- // we will not attempt to create the first directory in the path
- // (for example, do not create /sdcard if the SD card is not mounted)
- int secondSlash = path.indexOf('/', 1);
- if (secondSlash < 1) return false;
- String directoryPath = path.substring(0, secondSlash);
- File directory = new File(directoryPath);
- if (!directory.exists())
- return false;
- file.getParentFile().mkdirs();
- try {
- return file.createNewFile();
- } catch(IOException ioe) {
- Log.d(TAG, "File creation failed for " + path);
- }
- return false;
- }
- }
// get album art for specified file
private static final String sExternalMediaUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI.toString();
- private static Bitmap getArtworkFromFile(Context context, Uri uri, int albumid) {
+ private static Bitmap getArtworkFromFile(Context context, int songid, int albumid) {
Bitmap bm = null;
byte [] art = null;
String path = null;
- if (sArtId == albumid) {
- //Log.i("@@@@@@ ", "reusing cached data", new Exception());
- if (mCachedBit != null) {
- return mCachedBit;
- }
- art = mCachedArt;
- } else {
- // try reading embedded artwork
- if (uri == null) {
- try {
- int curalbum = sService.getAlbumId();
- if (curalbum == albumid || albumid < 0) {
- path = sService.getPath();
- if (path != null) {
- uri = Uri.parse(path);
- }
- }
- } catch (RemoteException ex) {
- return null;
- } catch (NullPointerException ex) {
- return null;
- }
- }
- if (uri == null) {
- if (albumid >= 0) {
- Cursor c = query(context,MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
- new String[] { MediaStore.Audio.Media._ID, MediaStore.Audio.Media.ALBUM },
- MediaStore.Audio.Media.ALBUM_ID + "=?", new String [] {String.valueOf(albumid)},
- null);
- if (c != null) {
- if (c.moveToFirst()) {
- int trackid = c.getInt(0);
- uri = ContentUris.withAppendedId(
- MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, trackid);
- if (MediaFile.UNKNOWN_STRING.equals(c.getString(1))) {
- albumid = -1;
- }
- }
- c.close();
- }
- }
- }
- if (uri != null) {
- MediaScanner scanner = new MediaScanner(context);
- ParcelFileDescriptor pfd = null;
- try {
- pfd = context.getContentResolver().openFileDescriptor(uri, "r");
- if (pfd != null) {
- FileDescriptor fd = pfd.getFileDescriptor();
- art = scanner.extractAlbumArt(fd);
- }
- } catch (IOException ex) {
- } catch (SecurityException ex) {
- } finally {
- try {
- if (pfd != null) {
- pfd.close();
- }
- } catch (IOException ex) {
- }
- }
- }
+ if (albumid < 0 && songid < 0) {
+ throw new IllegalArgumentException("Must specify an album or a song id");
}
- // if no embedded art exists, look for AlbumArt.jpg in same directory as the media file
- if (art == null && path != null) {
- if (path.startsWith(sExternalMediaUri)) {
- // get the real path
- Cursor c = query(context,Uri.parse(path),
- new String[] { MediaStore.Audio.Media.DATA},
- null, null, null);
- if (c != null) {
- c.moveToFirst();
- if (!c.isAfterLast()) {
- path = c.getString(0);
- }
- c.close();
+
+ try {
+ if (albumid < 0) {
+ Uri uri = Uri.parse("content://media/external/audio/media/" + songid + "/albumart");
+ ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
+ if (pfd != null) {
+ FileDescriptor fd = pfd.getFileDescriptor();
+ bm = BitmapFactory.decodeFileDescriptor(fd);
}
- }
- int lastSlash = path.lastIndexOf('/');
- if (lastSlash > 0) {
- String artPath = path.substring(0, lastSlash + 1) + "AlbumArt.jpg";
- File file = new File(artPath);
- if (file.exists()) {
- art = new byte[(int)file.length()];
- FileInputStream stream = null;
- try {
- stream = new FileInputStream(file);
- stream.read(art);
- } catch (IOException ex) {
- art = null;
- } finally {
- try {
- if (stream != null) {
- stream.close();
- }
- } catch (IOException ex) {
- }
- }
- } else {
- // TODO: try getting album art from the web
+ } else {
+ Uri uri = ContentUris.withAppendedId(sArtworkUri, albumid);
+ ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
+ if (pfd != null) {
+ FileDescriptor fd = pfd.getFileDescriptor();
+ bm = BitmapFactory.decodeFileDescriptor(fd);
}
}
+ } catch (FileNotFoundException ex) {
+ //
}
-
- if (art != null) {
- try {
- // get the size of the bitmap
- BitmapFactory.Options opts = new BitmapFactory.Options();
- opts.inJustDecodeBounds = true;
- opts.inSampleSize = 1;
- BitmapFactory.decodeByteArray(art, 0, art.length, opts);
-
- // request a reasonably sized output image
- // TODO: don't hardcode the size
- while (opts.outHeight > 320 || opts.outWidth > 320) {
- opts.outHeight /= 2;
- opts.outWidth /= 2;
- opts.inSampleSize *= 2;
- }
-
- // get the image for real now
- opts.inJustDecodeBounds = false;
- bm = BitmapFactory.decodeByteArray(art, 0, art.length, opts);
- if (albumid != -1) {
- sArtId = albumid;
- }
- mCachedArt = art;
- mCachedBit = bm;
- } catch (Exception e) {
- }
+ if (bm != null) {
+ mCachedBit = bm;
}
return bm;
}