import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.RemoteException;
import android.provider.MediaStore;
import android.provider.Settings;
+import android.text.TextUtils;
import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
+import android.view.ViewGroup;
import android.view.Window;
+import android.widget.TabWidget;
import android.widget.TextView;
import android.widget.Toast;
}
}
- public static int getCurrentAlbumId() {
+ public static long getCurrentAlbumId() {
if (sService != null) {
try {
return sService.getAlbumId();
return -1;
}
- public static int getCurrentArtistId() {
+ public static long getCurrentArtistId() {
if (MusicUtils.sService != null) {
try {
return sService.getArtistId();
return -1;
}
- public static int getCurrentAudioId() {
+ public static long getCurrentAudioId() {
if (MusicUtils.sService != null) {
try {
return sService.getAudioId();
return mode;
}
+ public static void togglePartyShuffle() {
+ if (sService != null) {
+ int shuffle = getCurrentShuffleMode();
+ try {
+ if (shuffle == MediaPlaybackService.SHUFFLE_AUTO) {
+ sService.setShuffleMode(MediaPlaybackService.SHUFFLE_NONE);
+ } else {
+ sService.setShuffleMode(MediaPlaybackService.SHUFFLE_AUTO);
+ }
+ } catch (RemoteException ex) {
+ }
+ }
+ }
+
+ public static void setPartyShuffleMenuIcon(Menu menu) {
+ MenuItem item = menu.findItem(Defs.PARTY_SHUFFLE);
+ if (item != null) {
+ int shuffle = MusicUtils.getCurrentShuffleMode();
+ if (shuffle == MediaPlaybackService.SHUFFLE_AUTO) {
+ item.setIcon(R.drawable.ic_menu_party_shuffle);
+ item.setTitle(R.string.party_shuffle_off);
+ } else {
+ item.setIcon(R.drawable.ic_menu_party_shuffle);
+ item.setTitle(R.string.party_shuffle);
+ }
+ }
+ }
+
/*
* Returns true if a file is currently opened for playback (regardless
* of whether it's playing or paused).
return false;
}
- private final static int [] sEmptyList = new int[0];
+ private final static long [] sEmptyList = new long[0];
- public static int [] getSongListForCursor(Cursor cursor) {
+ public static long [] getSongListForCursor(Cursor cursor) {
if (cursor == null) {
return sEmptyList;
}
int len = cursor.getCount();
- int [] list = new int[len];
+ long [] list = new long[len];
cursor.moveToFirst();
int colidx = -1;
try {
colidx = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID);
}
for (int i = 0; i < len; i++) {
- list[i] = cursor.getInt(colidx);
+ list[i] = cursor.getLong(colidx);
cursor.moveToNext();
}
return list;
}
- public static int [] getSongListForArtist(Context context, int id) {
+ public static long [] getSongListForArtist(Context context, long id) {
final String[] ccols = new String[] { MediaStore.Audio.Media._ID };
String where = MediaStore.Audio.Media.ARTIST_ID + "=" + id + " AND " +
MediaStore.Audio.Media.IS_MUSIC + "=1";
MediaStore.Audio.Media.ALBUM_KEY + "," + MediaStore.Audio.Media.TRACK);
if (cursor != null) {
- int [] list = getSongListForCursor(cursor);
+ long [] list = getSongListForCursor(cursor);
cursor.close();
return list;
}
return sEmptyList;
}
- public static int [] getSongListForAlbum(Context context, int id) {
+ public static long [] getSongListForAlbum(Context context, long id) {
final String[] ccols = new String[] { MediaStore.Audio.Media._ID };
String where = MediaStore.Audio.Media.ALBUM_ID + "=" + id + " AND " +
MediaStore.Audio.Media.IS_MUSIC + "=1";
ccols, where, null, MediaStore.Audio.Media.TRACK);
if (cursor != null) {
- int [] list = getSongListForCursor(cursor);
+ long [] list = getSongListForCursor(cursor);
cursor.close();
return list;
}
return sEmptyList;
}
- public static int [] getSongListForPlaylist(Context context, long plid) {
+ public static long [] getSongListForPlaylist(Context context, long plid) {
final String[] ccols = new String[] { MediaStore.Audio.Playlists.Members.AUDIO_ID };
Cursor cursor = query(context, MediaStore.Audio.Playlists.Members.getContentUri("external", plid),
ccols, null, null, MediaStore.Audio.Playlists.Members.DEFAULT_SORT_ORDER);
if (cursor != null) {
- int [] list = getSongListForCursor(cursor);
+ long [] list = getSongListForCursor(cursor);
cursor.close();
return list;
}
}
public static void playPlaylist(Context context, long plid) {
- int [] list = getSongListForPlaylist(context, plid);
+ long [] list = getSongListForPlaylist(context, plid);
if (list != null) {
playAll(context, list, -1, false);
}
}
- public static int [] getAllSongs(Context context) {
+ public static long [] getAllSongs(Context context) {
Cursor c = query(context, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[] {MediaStore.Audio.Media._ID}, MediaStore.Audio.Media.IS_MUSIC + "=1",
null, null);
return null;
}
int len = c.getCount();
- int[] list = new int[len];
+ long [] list = new long[len];
for (int i = 0; i < len; i++) {
c.moveToNext();
- list[i] = c.getInt(0);
+ list[i] = c.getLong(0);
}
return list;
cur.moveToFirst();
while (! cur.isAfterLast()) {
Intent intent = new Intent();
- intent.putExtra("playlist", cur.getInt(0));
+ intent.putExtra("playlist", cur.getLong(0));
// if (cur.getInt(0) == mLastPlaylistSelected) {
// sub.add(0, MusicBaseActivity.PLAYLIST_SELECTED, cur.getString(1)).setIntent(intent);
// } else {
return;
}
- public static void deleteTracks(Context context, int [] list) {
+ public static void deleteTracks(Context context, long [] list) {
String [] cols = new String [] { MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.ALBUM_ID };
c.moveToFirst();
while (! c.isAfterLast()) {
// remove from current playlist
- int id = c.getInt(0);
+ long id = c.getLong(0);
sService.removeTrack(id);
// remove from album art cache
- int artIndex = c.getInt(2);
+ long artIndex = c.getLong(2);
synchronized(sArtCache) {
sArtCache.remove(artIndex);
}
context.getContentResolver().notifyChange(Uri.parse("content://media"), null);
}
- public static void addToCurrentPlaylist(Context context, int [] list) {
+ public static void addToCurrentPlaylist(Context context, long [] list) {
if (sService == null) {
return;
}
}
}
- public static void addToPlaylist(Context context, int [] ids, long playlistid) {
+ public static void addToPlaylist(Context context, long [] ids, long playlistid) {
if (ids == null) {
// this shouldn't happen (the menuitems shouldn't be visible
// unless the selected item represents something playable
}
public static Cursor query(Context context, Uri uri, String[] projection,
- String selection, String[] selectionArgs, String sortOrder) {
+ String selection, String[] selectionArgs, String sortOrder, int limit) {
try {
ContentResolver resolver = context.getContentResolver();
if (resolver == null) {
return null;
}
+ if (limit > 0) {
+ uri = uri.buildUpon().appendQueryParameter("limit", "" + limit).build();
+ }
return resolver.query(uri, projection, selection, selectionArgs, sortOrder);
} catch (UnsupportedOperationException ex) {
return null;
}
}
+ public static Cursor query(Context context, Uri uri, String[] projection,
+ String selection, String[] selectionArgs, String sortOrder) {
+ return query(context, uri, projection, selection, selectionArgs, sortOrder, 0);
+ }
public static boolean isMediaScannerScanning(Context context) {
boolean result = false;
}
}
+ private static String mLastSdStatus;
+
public static void displayDatabaseError(Activity a) {
+ if (a.isFinishing()) {
+ // When switching tabs really fast, we can end up with a null
+ // cursor (not sure why), which will bring us here.
+ // Don't bother showing an error message in that case.
+ return;
+ }
+
String status = Environment.getExternalStorageState();
int title = R.string.sdcard_error_title;
int message = R.string.sdcard_error_message;
Intent intent = new Intent();
intent.setClass(a, ScanningProgress.class);
a.startActivityForResult(intent, Defs.SCAN_DONE);
- } else {
+ } else if (!TextUtils.equals(mLastSdStatus, status)) {
+ mLastSdStatus = status;
Log.d(TAG, "sd card: " + status);
}
if (v != null) {
v.setVisibility(View.GONE);
}
+ v = a.findViewById(R.id.buttonbar);
+ if (v != null) {
+ v.setVisibility(View.GONE);
+ }
TextView tv = (TextView) a.findViewById(R.id.sd_message);
tv.setText(message);
}
private static final Object[] sTimeArgs = new Object[5];
public static String makeTimeString(Context context, long secs) {
- String durationformat = context.getString(R.string.durationformat);
+ String durationformat = context.getString(
+ secs < 3600 ? R.string.durationformatshort : R.string.durationformatlong);
/* Provide multiple arguments so the format can be changed easily
* by modifying the xml.
playAll(context, cursor, position, false);
}
- public static void playAll(Context context, int [] list, int position) {
+ public static void playAll(Context context, long [] list, int position) {
playAll(context, list, position, false);
}
private static void playAll(Context context, Cursor cursor, int position, boolean force_shuffle) {
- int [] list = getSongListForCursor(cursor);
+ long [] list = getSongListForCursor(cursor);
playAll(context, list, position, force_shuffle);
}
- private static void playAll(Context context, int [] list, int position, boolean force_shuffle) {
+ private static void playAll(Context context, long [] list, int position, boolean force_shuffle) {
if (list.length == 0 || sService == null) {
Log.d("MusicUtils", "attempt to play empty song list");
// Don't try to play empty playlists. Nothing good will come of it.
if (force_shuffle) {
sService.setShuffleMode(MediaPlaybackService.SHUFFLE_NORMAL);
}
- int curid = sService.getAudioId();
+ long curid = sService.getAudioId();
int curpos = sService.getQueuePosition();
if (position != -1 && curpos == position && curid == list[position]) {
// The selected file is the file that's currently playing;
// figure out if we need to restart with a new playlist,
// or just launch the playback activity.
- int [] playlist = sService.getQueue();
+ long [] playlist = sService.getQueue();
if (Arrays.equals(list, playlist)) {
// we don't need to set a new list, but we should resume playback if needed
sService.play();
sService.play();
} catch (RemoteException ex) {
} finally {
- Intent intent = new Intent("com.android.music.PLAYBACK_VIEWER")
+ Intent intent = new Intent(context, MediaPlaybackActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
}
private static final BitmapFactory.Options sBitmapOptionsCache = new BitmapFactory.Options();
private static final BitmapFactory.Options sBitmapOptions = new BitmapFactory.Options();
private static final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
- private static final HashMap<Integer, Drawable> sArtCache = new HashMap<Integer, Drawable>();
+ private static final HashMap<Long, Drawable> sArtCache = new HashMap<Long, Drawable>();
private static int sArtCacheId = -1;
static {
}
}
- public static Drawable getCachedArtwork(Context context, int artIndex, BitmapDrawable defaultArtwork) {
+ public static Drawable getCachedArtwork(Context context, long artIndex, BitmapDrawable defaultArtwork) {
Drawable d = null;
synchronized(sArtCache) {
d = sArtCache.get(artIndex);
// Get album art for specified album. This method will not try to
// fall back to getting artwork directly from the file, nor will
// it attempt to repair the database.
- private static Bitmap getArtworkQuick(Context context, int album_id, int w, int h) {
+ private static Bitmap getArtworkQuick(Context context, long album_id, int w, int h) {
// NOTE: There is in fact a 1 pixel border on the right side in the ImageView
// used to display this drawable. Take it into account now, so we don't have to
// scale later.
}
return null;
}
-
+
/** Get album art for specified album. You should not pass in the album id
* for the "unknown" album here (use -1 instead)
+ * This method always returns the default album art icon when no album art is found.
*/
- public static Bitmap getArtwork(Context context, int song_id, int album_id) {
+ public static Bitmap getArtwork(Context context, long song_id, long album_id) {
+ return getArtwork(context, song_id, 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, long song_id, long album_id,
+ boolean allowdefault) {
if (album_id < 0) {
// This is something that is not in the database, so get the album art directly
return bm;
}
}
- return getDefaultArtwork(context);
+ if (allowdefault) {
+ return getDefaultArtwork(context);
+ }
+ return null;
}
ContentResolver res = context.getContentResolver();
if (bm != null) {
if (bm.getConfig() == null) {
bm = bm.copy(Bitmap.Config.RGB_565, false);
- if (bm == null) {
+ if (bm == null && allowdefault) {
return getDefaultArtwork(context);
}
}
- } else {
+ } else if (allowdefault) {
bm = getDefaultArtwork(context);
}
return bm;
// get album art for specified file
private static final String sExternalMediaUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI.toString();
- private static Bitmap getArtworkFromFile(Context context, int songid, int albumid) {
+ private static Bitmap getArtworkFromFile(Context context, long songid, long albumid) {
Bitmap bm = null;
byte [] art = null;
String path = null;
}
}
}
+
+ static int sActiveTabIndex = -1;
+
+ static boolean updateButtonBar(Activity a, int highlight) {
+ final TabWidget ll = (TabWidget) a.findViewById(R.id.buttonbar);
+ boolean withtabs = false;
+ Intent intent = a.getIntent();
+ if (intent != null) {
+ withtabs = intent.getBooleanExtra("withtabs", false);
+ }
+
+ if (highlight == 0 || !withtabs) {
+ ll.setVisibility(View.GONE);
+ return withtabs;
+ } else if (withtabs) {
+ ll.setVisibility(View.VISIBLE);
+ }
+ for (int i = ll.getChildCount() - 1; i >= 0; i--) {
+
+ View v = ll.getChildAt(i);
+ boolean isActive = (v.getId() == highlight);
+ if (isActive) {
+ ll.setCurrentTab(i);
+ sActiveTabIndex = i;
+ }
+ v.setTag(i);
+ v.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+
+ public void onFocusChange(View v, boolean hasFocus) {
+ if (hasFocus) {
+ for (int i = 0; i < ll.getTabCount(); i++) {
+ if (ll.getChildTabViewAt(i) == v) {
+ ll.setCurrentTab(i);
+ processTabClick((Activity)ll.getContext(), v, ll.getChildAt(sActiveTabIndex).getId());
+ break;
+ }
+ }
+ }
+ }});
+
+ v.setOnClickListener(new View.OnClickListener() {
+
+ public void onClick(View v) {
+ processTabClick((Activity)ll.getContext(), v, ll.getChildAt(sActiveTabIndex).getId());
+ }});
+ }
+ return withtabs;
+ }
+
+ static void processTabClick(Activity a, View v, int current) {
+ int id = v.getId();
+ if (id == current) {
+ return;
+ }
+
+ final TabWidget ll = (TabWidget) a.findViewById(R.id.buttonbar);
+ ll.setCurrentTab((Integer) v.getTag());
+
+ activateTab(a, id);
+ if (id != R.id.nowplayingtab) {
+ setIntPref(a, "activetab", id);
+ }
+ }
+
+ static void activateTab(Activity a, int id) {
+ Intent intent = new Intent(Intent.ACTION_PICK);
+ switch (id) {
+ case R.id.artisttab:
+ intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/artistalbum");
+ break;
+ case R.id.albumtab:
+ intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/album");
+ break;
+ case R.id.songtab:
+ intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/track");
+ break;
+ case R.id.playlisttab:
+ intent.setDataAndType(Uri.EMPTY, MediaStore.Audio.Playlists.CONTENT_TYPE);
+ break;
+ case R.id.nowplayingtab:
+ intent = new Intent(a, MediaPlaybackActivity.class);
+ a.startActivity(intent);
+ // fall through and return
+ default:
+ return;
+ }
+ intent.putExtra("withtabs", true);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ a.startActivity(intent);
+ a.finish();
+ a.overridePendingTransition(0, 0);
+ }
+
+ static void updateNowPlaying(Activity a) {
+ View nowPlayingView = a.findViewById(R.id.nowplaying);
+ if (nowPlayingView == null) {
+ return;
+ }
+ try {
+ boolean withtabs = false;
+ Intent intent = a.getIntent();
+ if (intent != null) {
+ withtabs = intent.getBooleanExtra("withtabs", false);
+ }
+ if (true && MusicUtils.sService != null && MusicUtils.sService.getAudioId() != -1) {
+ TextView title = (TextView) nowPlayingView.findViewById(R.id.title);
+ TextView artist = (TextView) nowPlayingView.findViewById(R.id.artist);
+ title.setText(MusicUtils.sService.getTrackName());
+ String artistName = MusicUtils.sService.getArtistName();
+ if (MediaStore.UNKNOWN_STRING.equals(artistName)) {
+ artistName = a.getString(R.string.unknown_artist_name);
+ }
+ artist.setText(artistName);
+ //mNowPlayingView.setOnFocusChangeListener(mFocuser);
+ //mNowPlayingView.setOnClickListener(this);
+ nowPlayingView.setVisibility(View.VISIBLE);
+ nowPlayingView.setOnClickListener(new View.OnClickListener() {
+
+ public void onClick(View v) {
+ Context c = v.getContext();
+ c.startActivity(new Intent(c, MediaPlaybackActivity.class));
+ }});
+ return;
+ }
+ } catch (RemoteException ex) {
+ }
+ nowPlayingView.setVisibility(View.GONE);
+ }
+
+ static void setBackground(View v, Bitmap bm) {
+
+ if (bm == null) {
+ v.setBackgroundResource(0);
+ return;
+ }
+
+ int vwidth = v.getWidth();
+ int vheight = v.getHeight();
+ int bwidth = bm.getWidth();
+ int bheight = bm.getHeight();
+ float scalex = (float) vwidth / bwidth;
+ float scaley = (float) vheight / bheight;
+ float scale = Math.max(scalex, scaley) * 1.3f;
+
+ Bitmap.Config config = Bitmap.Config.ARGB_8888;
+ Bitmap bg = Bitmap.createBitmap(vwidth, vheight, config);
+ Canvas c = new Canvas(bg);
+ Paint paint = new Paint();
+ paint.setAntiAlias(true);
+ paint.setFilterBitmap(true);
+ ColorMatrix greymatrix = new ColorMatrix();
+ greymatrix.setSaturation(0);
+ ColorMatrix darkmatrix = new ColorMatrix();
+ darkmatrix.setScale(.3f, .3f, .3f, 1.0f);
+ greymatrix.postConcat(darkmatrix);
+ ColorFilter filter = new ColorMatrixColorFilter(greymatrix);
+ paint.setColorFilter(filter);
+ Matrix matrix = new Matrix();
+ matrix.setTranslate(-bwidth/2, -bheight/2); // move bitmap center to origin
+ matrix.postRotate(10);
+ matrix.postScale(scale, scale);
+ matrix.postTranslate(vwidth/2, vheight/2); // Move bitmap center to view center
+ c.drawBitmap(bm, matrix, paint);
+ v.setBackgroundDrawable(new BitmapDrawable(bg));
+ }
+
+ static int getCardId(Context context) {
+ ContentResolver res = context.getContentResolver();
+ Cursor c = res.query(Uri.parse("content://media/external/fs_id"), null, null, null, null);
+ int id = -1;
+ if (c != null) {
+ c.moveToFirst();
+ id = c.getInt(0);
+ c.close();
+ }
+ return id;
+ }
}