Require 2.0

This commit is contained in:
Christopher Eby 2011-09-16 17:52:37 -05:00
parent 0fd6230497
commit 4191ba031f
3 changed files with 6 additions and 128 deletions

View File

@ -88,7 +88,7 @@ THE SOFTWARE.
<service android:name="PlaybackService" />
<activity android:name="PreferencesActivity" />
</application>
<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="8" />
<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="10" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

View File

@ -23,12 +23,9 @@
package org.kreed.vanilla;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.BroadcastReceiver;
@ -150,17 +147,6 @@ public final class PlaybackService extends Service implements Handler.Callback,
*/
private float mCurrentVolume = 1.0f;
private static Method mStartForeground;
private static Method mStopForeground;
static {
try {
mStartForeground = Service.class.getMethod("startForeground", int.class, Notification.class);
mStopForeground = Service.class.getMethod("stopForeground", boolean.class);
} catch (NoSuchMethodException e) {
}
}
@Override
public void onCreate()
{
@ -258,7 +244,7 @@ public final class PlaybackService extends Service implements Handler.Callback,
mLooper.quit();
// clear the notification
stopForegroundCompat(true);
stopForeground(true);
if (mMediaPlayer != null) {
mTimeline.saveState(this, mMediaPlayer.getCurrentPosition());
@ -280,40 +266,6 @@ public final class PlaybackService extends Service implements Handler.Callback,
super.onDestroy();
}
public void startForegroundCompat(int id, Notification notification)
{
if (mStartForeground == null) {
setForeground(true);
mNotificationManager.notify(id, notification);
} else {
try {
mStartForeground.invoke(this, Integer.valueOf(id), notification);
} catch (InvocationTargetException e) {
Log.w("VanillaMusic", e);
} catch (IllegalAccessException e) {
Log.w("VanillaMusic", e);
}
}
}
public void stopForegroundCompat(Boolean cancelNotification)
{
if (mStopForeground == null) {
setForeground(false);
} else {
try {
mStopForeground.invoke(this, cancelNotification);
} catch (InvocationTargetException e) {
Log.w("VanillaMusic", e);
} catch (IllegalAccessException e) {
Log.w("VanillaMusic", e);
}
}
if (cancelNotification && mNotificationManager != null)
mNotificationManager.cancel(NOTIFICATION_ID);
}
/**
* Return the SharedPreferences instance containing the PlaybackService
* settings, creating it if necessary.
@ -338,7 +290,7 @@ public final class PlaybackService extends Service implements Handler.Callback,
// This is the only way to remove a notification created by
// startForeground(), even if we are not currently in foreground
// mode.
stopForegroundCompat(true);
stopForeground(true);
updateNotification();
} else if ("scrobble".equals(key)) {
mScrobble = settings.getBoolean("scrobble", false);
@ -428,7 +380,7 @@ public final class PlaybackService extends Service implements Handler.Callback,
}
}
if (mNotificationMode != NEVER)
startForegroundCompat(NOTIFICATION_ID, new SongNotification(mCurrentSong, true));
startForeground(NOTIFICATION_ID, new SongNotification(mCurrentSong, true));
if (mWakeLock != null)
mWakeLock.acquire();
@ -439,10 +391,10 @@ public final class PlaybackService extends Service implements Handler.Callback,
}
}
if (mNotificationMode == ALWAYS) {
stopForegroundCompat(false);
stopForeground(false);
mNotificationManager.notify(NOTIFICATION_ID, new SongNotification(mCurrentSong, false));
} else {
stopForegroundCompat(true);
stopForeground(true);
}
if (mWakeLock != null && mWakeLock.isHeld())

View File

@ -33,11 +33,8 @@ import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import android.provider.MediaStore;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/**
* Represents a Song backed by the MediaStore. Includes basic metadata and
@ -406,17 +403,8 @@ public class Song implements Parcelable {
Context context = ContextApplication.getContext();
ContentResolver res = context.getContentResolver();
// Query the MediaStore content provider
cover = getCoverFromMediaFile(res);
// If that fails, try using MediaScanner directly
if (cover == null)
cover = getCoverFromMediaUsingMediaScanner(res);
// Fall back to the official, documented, slow way.
if (cover == null)
cover = getCoverFromMediaStoreCache(res);
Bitmap deletedCover = mCoverCache.put(id, cover);
if (deletedCover != null)
deletedCover.recycle();
@ -450,66 +438,4 @@ public class Song implements Parcelable {
return cover;
}
/**
* Obtain the cover from a media file using the private MediaScanner API
*
* @param resolver A ContentResolver to use.
* @return The cover or null if the file has no cover art or the art could
* not be loaded using this method.
*/
private Bitmap getCoverFromMediaUsingMediaScanner(ContentResolver resolver)
{
Bitmap cover = null;
// This is a private API, so do everything using reflection
// see http://android.git.kernel.org/?p=platform/packages/apps/Music.git;a=blob;f=src/com/android/music/MusicUtils.java;h=ea2079435ca5e2c6834c9f6f02d07fe7621e0fd9;hb=aae2791ffdd8923d99242f2cf453eb66116fd6b6#l1044
try {
// Attempt to open the media file in read-only mode
Uri uri = Uri.fromFile(new File(path));
FileDescriptor fileDescriptor = resolver.openFileDescriptor(uri, "r").getFileDescriptor();
if (fileDescriptor != null) {
// Construct a MediaScanner
Class<?> mediaScannerClass = Class.forName("android.media.MediaScanner");
Constructor<?> mediaScannerConstructor = mediaScannerClass.getDeclaredConstructor(Context.class);
Object mediaScanner = mediaScannerConstructor.newInstance(ContextApplication.getContext());
// Call extractAlbumArt(fileDescriptor)
Method method = mediaScannerClass.getDeclaredMethod("extractAlbumArt", FileDescriptor.class);
byte[] artBinary = (byte[]) method.invoke(mediaScanner, fileDescriptor);
// Convert the album art to a bitmap
if (artBinary != null)
cover = BitmapFactory.decodeByteArray(artBinary, 0, artBinary.length, BITMAP_OPTIONS);
}
} catch (Exception e) {
// Swallow every exception and return an empty cover if we can't do it due to the API not being there anymore
}
return cover;
}
/**
* Get the cover from the media store cache, the documented way.
*
* @param resolver A ContentResolver to use.
* @return The cover or null if the MediaStore has no cover for the given
* song.
*/
private Bitmap getCoverFromMediaStoreCache(ContentResolver resolver)
{
Uri media = MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI;
String[] albumProjection = {MediaStore.Audio.Albums.ALBUM_ART};
String albumSelection = MediaStore.Audio.Albums._ID + '=' + albumId;
Cursor cursor = resolver.query(media, albumProjection, albumSelection, null, null);
if (cursor != null) {
if (cursor.moveToNext())
return BitmapFactory.decodeFile(cursor.getString(0), BITMAP_OPTIONS);
cursor.close();
}
return null;
}
}