Remove ContextApplication
This commit is contained in:
parent
5837753b4a
commit
2023409bd9
@ -27,8 +27,7 @@ THE SOFTWARE.
|
||||
android:installLocation="auto">
|
||||
<application
|
||||
android:icon="@drawable/icon"
|
||||
android:label="@string/app_name"
|
||||
android:name="ContextApplication">
|
||||
android:label="@string/app_name">
|
||||
<activity
|
||||
android:name="LaunchActivity"
|
||||
android:theme="@style/NoBackground">
|
||||
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010, 2011 Christopher Eby <kreed@kreed.org>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.kreed.vanilla;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Subclass of Application that provides various static utility functions
|
||||
*/
|
||||
public class ContextApplication extends Application {
|
||||
private static ContextApplication mInstance;
|
||||
private static Random mRandom;
|
||||
|
||||
public ContextApplication()
|
||||
{
|
||||
mInstance = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a shared, application-wide Random instance.
|
||||
*/
|
||||
public static Random getRandom()
|
||||
{
|
||||
if (mRandom == null)
|
||||
mRandom = new Random();
|
||||
return mRandom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides an easy to access Context instance.
|
||||
*/
|
||||
public static Context getContext()
|
||||
{
|
||||
return mInstance;
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
|
||||
package org.kreed.vanilla;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
@ -66,10 +67,12 @@ public final class CoverBitmap {
|
||||
|
||||
/**
|
||||
* Initialize the regular text size members.
|
||||
*
|
||||
* @param context A context to use.
|
||||
*/
|
||||
private static void loadTextSizes()
|
||||
private static void loadTextSizes(Context context)
|
||||
{
|
||||
DisplayMetrics metrics = ContextApplication.getContext().getResources().getDisplayMetrics();
|
||||
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
|
||||
TEXT_SIZE = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 14, metrics);
|
||||
TEXT_SIZE_BIG = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, metrics);
|
||||
PADDING = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, metrics);
|
||||
@ -78,10 +81,12 @@ public final class CoverBitmap {
|
||||
|
||||
/**
|
||||
* Initialize the icon bitmaps.
|
||||
*
|
||||
* @param context A context to use.
|
||||
*/
|
||||
private static void loadIcons()
|
||||
private static void loadIcons(Context context)
|
||||
{
|
||||
Resources res = ContextApplication.getContext().getResources();
|
||||
Resources res = context.getResources();
|
||||
Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.ic_tab_songs_selected);
|
||||
SONG_ICON = Bitmap.createScaledBitmap(bitmap, TEXT_SIZE, TEXT_SIZE, false);
|
||||
bitmap.recycle();
|
||||
@ -118,6 +123,7 @@ public final class CoverBitmap {
|
||||
* Create an image representing the given song. Includes cover art and
|
||||
* possibly song title/artist/ablum, depending on the given style.
|
||||
*
|
||||
* @param context A context to use.
|
||||
* @param style One of CoverBitmap.STYLE_*
|
||||
* @param song The song to display information for
|
||||
* @param width Maximum width of image
|
||||
@ -128,29 +134,29 @@ public final class CoverBitmap {
|
||||
* @return The image, or null if the song was null, or width or height
|
||||
* were less than 1
|
||||
*/
|
||||
public static Bitmap createBitmap(int style, Song song, int width, int height, Bitmap bitmap)
|
||||
public static Bitmap createBitmap(Context context, int style, Song song, int width, int height, Bitmap bitmap)
|
||||
{
|
||||
switch (style) {
|
||||
case STYLE_OVERLAPPING_BOX:
|
||||
return createOverlappingBitmap(song, width, height, bitmap);
|
||||
return createOverlappingBitmap(context, song, width, height, bitmap);
|
||||
case STYLE_INFO_BELOW:
|
||||
return createSeparatedBitmap(song, width, height, bitmap);
|
||||
return createSeparatedBitmap(context, song, width, height, bitmap);
|
||||
case STYLE_NO_INFO:
|
||||
return createScaledBitmap(song, width, height);
|
||||
return createScaledBitmap(context, song, width, height);
|
||||
case STYLE_NO_INFO_ZOOMED:
|
||||
return createZoomedBitmap(song, width, height, bitmap);
|
||||
return createZoomedBitmap(context, song, width, height, bitmap);
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid bitmap type given: " + style);
|
||||
}
|
||||
}
|
||||
|
||||
private static Bitmap createOverlappingBitmap(Song song, int width, int height, Bitmap bitmap)
|
||||
private static Bitmap createOverlappingBitmap(Context context, Song song, int width, int height, Bitmap bitmap)
|
||||
{
|
||||
if (song == null || width < 1 || height < 1)
|
||||
return null;
|
||||
|
||||
if (TEXT_SIZE == -1)
|
||||
loadTextSizes();
|
||||
loadTextSizes(context);
|
||||
|
||||
Paint paint = new Paint();
|
||||
paint.setAntiAlias(true);
|
||||
@ -158,7 +164,7 @@ public final class CoverBitmap {
|
||||
String title = song.title == null ? "" : song.title;
|
||||
String album = song.album == null ? "" : song.album;
|
||||
String artist = song.artist == null ? "" : song.artist;
|
||||
Bitmap cover = song.getCover();
|
||||
Bitmap cover = song.getCover(context);
|
||||
|
||||
int titleSize = TEXT_SIZE_BIG;
|
||||
int subSize = TEXT_SIZE;
|
||||
@ -238,15 +244,15 @@ public final class CoverBitmap {
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
private static Bitmap createSeparatedBitmap(Song song, int width, int height, Bitmap bitmap)
|
||||
private static Bitmap createSeparatedBitmap(Context context, Song song, int width, int height, Bitmap bitmap)
|
||||
{
|
||||
if (song == null || width < 1 || height < 1)
|
||||
return null;
|
||||
|
||||
if (TEXT_SIZE == -1)
|
||||
loadTextSizes();
|
||||
loadTextSizes(context);
|
||||
if (SONG_ICON == null)
|
||||
loadIcons();
|
||||
loadIcons(context);
|
||||
|
||||
boolean horizontal = width > height;
|
||||
|
||||
@ -256,7 +262,7 @@ public final class CoverBitmap {
|
||||
String title = song.title == null ? "" : song.title;
|
||||
String album = song.album == null ? "" : song.album;
|
||||
String artist = song.artist == null ? "" : song.artist;
|
||||
Bitmap cover = song.getCover();
|
||||
Bitmap cover = song.getCover(context);
|
||||
|
||||
int textSize = TEXT_SIZE;
|
||||
int padding = PADDING;
|
||||
@ -340,12 +346,12 @@ public final class CoverBitmap {
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
private static Bitmap createZoomedBitmap(Song song, int width, int height, Bitmap bitmap)
|
||||
private static Bitmap createZoomedBitmap(Context context, Song song, int width, int height, Bitmap bitmap)
|
||||
{
|
||||
if (song == null || width < 1 || height < 1)
|
||||
return null;
|
||||
|
||||
Bitmap cover = song.getCover();
|
||||
Bitmap cover = song.getCover(context);
|
||||
if (cover == null)
|
||||
return null;
|
||||
|
||||
@ -379,17 +385,18 @@ public final class CoverBitmap {
|
||||
* preserved. At least one dimension of the result will match the provided
|
||||
* dimension exactly.
|
||||
*
|
||||
* @param context A context to use.
|
||||
* @param song The song to display information for
|
||||
* @param width Maximum width of image
|
||||
* @param height Maximum height of image
|
||||
* @return The scaled Bitmap, or null if a cover could not be found.
|
||||
*/
|
||||
public static Bitmap createScaledBitmap(Song song, int width, int height)
|
||||
public static Bitmap createScaledBitmap(Context context, Song song, int width, int height)
|
||||
{
|
||||
if (song == null || width < 1 || height < 1)
|
||||
return null;
|
||||
|
||||
Bitmap cover = song.getCover();
|
||||
Bitmap cover = song.getCover(context);
|
||||
if (cover == null)
|
||||
return null;
|
||||
|
||||
|
@ -326,7 +326,7 @@ public final class CoverView extends View implements Handler.Callback {
|
||||
|
||||
Bitmap bitmap = mBitmapCache.get(song.id);
|
||||
if (bitmap == null) {
|
||||
mBitmapCache.put(song.id, CoverBitmap.createBitmap(mCoverStyle, song, getWidth(), getHeight(), mBitmapCache.discardOldest()));
|
||||
mBitmapCache.put(song.id, CoverBitmap.createBitmap(getContext(), mCoverStyle, song, getWidth(), getHeight(), mBitmapCache.discardOldest()));
|
||||
postInvalidate();
|
||||
} else {
|
||||
mBitmapCache.touch(song.id);
|
||||
|
@ -51,7 +51,7 @@ import java.io.Serializable;
|
||||
* MediaAdapter provides an adapter backed by a MediaStore content provider.
|
||||
* It generates simple one- or two-line text views to display each media
|
||||
* element.
|
||||
*
|
||||
*
|
||||
* Filtering is supported, as is a more specific type of filtering referred to
|
||||
* as limiting. Limiting is separate from filtering; a new filter will not
|
||||
* erase an active filter. Limiting is intended to allow only media belonging
|
||||
@ -59,6 +59,8 @@ import java.io.Serializable;
|
||||
* See MediaView.getLimiter and setLimiter for details.
|
||||
*/
|
||||
public class MediaAdapter extends CursorAdapter implements FilterQueryProvider {
|
||||
private Context mContext;
|
||||
|
||||
/**
|
||||
* The type of media represented by this adapter. Must be one of the
|
||||
* MediaUtils.FIELD_* constants. Determines which content provider to query for
|
||||
@ -113,6 +115,7 @@ public class MediaAdapter extends CursorAdapter implements FilterQueryProvider {
|
||||
{
|
||||
super(context, null, requery);
|
||||
|
||||
mContext = context;
|
||||
mType = type;
|
||||
mExpandable = expandable;
|
||||
mLimiter = limiter;
|
||||
@ -225,7 +228,7 @@ public class MediaAdapter extends CursorAdapter implements FilterQueryProvider {
|
||||
*/
|
||||
public Cursor runQuery(CharSequence constraint)
|
||||
{
|
||||
ContentResolver resolver = ContextApplication.getContext().getContentResolver();
|
||||
ContentResolver resolver = mContext.getContentResolver();
|
||||
|
||||
String[] projection;
|
||||
if (mFields.length == 1)
|
||||
@ -279,7 +282,7 @@ public class MediaAdapter extends CursorAdapter implements FilterQueryProvider {
|
||||
if (mLimiter.type == MediaUtils.TYPE_GENRE) {
|
||||
// Genre is not standard metadata for MediaStore.Audio.Media.
|
||||
// We have to query it through a separate provider. : /
|
||||
return MediaUtils.queryGenre(mLimiter.id, projection, selection.toString(), selectionArgs);
|
||||
return MediaUtils.queryGenre(mContext, mLimiter.id, projection, selection.toString(), selectionArgs);
|
||||
} else {
|
||||
if (selection.length() != 0)
|
||||
selection.append(" AND ");
|
||||
|
@ -56,6 +56,8 @@ public class MediaButtonHandler {
|
||||
* uninitialized.
|
||||
*/
|
||||
private static int mUseControls = -1;
|
||||
|
||||
private Context mContext;
|
||||
/**
|
||||
* Whether the phone is currently in a call. 1 for yes, 0 for no, -1 for
|
||||
* uninitialized.
|
||||
@ -75,11 +77,11 @@ public class MediaButtonHandler {
|
||||
* Retrieve the MediaButtonHandler singleton, creating it if necessary.
|
||||
* Returns null if headset controls are not enabled.
|
||||
*/
|
||||
public static MediaButtonHandler getInstance()
|
||||
public static MediaButtonHandler getInstance(Context context)
|
||||
{
|
||||
if (useHeadsetControls()) {
|
||||
if (useHeadsetControls(context)) {
|
||||
if (mInstance == null)
|
||||
mInstance = new MediaButtonHandler();
|
||||
mInstance = new MediaButtonHandler(context.getApplicationContext());
|
||||
return mInstance;
|
||||
}
|
||||
return null;
|
||||
@ -88,10 +90,9 @@ public class MediaButtonHandler {
|
||||
/**
|
||||
* Construct a MediaButtonHandler.
|
||||
*/
|
||||
private MediaButtonHandler()
|
||||
private MediaButtonHandler(Context context)
|
||||
{
|
||||
Context context = ContextApplication.getContext();
|
||||
|
||||
mContext = context;
|
||||
mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
|
||||
mButtonReceiver = new ComponentName(context.getPackageName(), MediaButtonReceiver.class.getName());
|
||||
try {
|
||||
@ -102,17 +103,16 @@ public class MediaButtonHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private static void loadPreference()
|
||||
/**
|
||||
* Reload the preference and enable/disable buttons as appropriate.
|
||||
*
|
||||
* @param context A context to use.
|
||||
*/
|
||||
public static void reloadPreference(Context context)
|
||||
{
|
||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(ContextApplication.getContext());
|
||||
mUseControls = settings.getBoolean("media_button", true) ? 1 : 0;
|
||||
}
|
||||
|
||||
public static void reloadPreference()
|
||||
{
|
||||
loadPreference();
|
||||
if (useHeadsetControls()) {
|
||||
getInstance().registerMediaButton();
|
||||
mUseControls = -1;
|
||||
if (useHeadsetControls(context)) {
|
||||
getInstance(context).registerMediaButton();
|
||||
} else {
|
||||
unregisterMediaButton();
|
||||
}
|
||||
@ -121,11 +121,16 @@ public class MediaButtonHandler {
|
||||
/**
|
||||
* Return whether headset controls should be used, loading the preference
|
||||
* if necessary.
|
||||
*
|
||||
* @param context A context to use.
|
||||
*/
|
||||
public static boolean useHeadsetControls()
|
||||
public static boolean useHeadsetControls(Context context)
|
||||
{
|
||||
if (mUseControls == -1)
|
||||
loadPreference();
|
||||
if (mUseControls == -1) {
|
||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
mUseControls = settings.getBoolean("media_button", true) ? 1 : 0;
|
||||
}
|
||||
|
||||
return mUseControls == 1;
|
||||
}
|
||||
|
||||
@ -135,8 +140,7 @@ public class MediaButtonHandler {
|
||||
private boolean isInCall()
|
||||
{
|
||||
if (mInCall == -1) {
|
||||
Context context = ContextApplication.getContext();
|
||||
TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
TelephonyManager manager = (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
mInCall = (byte)(manager.getCallState() == TelephonyManager.CALL_STATE_IDLE ? 0 : 1);
|
||||
}
|
||||
return mInCall == 1;
|
||||
@ -157,12 +161,11 @@ public class MediaButtonHandler {
|
||||
*
|
||||
* @param action One of the PlaybackService.ACTION_* actions.
|
||||
*/
|
||||
private static void act(String action)
|
||||
private void act(String action)
|
||||
{
|
||||
Context context = ContextApplication.getContext();
|
||||
Intent intent = new Intent(context, PlaybackService.class);
|
||||
Intent intent = new Intent(mContext, PlaybackService.class);
|
||||
intent.setAction(action);
|
||||
context.startService(intent);
|
||||
mContext.startService(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -170,7 +173,7 @@ public class MediaButtonHandler {
|
||||
*/
|
||||
public boolean processKey(KeyEvent event)
|
||||
{
|
||||
if (event == null || isInCall() || !useHeadsetControls())
|
||||
if (event == null || isInCall() || !useHeadsetControls(mContext))
|
||||
return false;
|
||||
|
||||
int action = event.getAction();
|
||||
|
@ -31,7 +31,7 @@ public class MediaButtonReceiver extends BroadcastReceiver {
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
|
||||
boolean handled = MediaButtonHandler.getInstance().process(intent);
|
||||
boolean handled = MediaButtonHandler.getInstance(context).process(intent);
|
||||
if (handled && isOrderedBroadcast())
|
||||
abortBroadcast();
|
||||
}
|
||||
|
@ -53,18 +53,34 @@ public class MediaUtils {
|
||||
*/
|
||||
public static final int TYPE_GENRE = 5;
|
||||
|
||||
/**
|
||||
* Cached random instance.
|
||||
*/
|
||||
private static Random sRandom;
|
||||
|
||||
/**
|
||||
* Returns a cached random instanced, creating it if necessary.
|
||||
*/
|
||||
public static Random getRandom()
|
||||
{
|
||||
if (sRandom == null)
|
||||
sRandom = new Random();
|
||||
return sRandom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a cursor containing the ids of all the songs with artist or
|
||||
* album of the specified id.
|
||||
*
|
||||
* @param context A context to use.
|
||||
* @param type One of the TYPE_* constants, excluding playlists.
|
||||
* @param id The MediaStore id of the artist or album.
|
||||
* @param projection The columns to query.
|
||||
* @param select An extra selection to pass to the query, or null.
|
||||
*/
|
||||
private static Cursor getMediaCursor(int type, long id, String[] projection, String select)
|
||||
private static Cursor getMediaCursor(Context context, int type, long id, String[] projection, String select)
|
||||
{
|
||||
ContentResolver resolver = ContextApplication.getContext().getContentResolver();
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Uri media = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
||||
StringBuilder selection = new StringBuilder();
|
||||
|
||||
@ -99,12 +115,13 @@ public class MediaUtils {
|
||||
* Return a cursor containing the ids of all the songs in the playlist
|
||||
* with the given id.
|
||||
*
|
||||
* @param context A context to use.
|
||||
* @param id The id of the playlist in MediaStore.Audio.Playlists.
|
||||
* @param projection The columns to query.
|
||||
*/
|
||||
private static Cursor getPlaylistCursor(long id, String[] projection)
|
||||
private static Cursor getPlaylistCursor(Context context, long id, String[] projection)
|
||||
{
|
||||
ContentResolver resolver = ContextApplication.getContext().getContentResolver();
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", id);
|
||||
String sort = MediaStore.Audio.Playlists.Members.PLAY_ORDER;
|
||||
return resolver.query(uri, projection, null, null, sort);
|
||||
@ -114,14 +131,15 @@ public class MediaUtils {
|
||||
* Return a cursor containing the ids of all the songs in the genre
|
||||
* with the given id.
|
||||
*
|
||||
* @param context A context to use.
|
||||
* @param id The id of the genre in MediaStore.Audio.Genres.
|
||||
* @param projection The columns to query.
|
||||
* @param selection The selection to pass to the query, or null.
|
||||
* @param selectionArgs The arguments to substitute into the selection.
|
||||
*/
|
||||
public static Cursor queryGenre(long id, String[] projection, String selection, String[] selectionArgs)
|
||||
public static Cursor queryGenre(Context context, long id, String[] projection, String selection, String[] selectionArgs)
|
||||
{
|
||||
ContentResolver resolver = ContextApplication.getContext().getContentResolver();
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Uri uri = MediaStore.Audio.Genres.Members.getContentUri("external", id);
|
||||
String sort = MediaStore.Audio.Genres.Members.TITLE_KEY;
|
||||
return resolver.query(uri, projection, selection, selectionArgs, sort);
|
||||
@ -130,6 +148,7 @@ public class MediaUtils {
|
||||
/**
|
||||
* Returns a Cursor queried with the given information.
|
||||
*
|
||||
* @param context A context to use.
|
||||
* @param type Type the id represents. Must be one of the Song.TYPE_*
|
||||
* constants.
|
||||
* @param id The id of the element in the MediaStore content provider for
|
||||
@ -137,18 +156,18 @@ public class MediaUtils {
|
||||
* @param selection An extra selection to be passed to the query. May be
|
||||
* null. Must not be used with type == TYPE_SONG or type == TYPE_PLAYLIST
|
||||
*/
|
||||
public static Cursor query(int type, long id, String[] projection, String selection)
|
||||
public static Cursor query(Context context, int type, long id, String[] projection, String selection)
|
||||
{
|
||||
switch (type) {
|
||||
case TYPE_ARTIST:
|
||||
case TYPE_ALBUM:
|
||||
case TYPE_SONG:
|
||||
return getMediaCursor(type, id, projection, selection);
|
||||
return getMediaCursor(context, type, id, projection, selection);
|
||||
case TYPE_PLAYLIST:
|
||||
assert(selection == null);
|
||||
return getPlaylistCursor(id, projection);
|
||||
return getPlaylistCursor(context, id, projection);
|
||||
case TYPE_GENRE:
|
||||
return queryGenre(id, projection, selection, null);
|
||||
return queryGenre(context, id, projection, selection, null);
|
||||
default:
|
||||
throw new IllegalArgumentException("Specified type not valid: " + type);
|
||||
}
|
||||
@ -157,21 +176,22 @@ public class MediaUtils {
|
||||
/**
|
||||
* Return an array containing all the song ids that match the specified parameters
|
||||
*
|
||||
* @param context A context to use.
|
||||
* @param type Type the id represents. Must be one of the Song.TYPE_*
|
||||
* constants.
|
||||
* @param id The id of the element in the MediaStore content provider for
|
||||
* the given type.
|
||||
*/
|
||||
public static long[] getAllSongIdsWith(int type, long id)
|
||||
public static long[] getAllSongIdsWith(Context context, int type, long id)
|
||||
{
|
||||
if (type == TYPE_SONG)
|
||||
return new long[] { id };
|
||||
|
||||
Cursor cursor;
|
||||
if (type == MediaUtils.TYPE_PLAYLIST)
|
||||
cursor = query(type, id, Song.EMPTY_PLAYLIST_PROJECTION, null);
|
||||
cursor = query(context, type, id, Song.EMPTY_PLAYLIST_PROJECTION, null);
|
||||
else
|
||||
cursor = query(type, id, Song.EMPTY_PROJECTION, null);
|
||||
cursor = query(context, type, id, Song.EMPTY_PROJECTION, null);
|
||||
if (cursor == null)
|
||||
return null;
|
||||
|
||||
@ -204,7 +224,7 @@ public class MediaUtils {
|
||||
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
String[] projection = new String [] { MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DATA };
|
||||
Cursor cursor = getMediaCursor(type, id, projection, null);
|
||||
Cursor cursor = getMediaCursor(context, type, id, projection, null);
|
||||
|
||||
if (cursor != null) {
|
||||
PlaybackService service = PlaybackService.hasInstance() ? PlaybackService.get(context) : null;
|
||||
@ -230,13 +250,13 @@ public class MediaUtils {
|
||||
* Query the MediaStore to determine the id of the genre the song belongs
|
||||
* to.
|
||||
*/
|
||||
public static long queryGenreForSong(long id)
|
||||
public static long queryGenreForSong(Context context, long id)
|
||||
{
|
||||
// This is terribly inefficient, but it seems to be the only way to do
|
||||
// this. Honeycomb introduced an API to query the genre of the song.
|
||||
// We should look into it when ICS is released.
|
||||
|
||||
ContentResolver resolver = ContextApplication.getContext().getContentResolver();
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
|
||||
// query ids of all the genres
|
||||
Uri uri = MediaStore.Audio.Genres.EXTERNAL_CONTENT_URI;
|
||||
@ -269,7 +289,7 @@ public class MediaUtils {
|
||||
*/
|
||||
public static void shuffle(long[] list)
|
||||
{
|
||||
Random random = ContextApplication.getRandom();
|
||||
Random random = getRandom();
|
||||
for (int i = list.length; --i != -1; ) {
|
||||
int j = random.nextInt(i + 1);
|
||||
long tmp = list[j];
|
||||
@ -287,7 +307,7 @@ public class MediaUtils {
|
||||
public static void shuffle(Song[] list, int end)
|
||||
{
|
||||
assert(end <= list.length && end >= 0);
|
||||
Random random = ContextApplication.getRandom();
|
||||
Random random = getRandom();
|
||||
for (int i = end; --i != -1; ) {
|
||||
int j = random.nextInt(i + 1);
|
||||
Song tmp = list[j];
|
||||
|
@ -125,7 +125,7 @@ public class NewPlaylistDialog extends Dialog implements TextWatcher, View.OnCli
|
||||
mPositiveButton.setEnabled(true);
|
||||
// Update the action button based on whether there is an
|
||||
// existing playlist with the given name.
|
||||
int res = Playlist.getPlaylist(string) == -1 ? mActionRes : R.string.overwrite;
|
||||
int res = Playlist.getPlaylist(getContext(), string) == -1 ? mActionRes : R.string.overwrite;
|
||||
mPositiveButton.setText(res);
|
||||
}
|
||||
}
|
||||
@ -150,4 +150,4 @@ public class NewPlaylistDialog extends Dialog implements TextWatcher, View.OnCli
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ public class PlaybackActivity extends Activity implements Handler.Callback, View
|
||||
PlaybackService service = PlaybackService.get(this);
|
||||
service.userActionTriggered();
|
||||
|
||||
MediaButtonHandler buttons = MediaButtonHandler.getInstance();
|
||||
MediaButtonHandler buttons = MediaButtonHandler.getInstance(this);
|
||||
if (buttons != null)
|
||||
buttons.setInCall(false);
|
||||
}
|
||||
@ -127,7 +127,7 @@ public class PlaybackActivity extends Activity implements Handler.Callback, View
|
||||
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
|
||||
case KeyEvent.KEYCODE_MEDIA_NEXT:
|
||||
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
|
||||
return MediaButtonHandler.getInstance().processKey(event);
|
||||
return MediaButtonHandler.getInstance(this).processKey(event);
|
||||
}
|
||||
|
||||
return super.onKeyDown(keyCode, event);
|
||||
@ -141,7 +141,7 @@ public class PlaybackActivity extends Activity implements Handler.Callback, View
|
||||
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
|
||||
case KeyEvent.KEYCODE_MEDIA_NEXT:
|
||||
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
|
||||
return MediaButtonHandler.getInstance().processKey(event);
|
||||
return MediaButtonHandler.getInstance(this).processKey(event);
|
||||
}
|
||||
|
||||
return super.onKeyUp(keyCode, event);
|
||||
|
@ -184,9 +184,9 @@ public final class PlaybackService extends Service implements Handler.Callback,
|
||||
HandlerThread thread = new HandlerThread("PlaybackService");
|
||||
thread.start();
|
||||
|
||||
mTimeline = new SongTimeline();
|
||||
mTimeline = new SongTimeline(this);
|
||||
mTimeline.setCallback(this);
|
||||
mPendingSeek = mTimeline.loadState(this);
|
||||
mPendingSeek = mTimeline.loadState();
|
||||
|
||||
mMediaPlayer = new MediaPlayer();
|
||||
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
|
||||
@ -268,7 +268,7 @@ public final class PlaybackService extends Service implements Handler.Callback,
|
||||
}
|
||||
|
||||
userActionTriggered();
|
||||
MediaButtonHandler buttons = MediaButtonHandler.getInstance();
|
||||
MediaButtonHandler buttons = MediaButtonHandler.getInstance(this);
|
||||
if (buttons != null)
|
||||
buttons.registerMediaButton();
|
||||
}
|
||||
@ -285,7 +285,7 @@ public final class PlaybackService extends Service implements Handler.Callback,
|
||||
stopForeground(true);
|
||||
|
||||
if (mMediaPlayer != null) {
|
||||
mTimeline.saveState(this, mMediaPlayer.getCurrentPosition());
|
||||
mTimeline.saveState(mMediaPlayer.getCurrentPosition());
|
||||
mMediaPlayer.release();
|
||||
mMediaPlayer = null;
|
||||
}
|
||||
@ -338,7 +338,7 @@ public final class PlaybackService extends Service implements Handler.Callback,
|
||||
if (mMediaPlayer != null)
|
||||
mMediaPlayer.setVolume(volume, volume);
|
||||
} else if ("media_button".equals(key)) {
|
||||
MediaButtonHandler.reloadPreference();
|
||||
MediaButtonHandler.reloadPreference(this);
|
||||
} else if ("use_idle_timeout".equals(key) || "idle_timeout".equals(key)) {
|
||||
mIdleTimeout = settings.getBoolean("use_idle_timeout", false) ? settings.getInt("idle_timeout", 3600) : 0;
|
||||
userActionTriggered();
|
||||
@ -417,7 +417,7 @@ public final class PlaybackService extends Service implements Handler.Callback,
|
||||
mMediaPlayer.start();
|
||||
|
||||
if (mNotificationMode != NEVER)
|
||||
startForeground(NOTIFICATION_ID, new SongNotification(mCurrentSong, true));
|
||||
startForeground(NOTIFICATION_ID, new SongNotification(this, mCurrentSong, true));
|
||||
|
||||
if (mWakeLock != null)
|
||||
mWakeLock.acquire();
|
||||
@ -427,7 +427,7 @@ public final class PlaybackService extends Service implements Handler.Callback,
|
||||
|
||||
if (mNotificationMode == ALWAYS) {
|
||||
stopForeground(false);
|
||||
mNotificationManager.notify(NOTIFICATION_ID, new SongNotification(mCurrentSong, false));
|
||||
mNotificationManager.notify(NOTIFICATION_ID, new SongNotification(this, mCurrentSong, false));
|
||||
} else {
|
||||
stopForeground(true);
|
||||
}
|
||||
@ -512,7 +512,7 @@ public final class PlaybackService extends Service implements Handler.Callback,
|
||||
private void updateNotification()
|
||||
{
|
||||
if ((mNotificationMode == ALWAYS || mNotificationMode == WHEN_PLAYING && (mState & FLAG_PLAYING) != 0) && mCurrentSong != null)
|
||||
mNotificationManager.notify(NOTIFICATION_ID, new SongNotification(mCurrentSong, (mState & FLAG_PLAYING) != 0));
|
||||
mNotificationManager.notify(NOTIFICATION_ID, new SongNotification(this, mCurrentSong, (mState & FLAG_PLAYING) != 0));
|
||||
else
|
||||
mNotificationManager.cancel(NOTIFICATION_ID);
|
||||
}
|
||||
@ -587,7 +587,7 @@ public final class PlaybackService extends Service implements Handler.Callback,
|
||||
Song song = mTimeline.shiftCurrentSong(delta);
|
||||
mCurrentSong = song;
|
||||
if (song == null || song.id == -1 || song.path == null) {
|
||||
if (Song.isSongAvailable()) {
|
||||
if (Song.isSongAvailable(this)) {
|
||||
int flag = (mState & FLAG_RANDOM) == 0 ? FLAG_EMPTY_QUEUE : FLAG_ERROR;
|
||||
synchronized (mStateLock) {
|
||||
updateState((mState | flag) & ~FLAG_NO_MEDIA);
|
||||
@ -713,7 +713,7 @@ public final class PlaybackService extends Service implements Handler.Callback,
|
||||
switch (state) {
|
||||
case TelephonyManager.CALL_STATE_RINGING:
|
||||
case TelephonyManager.CALL_STATE_OFFHOOK: {
|
||||
MediaButtonHandler buttons = MediaButtonHandler.getInstance();
|
||||
MediaButtonHandler buttons = MediaButtonHandler.getInstance(PlaybackService.this);
|
||||
if (buttons != null)
|
||||
buttons.setInCall(true);
|
||||
|
||||
@ -726,7 +726,7 @@ public final class PlaybackService extends Service implements Handler.Callback,
|
||||
break;
|
||||
}
|
||||
case TelephonyManager.CALL_STATE_IDLE: {
|
||||
MediaButtonHandler buttons = MediaButtonHandler.getInstance();
|
||||
MediaButtonHandler buttons = MediaButtonHandler.getInstance(PlaybackService.this);
|
||||
if (buttons != null)
|
||||
buttons.setInCall(false);
|
||||
|
||||
@ -742,7 +742,7 @@ public final class PlaybackService extends Service implements Handler.Callback,
|
||||
|
||||
public void onMediaChange()
|
||||
{
|
||||
if (Song.isSongAvailable()) {
|
||||
if (Song.isSongAvailable(this)) {
|
||||
if ((mState & FLAG_NO_MEDIA) != 0)
|
||||
setCurrentSong(0);
|
||||
} else {
|
||||
@ -804,7 +804,7 @@ public final class PlaybackService extends Service implements Handler.Callback,
|
||||
case SAVE_STATE:
|
||||
// For unexpected terminations: crashes, task killers, etc.
|
||||
// In most cases onDestroy will handle this
|
||||
mTimeline.saveState(this, 0);
|
||||
mTimeline.saveState(0);
|
||||
break;
|
||||
case PROCESS_SONG:
|
||||
processSong((Song)message.obj);
|
||||
@ -994,7 +994,7 @@ public final class PlaybackService extends Service implements Handler.Callback,
|
||||
id = current.albumId;
|
||||
break;
|
||||
case MediaUtils.TYPE_GENRE:
|
||||
id = MediaUtils.queryGenreForSong(current.id);
|
||||
id = MediaUtils.queryGenreForSong(this, current.id);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported media type: " + type);
|
||||
|
@ -25,6 +25,7 @@ package org.kreed.vanilla;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.provider.MediaStore;
|
||||
@ -56,11 +57,12 @@ public class Playlist {
|
||||
/**
|
||||
* Queries all the playlists known to the MediaStore.
|
||||
*
|
||||
* @param context A context to use.
|
||||
* @return An array of Playlists
|
||||
*/
|
||||
public static Playlist[] getPlaylists()
|
||||
public static Playlist[] getPlaylists(Context context)
|
||||
{
|
||||
ContentResolver resolver = ContextApplication.getContext().getContentResolver();
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Uri media = MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI;
|
||||
String[] projection = { MediaStore.Audio.Playlists._ID, MediaStore.Audio.Playlists.NAME };
|
||||
String sort = MediaStore.Audio.Playlists.NAME;
|
||||
@ -87,15 +89,16 @@ public class Playlist {
|
||||
/**
|
||||
* Retrieves the id for a playlist with the given name.
|
||||
*
|
||||
* @param context A context to use.
|
||||
* @param name The name of the playlist.
|
||||
* @return The id of the playlist, or -1 if there is no playlist with the
|
||||
* given name.
|
||||
*/
|
||||
public static long getPlaylist(String name)
|
||||
public static long getPlaylist(Context context, String name)
|
||||
{
|
||||
long id = -1;
|
||||
|
||||
ContentResolver resolver = ContextApplication.getContext().getContentResolver();
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Cursor cursor = resolver.query(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
|
||||
new String[] { MediaStore.Audio.Playlists._ID },
|
||||
MediaStore.Audio.Playlists.NAME + "=?",
|
||||
@ -114,13 +117,14 @@ public class Playlist {
|
||||
* Create a new playlist with the given name. If a playlist with the given
|
||||
* name already exists, it will be overwritten.
|
||||
*
|
||||
* @param context A context to use.
|
||||
* @param name The name of the playlist.
|
||||
* @return The id of the new playlist.
|
||||
*/
|
||||
public static long createPlaylist(String name)
|
||||
public static long createPlaylist(Context context, String name)
|
||||
{
|
||||
ContentResolver resolver = ContextApplication.getContext().getContentResolver();
|
||||
long id = getPlaylist(name);
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
long id = getPlaylist(context, name);
|
||||
|
||||
if (id == -1) {
|
||||
// We need to create a new playlist.
|
||||
@ -140,14 +144,15 @@ public class Playlist {
|
||||
/**
|
||||
* Add the given set of song ids to the playlist with the given id.
|
||||
*
|
||||
* @param context A context to use.
|
||||
* @param playlistId The MediaStore.Audio.Playlist id of the playlist to
|
||||
* modify.
|
||||
* @param toAdd The MediaStore ids of all the songs to be added to the
|
||||
* playlist.
|
||||
*/
|
||||
public static void addToPlaylist(long playlistId, long[] toAdd)
|
||||
public static void addToPlaylist(Context context, long playlistId, long[] toAdd)
|
||||
{
|
||||
ContentResolver resolver = ContextApplication.getContext().getContentResolver();
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId);
|
||||
String[] projection = new String[] { MediaStore.Audio.Playlists.Members.PLAY_ORDER };
|
||||
Cursor cursor = resolver.query(uri, projection, null, null, null);
|
||||
@ -168,31 +173,33 @@ public class Playlist {
|
||||
/**
|
||||
* Delete the playlist with the given id.
|
||||
*
|
||||
* @param context A context to use.
|
||||
* @param id The Media.Audio.Playlists id of the playlist.
|
||||
*/
|
||||
public static void deletePlaylist(long id)
|
||||
public static void deletePlaylist(Context context, long id)
|
||||
{
|
||||
Uri uri = ContentUris.withAppendedId(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, id);
|
||||
ContextApplication.getContext().getContentResolver().delete(uri, null, null);
|
||||
context.getContentResolver().delete(uri, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename the playlist with the given id.
|
||||
*
|
||||
* @param context A context to use.
|
||||
* @param id The Media.Audio.Playlists id of the playlist.
|
||||
* @param newName The new name for the playlist.
|
||||
*/
|
||||
public static void renamePlaylist(long id, String newName)
|
||||
public static void renamePlaylist(Context context, long id, String newName)
|
||||
{
|
||||
long existingId = getPlaylist(newName);
|
||||
long existingId = getPlaylist(context, newName);
|
||||
// We are already called the requested name; nothing to do.
|
||||
if (existingId == id)
|
||||
return;
|
||||
// There is already a playlist with this name. Kill it.
|
||||
if (existingId != -1)
|
||||
deletePlaylist(existingId);
|
||||
deletePlaylist(context, existingId);
|
||||
|
||||
ContentResolver resolver = ContextApplication.getContext().getContentResolver();
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
ContentValues values = new ContentValues(1);
|
||||
values.put(MediaStore.Audio.Playlists.NAME, newName);
|
||||
resolver.update(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, values, MediaStore.Audio.Playlists._ID + "=" + id, null);
|
||||
|
@ -146,13 +146,16 @@ public class Song {
|
||||
public int flags;
|
||||
|
||||
/**
|
||||
* @return true if it's possible to retrieve any songs, otherwise false. For example, false
|
||||
* could be returned if there are no songs in the library.
|
||||
* Determine if any songs are available from the library.
|
||||
*
|
||||
* @param context A context to use.
|
||||
* @return True if it's possible to retrieve any songs, false otherwise. For
|
||||
* example, false could be returned if there are no songs in the library.
|
||||
*/
|
||||
public static boolean isSongAvailable()
|
||||
public static boolean isSongAvailable(Context context)
|
||||
{
|
||||
if (mSongCount == -1) {
|
||||
ContentResolver resolver = ContextApplication.getContext().getContentResolver();
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Uri media = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
||||
String selection = MediaStore.Audio.Media.IS_MUSIC + "!=0";
|
||||
Cursor cursor = resolver.query(media, new String[]{"count(_id)"}, selection, null, null);
|
||||
@ -169,13 +172,15 @@ public class Song {
|
||||
/**
|
||||
* Returns a shuffled array contaning the ids of all the songs on the
|
||||
* device's library.
|
||||
*
|
||||
* @param context A context to use.
|
||||
*/
|
||||
public static long[] loadAllSongs()
|
||||
public static long[] loadAllSongs(Context context)
|
||||
{
|
||||
mAllSongsIdx = 0;
|
||||
mRandomCacheEnd = -1;
|
||||
|
||||
ContentResolver resolver = ContextApplication.getContext().getContentResolver();
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Uri media = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
||||
String selection = MediaStore.Audio.Media.IS_MUSIC + "!=0";
|
||||
Cursor cursor = resolver.query(media, EMPTY_PROJECTION, selection, null, null);
|
||||
@ -208,13 +213,15 @@ public class Song {
|
||||
/**
|
||||
* Returns a song randomly selected from all the songs in the Android
|
||||
* MediaStore.
|
||||
*
|
||||
* @param context A context to use.
|
||||
*/
|
||||
public static Song randomSong()
|
||||
public static Song randomSong(Context context)
|
||||
{
|
||||
long[] songs = mAllSongs;
|
||||
|
||||
if (songs == null) {
|
||||
songs = loadAllSongs();
|
||||
songs = loadAllSongs(context);
|
||||
if (songs == null)
|
||||
return null;
|
||||
mAllSongs = songs;
|
||||
@ -225,7 +232,7 @@ public class Song {
|
||||
}
|
||||
|
||||
if (mAllSongsIdx >= mRandomCacheEnd) {
|
||||
ContentResolver resolver = ContextApplication.getContext().getContentResolver();
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Uri media = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
||||
|
||||
StringBuilder selection = new StringBuilder("_ID IN (");
|
||||
@ -346,9 +353,10 @@ public class Song {
|
||||
/**
|
||||
* Query the album art for this song.
|
||||
*
|
||||
* @param context A context to use.
|
||||
* @return The album art or null if no album art could be found
|
||||
*/
|
||||
public Bitmap getCover()
|
||||
public Bitmap getCover(Context context)
|
||||
{
|
||||
if (id == -1 || mDisableCoverArt)
|
||||
return null;
|
||||
@ -358,10 +366,17 @@ public class Song {
|
||||
if (cover != null)
|
||||
return cover;
|
||||
|
||||
Context context = ContextApplication.getContext();
|
||||
ContentResolver res = context.getContentResolver();
|
||||
|
||||
cover = getCoverFromMediaFile(res);
|
||||
try {
|
||||
ParcelFileDescriptor parcelFileDescriptor = res.openFileDescriptor(getCoverUri(), "r");
|
||||
if (parcelFileDescriptor != null) {
|
||||
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
|
||||
cover = BitmapFactory.decodeFileDescriptor(fileDescriptor, null, BITMAP_OPTIONS);
|
||||
}
|
||||
} catch (IllegalStateException e) {
|
||||
} catch (FileNotFoundException e) {
|
||||
}
|
||||
|
||||
Bitmap deletedCover = mCoverCache.put(id, cover);
|
||||
if (deletedCover != null)
|
||||
@ -384,30 +399,6 @@ public class Song {
|
||||
return Uri.parse("content://media/external/audio/media/" + id + "/albumart");
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to read the album art directly from a media file using the
|
||||
* media ContentProvider.
|
||||
*
|
||||
* @param resolver A ContentResolver to use.
|
||||
* @return The album art or null if no album art could be found.
|
||||
*/
|
||||
private Bitmap getCoverFromMediaFile(ContentResolver resolver)
|
||||
{
|
||||
Bitmap cover = null;
|
||||
|
||||
try {
|
||||
ParcelFileDescriptor parcelFileDescriptor = resolver.openFileDescriptor(getCoverUri(), "r");
|
||||
if (parcelFileDescriptor != null) {
|
||||
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
|
||||
cover = BitmapFactory.decodeFileDescriptor(fileDescriptor, null, BITMAP_OPTIONS);
|
||||
}
|
||||
} catch (IllegalStateException e) {
|
||||
} catch (FileNotFoundException e) {
|
||||
}
|
||||
|
||||
return cover;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
@ -62,9 +62,8 @@ public class SongNotification extends Notification {
|
||||
* @param song The Song to display information about.
|
||||
* @param playing True if music is playing.
|
||||
*/
|
||||
public SongNotification(Song song, boolean playing)
|
||||
public SongNotification(Context context, Song song, boolean playing)
|
||||
{
|
||||
Context context = ContextApplication.getContext();
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
int action = Integer.parseInt(prefs.getString("notification_action", "0"));
|
||||
int statusIcon = playing ? R.drawable.status_icon : R.drawable.status_icon_paused;
|
||||
|
@ -448,7 +448,7 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
|
||||
menu.add(0, MENU_DELETE, 0, R.string.delete);
|
||||
|
||||
playlistMenu.add(type, MENU_NEW_PLAYLIST, id, R.string.new_playlist);
|
||||
Playlist[] playlists = Playlist.getPlaylists();
|
||||
Playlist[] playlists = Playlist.getPlaylists(this);
|
||||
if (playlists != null) {
|
||||
for (int i = 0; i != playlists.length; ++i)
|
||||
playlistMenu.add(type, (int)playlists[i].id + 100, id, playlists[i].name);
|
||||
@ -470,8 +470,8 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
|
||||
*/
|
||||
private void addToPlaylist(long playlistId, int type, long mediaId, CharSequence title)
|
||||
{
|
||||
long[] ids = MediaUtils.getAllSongIdsWith(type, mediaId);
|
||||
Playlist.addToPlaylist(playlistId, ids);
|
||||
long[] ids = MediaUtils.getAllSongIdsWith(this, type, mediaId);
|
||||
Playlist.addToPlaylist(this, playlistId, ids);
|
||||
|
||||
String message = getResources().getQuantityString(R.plurals.added_to_playlist, ids.length, ids.length, title);
|
||||
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
|
||||
@ -489,7 +489,7 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
|
||||
private void delete(int type, long id, String title)
|
||||
{
|
||||
if (type == MediaUtils.TYPE_PLAYLIST) {
|
||||
Playlist.deletePlaylist(id);
|
||||
Playlist.deletePlaylist(this, id);
|
||||
String message = getResources().getString(R.string.playlist_deleted, title);
|
||||
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
@ -635,7 +635,7 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
|
||||
NewPlaylistDialog dialog = (NewPlaylistDialog)message.obj;
|
||||
if (dialog.isAccepted()) {
|
||||
String name = dialog.getText();
|
||||
long playlistId = Playlist.createPlaylist(name);
|
||||
long playlistId = Playlist.createPlaylist(this, name);
|
||||
addToPlaylist(playlistId, message.arg1, message.arg2, name);
|
||||
}
|
||||
break;
|
||||
@ -646,7 +646,7 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
|
||||
case MSG_RENAME_PLAYLIST: {
|
||||
NewPlaylistDialog dialog = (NewPlaylistDialog)message.obj;
|
||||
if (dialog.isAccepted())
|
||||
Playlist.renamePlaylist(message.arg2, dialog.getText());
|
||||
Playlist.renamePlaylist(this, message.arg2, dialog.getText());
|
||||
}
|
||||
default:
|
||||
return super.handleMessage(message);
|
||||
@ -700,11 +700,11 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
|
||||
mStatusText.setText(text);
|
||||
|
||||
if (mCoverSize == -1) {
|
||||
DisplayMetrics metrics = ContextApplication.getContext().getResources().getDisplayMetrics();
|
||||
DisplayMetrics metrics = getResources().getDisplayMetrics();
|
||||
mCoverSize = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 64, metrics);
|
||||
}
|
||||
|
||||
Bitmap cover = CoverBitmap.createScaledBitmap(song, mCoverSize, mCoverSize);
|
||||
Bitmap cover = CoverBitmap.createScaledBitmap(this, song, mCoverSize, mCoverSize);
|
||||
mCover.setImageBitmap(cover);
|
||||
mCover.setVisibility(cover == null ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
|
@ -92,6 +92,8 @@ public final class SongTimeline {
|
||||
*/
|
||||
private static final long STATE_FILE_MAGIC = 0xf89daa2fac33L;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
/**
|
||||
* All the songs currently contained in the timeline. Each Song object
|
||||
* should be unique, even if it refers to the same media.
|
||||
@ -142,6 +144,11 @@ public final class SongTimeline {
|
||||
*/
|
||||
private Callback mCallback;
|
||||
|
||||
public SongTimeline(Context context)
|
||||
{
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the ids of songs.
|
||||
*/
|
||||
@ -172,16 +179,15 @@ public final class SongTimeline {
|
||||
* Initializes the timeline with the state stored in the state file created
|
||||
* by a call to save state.
|
||||
*
|
||||
* @param context The Context to open the state file with
|
||||
* @return The optional extra data, or -1 if loading failed
|
||||
*/
|
||||
public int loadState(Context context)
|
||||
public int loadState()
|
||||
{
|
||||
int extra = -1;
|
||||
|
||||
try {
|
||||
synchronized (this) {
|
||||
DataInputStream in = new DataInputStream(context.openFileInput(STATE_FILE));
|
||||
DataInputStream in = new DataInputStream(mContext.openFileInput(STATE_FILE));
|
||||
if (in.readLong() == STATE_FILE_MAGIC) {
|
||||
int n = in.readInt();
|
||||
if (n > 0) {
|
||||
@ -207,7 +213,7 @@ public final class SongTimeline {
|
||||
// return its results in.
|
||||
Collections.sort(songs, new IdComparator());
|
||||
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
ContentResolver resolver = mContext.getContentResolver();
|
||||
Uri media = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
||||
|
||||
Cursor cursor = resolver.query(media, Song.FILLED_PROJECTION, selection.toString(), null, "_id");
|
||||
@ -263,13 +269,12 @@ public final class SongTimeline {
|
||||
* This can be passed to the appropriate constructor to initialize the
|
||||
* timeline with this state.
|
||||
*
|
||||
* @param context The Context to open the state file with
|
||||
* @param extra Optional extra data to be included. Should not be -1.
|
||||
*/
|
||||
public void saveState(Context context, int extra)
|
||||
public void saveState(int extra)
|
||||
{
|
||||
try {
|
||||
DataOutputStream out = new DataOutputStream(context.openFileOutput(STATE_FILE, 0));
|
||||
DataOutputStream out = new DataOutputStream(mContext.openFileOutput(STATE_FILE, 0));
|
||||
out.writeLong(STATE_FILE_MAGIC);
|
||||
|
||||
synchronized (this) {
|
||||
@ -360,7 +365,7 @@ public final class SongTimeline {
|
||||
private Song shuffleAll()
|
||||
{
|
||||
ArrayList<Song> songs = new ArrayList<Song>(mSongs);
|
||||
Collections.shuffle(songs, ContextApplication.getRandom());
|
||||
Collections.shuffle(songs, MediaUtils.getRandom());
|
||||
mShuffledSongs = songs;
|
||||
return songs.get(0);
|
||||
}
|
||||
@ -401,7 +406,7 @@ public final class SongTimeline {
|
||||
song = timeline.get(0);
|
||||
break;
|
||||
case FINISH_RANDOM:
|
||||
song = Song.randomSong();
|
||||
song = Song.randomSong(mContext);
|
||||
timeline.add(song);
|
||||
break;
|
||||
default:
|
||||
@ -473,9 +478,9 @@ public final class SongTimeline {
|
||||
{
|
||||
Cursor cursor;
|
||||
if (type == MediaUtils.TYPE_PLAYLIST)
|
||||
cursor = MediaUtils.query(type, id, Song.FILLED_PLAYLIST_PROJECTION, selection);
|
||||
cursor = MediaUtils.query(mContext, type, id, Song.FILLED_PLAYLIST_PROJECTION, selection);
|
||||
else
|
||||
cursor = MediaUtils.query(type, id, Song.FILLED_PROJECTION, selection);
|
||||
cursor = MediaUtils.query(mContext, type, id, Song.FILLED_PROJECTION, selection);
|
||||
if (cursor == null)
|
||||
return 0;
|
||||
int count = cursor.getCount();
|
||||
@ -516,7 +521,7 @@ public final class SongTimeline {
|
||||
}
|
||||
|
||||
if (mShuffle)
|
||||
Collections.shuffle(timeline.subList(start, timeline.size()), ContextApplication.getRandom());
|
||||
Collections.shuffle(timeline.subList(start, timeline.size()), MediaUtils.getRandom());
|
||||
|
||||
broadcastChangedSongs();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user