2 package com.andrew.apollo.utils;
\r
4 import java.util.Arrays;
\r
5 import java.util.Formatter;
\r
6 import java.util.HashMap;
\r
7 import java.util.List;
\r
8 import java.util.Locale;
\r
9 import java.util.Map;
\r
11 import android.app.Activity;
\r
12 import android.app.SearchManager;
\r
13 import android.content.ContentResolver;
\r
14 import android.content.ContentUris;
\r
15 import android.content.ContentValues;
\r
16 import android.content.Context;
\r
17 import android.content.ContextWrapper;
\r
18 import android.content.Intent;
\r
19 import android.content.ServiceConnection;
\r
20 import android.content.SharedPreferences;
\r
21 import android.content.res.Resources;
\r
22 import android.database.Cursor;
\r
23 import android.net.Uri;
\r
24 import android.os.Environment;
\r
25 import android.os.RemoteException;
\r
26 import android.provider.BaseColumns;
\r
27 import android.provider.MediaStore;
\r
28 import android.provider.MediaStore.Audio;
\r
29 import android.provider.MediaStore.Audio.AlbumColumns;
\r
30 import android.provider.MediaStore.Audio.ArtistColumns;
\r
31 import android.provider.MediaStore.Audio.AudioColumns;
\r
32 import android.provider.MediaStore.Audio.Genres;
\r
33 import android.provider.MediaStore.Audio.GenresColumns;
\r
34 import android.provider.MediaStore.Audio.Playlists;
\r
35 import android.provider.MediaStore.Audio.PlaylistsColumns;
\r
36 import android.provider.MediaStore.MediaColumns;
\r
37 import android.provider.Settings;
\r
38 import android.support.v4.app.FragmentActivity;
\r
39 import android.text.TextUtils;
\r
40 import android.view.Window;
\r
41 import android.widget.ImageButton;
\r
42 import android.widget.Toast;
\r
44 import com.andrew.apollo.Constants;
\r
45 import com.andrew.apollo.IApolloService;
\r
46 import com.andrew.apollo.R;
\r
47 import com.andrew.apollo.activities.ScanningProgress;
\r
48 import com.andrew.apollo.service.ApolloService;
\r
49 import com.andrew.apollo.service.ServiceBinder;
\r
50 import com.andrew.apollo.service.ServiceToken;
\r
53 * Various methods used to help with specific music statements
\r
55 public class MusicUtils implements Constants {
\r
57 // Used to make number of albums/songs/time strings
\r
58 private final static StringBuilder sFormatBuilder = new StringBuilder();
\r
60 private final static Formatter sFormatter = new Formatter(sFormatBuilder, Locale.getDefault());
\r
62 public static IApolloService mService = null;
\r
64 private static HashMap<Context, ServiceBinder> sConnectionMap = new HashMap<Context, ServiceBinder>();
\r
66 private final static long[] sEmptyList = new long[0];
\r
68 private static final Object[] sTimeArgs = new Object[5];
\r
70 private static ContentValues[] sContentValuesCache = null;
\r
72 private static String mLastSdStatus;
\r
74 private final static int SCAN_DONE = 0;
\r
80 public static ServiceToken bindToService(FragmentActivity context) {
\r
81 return bindToService(context, null);
\r
89 public static ServiceToken bindToService(Context context, ServiceConnection callback) {
\r
90 Activity realActivity = ((Activity)context).getParent();
\r
91 if (realActivity == null) {
\r
92 realActivity = (Activity)context;
\r
94 ContextWrapper cw = new ContextWrapper(realActivity);
\r
95 cw.startService(new Intent(cw, ApolloService.class));
\r
96 ServiceBinder sb = new ServiceBinder(callback);
\r
97 if (cw.bindService((new Intent()).setClass(cw, ApolloService.class), sb, 0)) {
\r
98 sConnectionMap.put(cw, sb);
\r
99 return new ServiceToken(cw);
\r
107 public static void unbindFromService(ServiceToken token) {
\r
108 if (token == null) {
\r
111 ContextWrapper cw = token.mWrappedContext;
\r
112 ServiceBinder sb = sConnectionMap.remove(cw);
\r
116 cw.unbindService(sb);
\r
117 if (sConnectionMap.isEmpty()) {
\r
127 * @return a string based on the number of albums for an artist or songs for
\r
130 public static String makeAlbumsLabel(Context mContext, int numalbums, int numsongs,
\r
131 boolean isUnknown) {
\r
133 StringBuilder songs_albums = new StringBuilder();
\r
135 Resources r = mContext.getResources();
\r
137 String f = r.getQuantityText(R.plurals.Nsongs, numsongs).toString();
\r
138 sFormatBuilder.setLength(0);
\r
139 sFormatter.format(f, Integer.valueOf(numsongs));
\r
140 songs_albums.append(sFormatBuilder);
\r
142 String f = r.getQuantityText(R.plurals.Nalbums, numalbums).toString();
\r
143 sFormatBuilder.setLength(0);
\r
144 sFormatter.format(f, Integer.valueOf(numalbums));
\r
145 songs_albums.append(sFormatBuilder);
\r
146 songs_albums.append("\n");
\r
148 return songs_albums.toString();
\r
155 public static int getCardId(Context mContext) {
\r
157 ContentResolver res = mContext.getContentResolver();
\r
158 Cursor c = res.query(Uri.parse("content://media/external/fs_id"), null, null, null, null);
\r
171 * @param projection
\r
173 * @param selectionArgs
\r
178 public static Cursor query(Context context, Uri uri, String[] projection, String selection,
\r
179 String[] selectionArgs, String sortOrder, int limit) {
\r
181 ContentResolver resolver = context.getContentResolver();
\r
182 if (resolver == null) {
\r
186 uri = uri.buildUpon().appendQueryParameter("limit", "" + limit).build();
\r
188 return resolver.query(uri, projection, selection, selectionArgs, sortOrder);
\r
189 } catch (UnsupportedOperationException ex) {
\r
197 * @param projection
\r
199 * @param selectionArgs
\r
203 public static Cursor query(Context context, Uri uri, String[] projection, String selection,
\r
204 String[] selectionArgs, String sortOrder) {
\r
205 return query(context, uri, projection, selection, selectionArgs, sortOrder, 0);
\r
212 public static void shuffleAll(Context context, Cursor cursor) {
\r
213 playAll(context, cursor, 0, true);
\r
220 public static void playAll(Context context, Cursor cursor) {
\r
221 playAll(context, cursor, 0, false);
\r
229 public static void playAll(Context context, Cursor cursor, int position) {
\r
230 playAll(context, cursor, position, false);
\r
238 public static void playAll(Context context, long[] list, int position) {
\r
239 playAll(context, list, position, false);
\r
246 * @param force_shuffle
\r
248 private static void playAll(Context context, Cursor cursor, int position, boolean force_shuffle) {
\r
250 long[] list = getSongListForCursor(cursor);
\r
251 playAll(context, list, position, force_shuffle);
\r
258 public static long[] getSongListForCursor(Cursor cursor) {
\r
259 if (cursor == null) {
\r
262 int len = cursor.getCount();
\r
263 long[] list = new long[len];
\r
264 cursor.moveToFirst();
\r
267 colidx = cursor.getColumnIndexOrThrow(Audio.Playlists.Members.AUDIO_ID);
\r
268 } catch (IllegalArgumentException ex) {
\r
269 colidx = cursor.getColumnIndexOrThrow(BaseColumns._ID);
\r
271 for (int i = 0; i < len; i++) {
\r
272 list[i] = cursor.getLong(colidx);
\r
273 cursor.moveToNext();
\r
282 * @param force_shuffle
\r
284 private static void playAll(Context context, long[] list, int position, boolean force_shuffle) {
\r
285 if (list.length == 0 || mService == null) {
\r
289 if (force_shuffle) {
\r
290 mService.setShuffleMode(ApolloService.SHUFFLE_NORMAL);
\r
292 long curid = mService.getAudioId();
\r
293 int curpos = mService.getQueuePosition();
\r
294 if (position != -1 && curpos == position && curid == list[position]) {
\r
295 // The selected file is the file that's currently playing;
\r
296 // figure out if we need to restart with a new playlist,
\r
297 // or just launch the playback activity.
\r
298 long[] playlist = mService.getQueue();
\r
299 if (Arrays.equals(list, playlist)) {
\r
300 // we don't need to set a new list, but we should resume
\r
301 // playback if needed
\r
306 if (position < 0) {
\r
309 mService.open(list, force_shuffle ? -1 : position);
\r
311 } catch (RemoteException ex) {
\r
312 ex.printStackTrace();
\r
319 public static long[] getQueue() {
\r
321 if (mService == null)
\r
325 return mService.getQueue();
\r
326 } catch (RemoteException e) {
\r
327 e.printStackTrace();
\r
336 * @return number of weeks used to create the Recent tab
\r
338 public static int getIntPref(Context context, String name, int def) {
\r
339 SharedPreferences prefs = context.getSharedPreferences(context.getPackageName(),
\r
340 Context.MODE_PRIVATE);
\r
341 return prefs.getInt(name, def);
\r
349 public static long[] getSongListForArtist(Context context, long id) {
\r
350 final String[] projection = new String[] {
\r
353 String selection = AudioColumns.ARTIST_ID + "=" + id + " AND " + AudioColumns.IS_MUSIC
\r
355 String sortOrder = AudioColumns.ALBUM_KEY + "," + AudioColumns.TRACK;
\r
356 Uri uri = Audio.Media.EXTERNAL_CONTENT_URI;
\r
357 Cursor cursor = query(context, uri, projection, selection, null, sortOrder);
\r
358 if (cursor != null) {
\r
359 long[] list = getSongListForCursor(cursor);
\r
371 public static long[] getSongListForAlbum(Context context, long id) {
\r
372 final String[] projection = new String[] {
\r
375 String selection = AudioColumns.ALBUM_ID + "=" + id + " AND " + AudioColumns.IS_MUSIC
\r
377 String sortOrder = AudioColumns.TRACK;
\r
378 Uri uri = Audio.Media.EXTERNAL_CONTENT_URI;
\r
379 Cursor cursor = query(context, uri, projection, selection, null, sortOrder);
\r
380 if (cursor != null) {
\r
381 long[] list = getSongListForCursor(cursor);
\r
393 public static long[] getSongListForGenre(Context context, long id) {
\r
394 String[] projection = new String[] {
\r
397 StringBuilder selection = new StringBuilder();
\r
398 selection.append(AudioColumns.IS_MUSIC + "=1");
\r
399 selection.append(" AND " + MediaColumns.TITLE + "!=''");
\r
400 Uri uri = Genres.Members.getContentUri(EXTERNAL, id);
\r
401 Cursor cursor = context.getContentResolver().query(uri, projection, selection.toString(),
\r
403 if (cursor != null) {
\r
404 long[] list = getSongListForCursor(cursor);
\r
416 public static long[] getSongListForPlaylist(Context context, long id) {
\r
417 final String[] projection = new String[] {
\r
418 Audio.Playlists.Members.AUDIO_ID
\r
420 String sortOrder = Playlists.Members.DEFAULT_SORT_ORDER;
\r
421 Uri uri = Playlists.Members.getContentUri(EXTERNAL, id);
\r
422 Cursor cursor = query(context, uri, projection, null, null, sortOrder);
\r
423 if (cursor != null) {
\r
424 long[] list = getSongListForCursor(cursor);
\r
436 public static long createPlaylist(Context context, String name) {
\r
438 if (name != null && name.length() > 0) {
\r
439 ContentResolver resolver = context.getContentResolver();
\r
440 String[] cols = new String[] {
\r
441 PlaylistsColumns.NAME
\r
443 String whereclause = PlaylistsColumns.NAME + " = '" + name + "'";
\r
444 Cursor cur = resolver.query(Audio.Playlists.EXTERNAL_CONTENT_URI, cols, whereclause,
\r
446 if (cur.getCount() <= 0) {
\r
447 ContentValues values = new ContentValues(1);
\r
448 values.put(PlaylistsColumns.NAME, name);
\r
449 Uri uri = resolver.insert(Audio.Playlists.EXTERNAL_CONTENT_URI, values);
\r
450 return Long.parseLong(uri.getLastPathSegment());
\r
461 public static long getFavoritesId(Context context) {
\r
462 long favorites_id = -1;
\r
463 String favorites_where = PlaylistsColumns.NAME + "='" + "Favorites" + "'";
\r
464 String[] favorites_cols = new String[] {
\r
467 Uri favorites_uri = Audio.Playlists.EXTERNAL_CONTENT_URI;
\r
468 Cursor cursor = query(context, favorites_uri, favorites_cols, favorites_where, null, null);
\r
469 if (cursor.getCount() <= 0) {
\r
470 favorites_id = createPlaylist(context, "Favorites");
\r
472 cursor.moveToFirst();
\r
473 favorites_id = cursor.getLong(0);
\r
476 return favorites_id;
\r
483 public static void setRingtone(Context context, long id) {
\r
484 ContentResolver resolver = context.getContentResolver();
\r
485 // Set the flag in the database to mark this as a ringtone
\r
486 Uri ringUri = ContentUris.withAppendedId(Audio.Media.EXTERNAL_CONTENT_URI, id);
\r
488 ContentValues values = new ContentValues(2);
\r
489 values.put(AudioColumns.IS_RINGTONE, "1");
\r
490 values.put(AudioColumns.IS_ALARM, "1");
\r
491 resolver.update(ringUri, values, null, null);
\r
492 } catch (UnsupportedOperationException ex) {
\r
493 // most likely the card just got unmounted
\r
497 String[] cols = new String[] {
\r
498 BaseColumns._ID, MediaColumns.DATA, MediaColumns.TITLE
\r
501 String where = BaseColumns._ID + "=" + id;
\r
502 Cursor cursor = query(context, Audio.Media.EXTERNAL_CONTENT_URI, cols, where, null, null);
\r
504 if (cursor != null && cursor.getCount() == 1) {
\r
505 // Set the system setting to make this the current ringtone
\r
506 cursor.moveToFirst();
\r
507 Settings.System.putString(resolver, Settings.System.RINGTONE, ringUri.toString());
\r
508 String message = context.getString(R.string.set_as_ringtone, cursor.getString(2));
\r
509 Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
\r
512 if (cursor != null) {
\r
522 public static void clearPlaylist(Context context, int plid) {
\r
523 Uri uri = Audio.Playlists.Members.getContentUri(EXTERNAL, plid);
\r
524 context.getContentResolver().delete(uri, null, null);
\r
531 * @param playlistid
\r
533 public static void addToPlaylist(Context context, long[] ids, long playlistid) {
\r
537 int size = ids.length;
\r
538 ContentResolver resolver = context.getContentResolver();
\r
539 // need to determine the number of items currently in the playlist,
\r
540 // so the play_order field can be maintained.
\r
541 String[] cols = new String[] {
\r
544 Uri uri = Audio.Playlists.Members.getContentUri(EXTERNAL, playlistid);
\r
545 Cursor cur = resolver.query(uri, cols, null, null, null);
\r
547 int base = cur.getInt(0);
\r
549 int numinserted = 0;
\r
550 for (int i = 0; i < size; i += 1000) {
\r
551 makeInsertItems(ids, i, 1000, base);
\r
552 numinserted += resolver.bulkInsert(uri, sContentValuesCache);
\r
554 String message = context.getResources().getQuantityString(
\r
555 R.plurals.NNNtrackstoplaylist, numinserted, numinserted);
\r
556 Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
\r
566 private static void makeInsertItems(long[] ids, int offset, int len, int base) {
\r
568 // adjust 'len' if would extend beyond the end of the source array
\r
569 if (offset + len > ids.length) {
\r
570 len = ids.length - offset;
\r
572 // allocate the ContentValues array, or reallocate if it is the wrong
\r
574 if (sContentValuesCache == null || sContentValuesCache.length != len) {
\r
575 sContentValuesCache = new ContentValues[len];
\r
577 // fill in the ContentValues array with the right values for this pass
\r
578 for (int i = 0; i < len; i++) {
\r
579 if (sContentValuesCache[i] == null) {
\r
580 sContentValuesCache[i] = new ContentValues();
\r
583 sContentValuesCache[i].put(Playlists.Members.PLAY_ORDER, base + offset + i);
\r
584 sContentValuesCache[i].put(Playlists.Members.AUDIO_ID, ids[offset + i]);
\r
591 public static void toggleFavorite() {
\r
593 if (mService == null)
\r
596 mService.toggleFavorite();
\r
597 } catch (RemoteException e) {
\r
598 e.printStackTrace();
\r
606 public static void addToFavorites(Context context, long id) {
\r
613 ContentResolver resolver = context.getContentResolver();
\r
615 String favorites_where = PlaylistsColumns.NAME + "='" + PLAYLIST_NAME_FAVORITES + "'";
\r
616 String[] favorites_cols = new String[] {
\r
619 Uri favorites_uri = Audio.Playlists.EXTERNAL_CONTENT_URI;
\r
620 Cursor cursor = resolver.query(favorites_uri, favorites_cols, favorites_where, null,
\r
622 if (cursor.getCount() <= 0) {
\r
623 favorites_id = createPlaylist(context, PLAYLIST_NAME_FAVORITES);
\r
625 cursor.moveToFirst();
\r
626 favorites_id = cursor.getLong(0);
\r
630 String[] cols = new String[] {
\r
631 Playlists.Members.AUDIO_ID
\r
633 Uri uri = Playlists.Members.getContentUri(EXTERNAL, favorites_id);
\r
634 Cursor cur = resolver.query(uri, cols, null, null, null);
\r
636 int base = cur.getCount();
\r
638 while (!cur.isAfterLast()) {
\r
639 if (cur.getLong(0) == id)
\r
645 ContentValues values = new ContentValues();
\r
646 values.put(Playlists.Members.AUDIO_ID, id);
\r
647 values.put(Playlists.Members.PLAY_ORDER, base + 1);
\r
648 resolver.insert(uri, values);
\r
657 public static boolean isFavorite(Context context, long id) {
\r
664 ContentResolver resolver = context.getContentResolver();
\r
666 String favorites_where = PlaylistsColumns.NAME + "='" + PLAYLIST_NAME_FAVORITES + "'";
\r
667 String[] favorites_cols = new String[] {
\r
670 Uri favorites_uri = Audio.Playlists.EXTERNAL_CONTENT_URI;
\r
671 Cursor cursor = resolver.query(favorites_uri, favorites_cols, favorites_where, null,
\r
673 if (cursor.getCount() <= 0) {
\r
674 favorites_id = createPlaylist(context, PLAYLIST_NAME_FAVORITES);
\r
676 cursor.moveToFirst();
\r
677 favorites_id = cursor.getLong(0);
\r
681 String[] cols = new String[] {
\r
682 Playlists.Members.AUDIO_ID
\r
684 Uri uri = Playlists.Members.getContentUri(EXTERNAL, favorites_id);
\r
685 Cursor cur = resolver.query(uri, cols, null, null, null);
\r
688 while (!cur.isAfterLast()) {
\r
689 if (cur.getLong(0) == id) {
\r
705 public static void removeFromFavorites(Context context, long id) {
\r
709 ContentResolver resolver = context.getContentResolver();
\r
710 String favorites_where = PlaylistsColumns.NAME + "='" + PLAYLIST_NAME_FAVORITES + "'";
\r
711 String[] favorites_cols = new String[] {
\r
714 Uri favorites_uri = Audio.Playlists.EXTERNAL_CONTENT_URI;
\r
715 Cursor cursor = resolver.query(favorites_uri, favorites_cols, favorites_where, null,
\r
717 if (cursor.getCount() <= 0) {
\r
718 favorites_id = createPlaylist(context, PLAYLIST_NAME_FAVORITES);
\r
720 cursor.moveToFirst();
\r
721 favorites_id = cursor.getLong(0);
\r
724 Uri uri = Playlists.Members.getContentUri(EXTERNAL, favorites_id);
\r
725 resolver.delete(uri, Playlists.Members.AUDIO_ID + "=" + id, null);
\r
731 * @param mImageButton
\r
734 public static void setFavoriteImage(ImageButton mImageButton) {
\r
736 if (MusicUtils.mService.isFavorite(MusicUtils.mService.getAudioId())) {
\r
737 mImageButton.setImageResource(R.drawable.apollo_holo_light_favorite_selected);
\r
739 mImageButton.setImageResource(R.drawable.apollo_holo_light_favorite_normal);
\r
741 ThemeUtils.setImageButton(mImageButton.getContext(), mImageButton,
\r
742 "apollo_favorite_normal");
\r
744 } catch (RemoteException e) {
\r
745 e.printStackTrace();
\r
754 public static void renamePlaylist(Context mContext, long id, String name) {
\r
756 if (name != null && name.length() > 0) {
\r
757 ContentResolver resolver = mContext.getContentResolver();
\r
758 ContentValues values = new ContentValues(1);
\r
759 values.put(PlaylistsColumns.NAME, name);
\r
760 resolver.update(Audio.Playlists.EXTERNAL_CONTENT_URI, values, BaseColumns._ID + "=?",
\r
764 Toast.makeText(mContext, "Playlist renamed", Toast.LENGTH_SHORT).show();
\r
772 public static void addToCurrentPlaylist(Context mContext, long[] list) {
\r
774 if (mService == null)
\r
777 mService.enqueue(list, ApolloService.LAST);
\r
778 String message = mContext.getResources().getQuantityString(
\r
779 R.plurals.NNNtrackstoplaylist, list.length, Integer.valueOf(list.length));
\r
780 Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
\r
781 } catch (RemoteException ex) {
\r
788 * @return time String
\r
790 public static String makeTimeString(Context context, long secs) {
\r
792 String durationformat = context.getString(secs < 3600 ? R.string.durationformatshort
\r
793 : R.string.durationformatlong);
\r
796 * Provide multiple arguments so the format can be changed easily by
\r
797 * modifying the xml.
\r
799 sFormatBuilder.setLength(0);
\r
801 final Object[] timeArgs = sTimeArgs;
\r
802 timeArgs[0] = secs / 3600;
\r
803 timeArgs[1] = secs / 60;
\r
804 timeArgs[2] = secs / 60 % 60;
\r
805 timeArgs[3] = secs;
\r
806 timeArgs[4] = secs % 60;
\r
808 return sFormatter.format(durationformat, timeArgs).toString();
\r
812 * @return current album ID
\r
814 public static long getCurrentAlbumId() {
\r
816 if (mService != null) {
\r
818 return mService.getAlbumId();
\r
819 } catch (RemoteException ex) {
\r
826 * @return current artist ID
\r
828 public static long getCurrentArtistId() {
\r
830 if (MusicUtils.mService != null) {
\r
832 return mService.getArtistId();
\r
833 } catch (RemoteException ex) {
\r
840 * @return current track ID
\r
842 public static long getCurrentAudioId() {
\r
844 if (MusicUtils.mService != null) {
\r
846 return mService.getAudioId();
\r
847 } catch (RemoteException ex) {
\r
854 * @return current artist name
\r
856 public static String getArtistName() {
\r
858 if (mService != null) {
\r
860 return mService.getArtistName();
\r
861 } catch (RemoteException ex) {
\r
868 * @return current album name
\r
870 public static String getAlbumName() {
\r
872 if (mService != null) {
\r
874 return mService.getAlbumName();
\r
875 } catch (RemoteException ex) {
\r
882 * @return current track name
\r
884 public static String getTrackName() {
\r
886 if (mService != null) {
\r
888 return mService.getTrackName();
\r
889 } catch (RemoteException ex) {
\r
896 * @return duration of a track
\r
898 public static long getDuration() {
\r
899 if (mService != null) {
\r
901 return mService.duration();
\r
902 } catch (RemoteException e) {
\r
910 * @return whether the mediascanner is running
\r
912 public static boolean isMediaScannerScanning(Context context) {
\r
913 boolean result = false;
\r
914 Cursor cursor = query(context, MediaStore.getMediaScannerUri(), new String[] {
\r
915 MediaStore.MEDIA_SCANNER_VOLUME
\r
916 }, null, null, null);
\r
917 if (cursor != null) {
\r
918 if (cursor.getCount() == 1) {
\r
919 cursor.moveToFirst();
\r
920 result = EXTERNAL.equals(cursor.getString(0));
\r
930 public static void setSpinnerState(Activity a) {
\r
931 if (isMediaScannerScanning(a)) {
\r
932 // Start the progress spinner
\r
933 a.getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS,
\r
934 Window.PROGRESS_INDETERMINATE_ON);
\r
936 a.getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS,
\r
937 Window.PROGRESS_VISIBILITY_ON);
\r
939 // Stop the progress spinner
\r
940 a.getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS,
\r
941 Window.PROGRESS_VISIBILITY_OFF);
\r
949 public static void displayDatabaseError(Activity a) {
\r
950 if (a.isFinishing()) {
\r
954 String status = Environment.getExternalStorageState();
\r
955 if (status.equals(Environment.MEDIA_MOUNTED)) {
\r
956 Intent intent = new Intent();
\r
957 intent.setClass(a, ScanningProgress.class);
\r
958 a.startActivityForResult(intent, SCAN_DONE);
\r
959 } else if (!TextUtils.equals(mLastSdStatus, status)) {
\r
960 mLastSdStatus = status;
\r
965 * Create a Search Chooser
\r
967 public static void doSearch(Context mContext, Cursor mCursor, int index) {
\r
968 CharSequence title = null;
\r
969 Intent i = new Intent();
\r
970 i.setAction(MediaStore.INTENT_ACTION_MEDIA_SEARCH);
\r
971 i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
\r
972 String query = mCursor.getString(index);
\r
974 i.putExtra("", query);
\r
975 title = title + " " + query;
\r
976 title = "Search " + title;
\r
977 i.putExtra(SearchManager.QUERY, query);
\r
978 mContext.startActivity(Intent.createChooser(i, title));
\r
983 * @return removes track from a playlist
\r
985 public static int removeTrack(long id) {
\r
986 if (mService == null)
\r
990 return mService.removeTrack(id);
\r
991 } catch (RemoteException e) {
\r
992 e.printStackTrace();
\r
1000 public static void setQueuePosition(int index) {
\r
1001 if (mService == null)
\r
1004 mService.setQueuePosition(index);
\r
1005 } catch (RemoteException e) {
\r
1009 public static String getArtistName(Context mContext, long artist_id, boolean default_name) {
\r
1010 String where = BaseColumns._ID + "=" + artist_id;
\r
1011 String[] cols = new String[] {
\r
1012 ArtistColumns.ARTIST
\r
1014 Uri uri = Audio.Artists.EXTERNAL_CONTENT_URI;
\r
1015 Cursor cursor = mContext.getContentResolver().query(uri, cols, where, null, null);
\r
1016 if (cursor.getCount() <= 0) {
\r
1018 return mContext.getString(R.string.unknown);
\r
1020 return MediaStore.UNKNOWN_STRING;
\r
1022 cursor.moveToFirst();
\r
1023 String name = cursor.getString(0);
\r
1025 if (name == null || MediaStore.UNKNOWN_STRING.equals(name)) {
\r
1027 return mContext.getString(R.string.unknown);
\r
1029 return MediaStore.UNKNOWN_STRING;
\r
1038 * @param default_name
\r
1039 * @return album name
\r
1041 public static String getAlbumName(Context mContext, long album_id, boolean default_name) {
\r
1042 String where = BaseColumns._ID + "=" + album_id;
\r
1043 String[] cols = new String[] {
\r
1044 AlbumColumns.ALBUM
\r
1046 Uri uri = Audio.Albums.EXTERNAL_CONTENT_URI;
\r
1047 Cursor cursor = mContext.getContentResolver().query(uri, cols, where, null, null);
\r
1048 if (cursor.getCount() <= 0) {
\r
1050 return mContext.getString(R.string.unknown);
\r
1052 return MediaStore.UNKNOWN_STRING;
\r
1054 cursor.moveToFirst();
\r
1055 String name = cursor.getString(0);
\r
1057 if (name == null || MediaStore.UNKNOWN_STRING.equals(name)) {
\r
1059 return mContext.getString(R.string.unknown);
\r
1061 return MediaStore.UNKNOWN_STRING;
\r
1068 * @param playlist_id
\r
1069 * @return playlist name
\r
1071 public static String getPlaylistName(Context mContext, long playlist_id) {
\r
1072 String where = BaseColumns._ID + "=" + playlist_id;
\r
1073 String[] cols = new String[] {
\r
1074 PlaylistsColumns.NAME
\r
1076 Uri uri = Audio.Playlists.EXTERNAL_CONTENT_URI;
\r
1077 Cursor cursor = mContext.getContentResolver().query(uri, cols, where, null, null);
\r
1078 if (cursor.getCount() <= 0)
\r
1080 cursor.moveToFirst();
\r
1081 String name = cursor.getString(0);
\r
1089 * @param default_name
\r
1090 * @return genre name
\r
1092 public static String getGenreName(Context mContext, long genre_id, boolean default_name) {
\r
1093 String where = BaseColumns._ID + "=" + genre_id;
\r
1094 String[] cols = new String[] {
\r
1095 GenresColumns.NAME
\r
1097 Uri uri = Audio.Genres.EXTERNAL_CONTENT_URI;
\r
1098 Cursor cursor = mContext.getContentResolver().query(uri, cols, where, null, null);
\r
1099 if (cursor.getCount() <= 0) {
\r
1101 return mContext.getString(R.string.unknown);
\r
1103 return MediaStore.UNKNOWN_STRING;
\r
1105 cursor.moveToFirst();
\r
1106 String name = cursor.getString(0);
\r
1108 if (name == null || MediaStore.UNKNOWN_STRING.equals(name)) {
\r
1110 return mContext.getString(R.string.unknown);
\r
1112 return MediaStore.UNKNOWN_STRING;
\r
1120 * @return parsed genre name
\r
1122 public static String parseGenreName(Context mContext, String genre) {
\r
1123 int genre_id = -1;
\r
1125 if (genre == null || genre.trim().length() <= 0)
\r
1126 return mContext.getResources().getString(R.string.unknown);
\r
1129 genre_id = Integer.parseInt(genre);
\r
1130 } catch (NumberFormatException e) {
\r
1133 if (genre_id >= 0 && genre_id < GENRES_DB.length)
\r
1134 return GENRES_DB[genre_id];
\r
1136 return mContext.getResources().getString(R.string.unknown);
\r
1140 * @return if music is playing
\r
1142 public static boolean isPlaying() {
\r
1143 if (mService == null)
\r
1147 mService.isPlaying();
\r
1148 } catch (RemoteException e) {
\r
1154 * @return current track's queue position
\r
1156 public static int getQueuePosition() {
\r
1157 if (mService == null)
\r
1160 return mService.getQueuePosition();
\r
1161 } catch (RemoteException e) {
\r
1168 * @param create_shortcut
\r
1171 public static void makePlaylistList(Context mContext, boolean create_shortcut,
\r
1172 List<Map<String, String>> list) {
\r
1174 Map<String, String> map;
\r
1176 String[] cols = new String[] {
\r
1177 Audio.Playlists._ID, Audio.Playlists.NAME
\r
1179 StringBuilder where = new StringBuilder();
\r
1181 ContentResolver resolver = mContext.getContentResolver();
\r
1182 if (resolver == null) {
\r
1183 System.out.println("resolver = null");
\r
1185 where.append(Audio.Playlists.NAME + " != ''");
\r
1186 where.append(" AND " + Audio.Playlists.NAME + " != '" + PLAYLIST_NAME_FAVORITES + "'");
\r
1187 Cursor cur = resolver.query(Audio.Playlists.EXTERNAL_CONTENT_URI, cols,
\r
1188 where.toString(), null, Audio.Playlists.NAME);
\r
1191 // map = new HashMap<String, String>();
\r
1192 // map.put("id", String.valueOf(PLAYLIST_FAVORITES));
\r
1193 // map.put("name", mContext.getString(R.string.favorite));
\r
1196 map = new HashMap<String, String>();
\r
1197 map.put("id", String.valueOf(PLAYLIST_QUEUE));
\r
1198 map.put("name", mContext.getString(R.string.queue));
\r
1201 map = new HashMap<String, String>();
\r
1202 map.put("id", String.valueOf(PLAYLIST_NEW));
\r
1203 map.put("name", mContext.getString(R.string.new_playlist));
\r
1206 if (cur != null && cur.getCount() > 0) {
\r
1207 cur.moveToFirst();
\r
1208 while (!cur.isAfterLast()) {
\r
1209 map = new HashMap<String, String>();
\r
1210 map.put("id", String.valueOf(cur.getLong(0)));
\r
1211 map.put("name", cur.getString(1));
\r
1216 if (cur != null) {
\r