1792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project/* 2792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * 4792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * you may not use this file except in compliance with the License. 6792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * You may obtain a copy of the License at 7792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * 8792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * 10792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * See the License for the specific language governing permissions and 14792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * limitations under the License. 15792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 16792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 17792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectpackage com.android.music; 18792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 19792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.app.Activity; 20792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.ComponentName; 21792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.ContentResolver; 22792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.ContentUris; 23792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.ContentValues; 24792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.Context; 25f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissenimport android.content.ContextWrapper; 26792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.Intent; 27792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.ServiceConnection; 28792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.SharedPreferences; 29792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.SharedPreferences.Editor; 30792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.res.Resources; 31792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.database.Cursor; 32792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.graphics.Bitmap; 33792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.graphics.BitmapFactory; 34792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.graphics.Canvas; 35792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.graphics.ColorFilter; 363193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissenimport android.graphics.ColorMatrix; 373193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissenimport android.graphics.ColorMatrixColorFilter; 383193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissenimport android.graphics.Matrix; 393193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissenimport android.graphics.Paint; 40792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.graphics.PixelFormat; 41792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.graphics.drawable.BitmapDrawable; 42792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.graphics.drawable.Drawable; 43792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.net.Uri; 44792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.os.Environment; 45792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.os.ParcelFileDescriptor; 467a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissenimport android.os.RemoteException; 47792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.provider.MediaStore; 48792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.provider.Settings; 497a05298d5af6f796f3a260fa60b11d1c029b4207Marco Nelissenimport android.text.TextUtils; 503988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissenimport android.text.format.Time; 51792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.util.Log; 52ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissenimport android.view.Menu; 53ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissenimport android.view.MenuItem; 54792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.view.SubMenu; 55792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.view.View; 56792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.view.Window; 57ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissenimport android.widget.TabWidget; 58792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.widget.TextView; 59792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.widget.Toast; 60792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 617a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissenimport java.io.File; 627a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissenimport java.io.FileDescriptor; 637a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissenimport java.io.FileNotFoundException; 647a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissenimport java.io.IOException; 657a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissenimport java.io.InputStream; 663988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissenimport java.io.PrintWriter; 677a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissenimport java.util.Arrays; 687a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissenimport java.util.Formatter; 697a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissenimport java.util.HashMap; 707a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissenimport java.util.Locale; 717a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen 72792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectpublic class MusicUtils { 73792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 74792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static final String TAG = "MusicUtils"; 75792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 76792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public interface Defs { 77792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public final static int OPEN_URL = 0; 78792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public final static int ADD_TO_PLAYLIST = 1; 79792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public final static int USE_AS_RINGTONE = 2; 80792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public final static int PLAYLIST_SELECTED = 3; 81792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public final static int NEW_PLAYLIST = 4; 82792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public final static int PLAY_SELECTION = 5; 83792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public final static int GOTO_START = 6; 84792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public final static int GOTO_PLAYBACK = 7; 85792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public final static int PARTY_SHUFFLE = 8; 86792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public final static int SHUFFLE_ALL = 9; 87792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public final static int DELETE_ITEM = 10; 88792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public final static int SCAN_DONE = 11; 89792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public final static int QUEUE = 12; 90f2ef3b5153fd2f447939f267d8887ff3bba0d13fMarco Nelissen public final static int EFFECTS_PANEL = 13; 91f2ef3b5153fd2f447939f267d8887ff3bba0d13fMarco Nelissen public final static int CHILD_MENU_BASE = 14; // this should be the last item 92792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 93792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 94792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static String makeAlbumsLabel(Context context, int numalbums, int numsongs, boolean isUnknown) { 95792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // There are two formats for the albums/songs information: 96792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // "N Song(s)" - used for unknown artist/album 97792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // "N Album(s)" - used for known albums 98792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 99792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project StringBuilder songs_albums = new StringBuilder(); 100792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 101792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Resources r = context.getResources(); 102792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (isUnknown) { 103792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (numsongs == 1) { 104792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project songs_albums.append(context.getString(R.string.onesong)); 105792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 106792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String f = r.getQuantityText(R.plurals.Nsongs, numsongs).toString(); 107792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sFormatBuilder.setLength(0); 108792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sFormatter.format(f, Integer.valueOf(numsongs)); 109792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project songs_albums.append(sFormatBuilder); 110792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 111792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 112792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String f = r.getQuantityText(R.plurals.Nalbums, numalbums).toString(); 113792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sFormatBuilder.setLength(0); 114792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sFormatter.format(f, Integer.valueOf(numalbums)); 115792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project songs_albums.append(sFormatBuilder); 116792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project songs_albums.append(context.getString(R.string.albumsongseparator)); 117792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 118792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return songs_albums.toString(); 119792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 120792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 121792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 122792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * This is now only used for the query screen 123792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 124792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static String makeAlbumsSongsLabel(Context context, int numalbums, int numsongs, boolean isUnknown) { 125792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // There are several formats for the albums/songs information: 126792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // "1 Song" - used if there is only 1 song 127792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // "N Songs" - used for the "unknown artist" item 128792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // "1 Album"/"N Songs" 129792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // "N Album"/"M Songs" 130792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Depending on locale, these may need to be further subdivided 131792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 132792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project StringBuilder songs_albums = new StringBuilder(); 133792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 134792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (numsongs == 1) { 135792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project songs_albums.append(context.getString(R.string.onesong)); 136792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 137792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Resources r = context.getResources(); 138792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (! isUnknown) { 139792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String f = r.getQuantityText(R.plurals.Nalbums, numalbums).toString(); 140792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sFormatBuilder.setLength(0); 141792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sFormatter.format(f, Integer.valueOf(numalbums)); 142792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project songs_albums.append(sFormatBuilder); 143792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project songs_albums.append(context.getString(R.string.albumsongseparator)); 144792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 145792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String f = r.getQuantityText(R.plurals.Nsongs, numsongs).toString(); 146792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sFormatBuilder.setLength(0); 147792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sFormatter.format(f, Integer.valueOf(numsongs)); 148792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project songs_albums.append(sFormatBuilder); 149792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 150792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return songs_albums.toString(); 151792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 152792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 153792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static IMediaPlaybackService sService = null; 154792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static HashMap<Context, ServiceBinder> sConnectionMap = new HashMap<Context, ServiceBinder>(); 155792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 156f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen public static class ServiceToken { 157f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen ContextWrapper mWrappedContext; 158f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen ServiceToken(ContextWrapper context) { 159f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen mWrappedContext = context; 160f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen } 161f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen } 162f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen 1633b55356662437499c38418629a38c8fb08880302Marco Nelissen public static ServiceToken bindToService(Activity context) { 164792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return bindToService(context, null); 165792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 166792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1673b55356662437499c38418629a38c8fb08880302Marco Nelissen public static ServiceToken bindToService(Activity context, ServiceConnection callback) { 1683b55356662437499c38418629a38c8fb08880302Marco Nelissen Activity realActivity = context.getParent(); 1693b55356662437499c38418629a38c8fb08880302Marco Nelissen if (realActivity == null) { 1703b55356662437499c38418629a38c8fb08880302Marco Nelissen realActivity = context; 1713b55356662437499c38418629a38c8fb08880302Marco Nelissen } 1723b55356662437499c38418629a38c8fb08880302Marco Nelissen ContextWrapper cw = new ContextWrapper(realActivity); 173f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen cw.startService(new Intent(cw, MediaPlaybackService.class)); 174792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ServiceBinder sb = new ServiceBinder(callback); 175f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen if (cw.bindService((new Intent()).setClass(cw, MediaPlaybackService.class), sb, 0)) { 176f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen sConnectionMap.put(cw, sb); 177f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen return new ServiceToken(cw); 178f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen } 1793b55356662437499c38418629a38c8fb08880302Marco Nelissen Log.e("Music", "Failed to bind to service"); 180f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen return null; 181792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 182f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen 183f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen public static void unbindFromService(ServiceToken token) { 1843b55356662437499c38418629a38c8fb08880302Marco Nelissen if (token == null) { 1853b55356662437499c38418629a38c8fb08880302Marco Nelissen Log.e("MusicUtils", "Trying to unbind with null token"); 1863b55356662437499c38418629a38c8fb08880302Marco Nelissen return; 1873b55356662437499c38418629a38c8fb08880302Marco Nelissen } 188f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen ContextWrapper cw = token.mWrappedContext; 189f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen ServiceBinder sb = sConnectionMap.remove(cw); 190792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (sb == null) { 191792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Log.e("MusicUtils", "Trying to unbind for unknown Context"); 192792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 193792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 194f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen cw.unbindService(sb); 195792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (sConnectionMap.isEmpty()) { 196792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // presumably there is nobody interested in the service at this point, 197792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // so don't hang on to the ServiceConnection 198792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sService = null; 199792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 200792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 201792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 202792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static class ServiceBinder implements ServiceConnection { 203792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ServiceConnection mCallback; 204792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ServiceBinder(ServiceConnection callback) { 205792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCallback = callback; 206792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 207792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 208792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void onServiceConnected(ComponentName className, android.os.IBinder service) { 209792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sService = IMediaPlaybackService.Stub.asInterface(service); 210792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project initAlbumArtCache(); 211792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mCallback != null) { 212792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCallback.onServiceConnected(className, service); 213792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 214792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 215792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 216792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void onServiceDisconnected(ComponentName className) { 217792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mCallback != null) { 218792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCallback.onServiceDisconnected(className); 219792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 220792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sService = null; 221792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 222792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 223792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 224bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static long getCurrentAlbumId() { 225792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (sService != null) { 226792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 227792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return sService.getAlbumId(); 228792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RemoteException ex) { 229792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 230792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 231792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return -1; 232792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 233792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 234bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static long getCurrentArtistId() { 235792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (MusicUtils.sService != null) { 236792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 237792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return sService.getArtistId(); 238792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RemoteException ex) { 239792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 240792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 241792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return -1; 242792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 243792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 244bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static long getCurrentAudioId() { 245792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (MusicUtils.sService != null) { 246792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 247792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return sService.getAudioId(); 248792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RemoteException ex) { 249792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 250792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 251792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return -1; 252792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 253792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 254792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static int getCurrentShuffleMode() { 255792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int mode = MediaPlaybackService.SHUFFLE_NONE; 256792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (sService != null) { 257792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 258792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mode = sService.getShuffleMode(); 259792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RemoteException ex) { 260792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 261792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 262792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mode; 263792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 264792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 265ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen public static void togglePartyShuffle() { 266ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (sService != null) { 267ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen int shuffle = getCurrentShuffleMode(); 268ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen try { 269ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (shuffle == MediaPlaybackService.SHUFFLE_AUTO) { 270ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen sService.setShuffleMode(MediaPlaybackService.SHUFFLE_NONE); 271ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } else { 272ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen sService.setShuffleMode(MediaPlaybackService.SHUFFLE_AUTO); 273ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 274ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } catch (RemoteException ex) { 275ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 276ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 277ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 278ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 279ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen public static void setPartyShuffleMenuIcon(Menu menu) { 280ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen MenuItem item = menu.findItem(Defs.PARTY_SHUFFLE); 281ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (item != null) { 282ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen int shuffle = MusicUtils.getCurrentShuffleMode(); 283ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (shuffle == MediaPlaybackService.SHUFFLE_AUTO) { 284ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen item.setIcon(R.drawable.ic_menu_party_shuffle); 285ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen item.setTitle(R.string.party_shuffle_off); 286ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } else { 287ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen item.setIcon(R.drawable.ic_menu_party_shuffle); 288ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen item.setTitle(R.string.party_shuffle); 289ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 290ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 291ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 292ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 293792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /* 294792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Returns true if a file is currently opened for playback (regardless 295792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * of whether it's playing or paused). 296792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 297792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static boolean isMusicLoaded() { 298792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (MusicUtils.sService != null) { 299792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 300792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return sService.getPath() != null; 301792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RemoteException ex) { 302792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 303792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 304792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return false; 305792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 306792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 307bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen private final static long [] sEmptyList = new long[0]; 308f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen 309bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static long [] getSongListForCursor(Cursor cursor) { 310792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cursor == null) { 311792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return sEmptyList; 312792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 313792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int len = cursor.getCount(); 314bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long [] list = new long[len]; 315792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cursor.moveToFirst(); 316792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int colidx = -1; 317792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 318792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project colidx = cursor.getColumnIndexOrThrow(MediaStore.Audio.Playlists.Members.AUDIO_ID); 319792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (IllegalArgumentException ex) { 320792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project colidx = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID); 321792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 322792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i = 0; i < len; i++) { 323bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen list[i] = cursor.getLong(colidx); 324792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cursor.moveToNext(); 325792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 326792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return list; 327792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 328792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 329bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static long [] getSongListForArtist(Context context, long id) { 330792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project final String[] ccols = new String[] { MediaStore.Audio.Media._ID }; 331792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String where = MediaStore.Audio.Media.ARTIST_ID + "=" + id + " AND " + 332792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.IS_MUSIC + "=1"; 333792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor cursor = query(context, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 334792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ccols, where, null, 335792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.ALBUM_KEY + "," + MediaStore.Audio.Media.TRACK); 336792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 337792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cursor != null) { 338bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long [] list = getSongListForCursor(cursor); 339792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cursor.close(); 340792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return list; 341792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 342792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return sEmptyList; 343792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 344792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 345bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static long [] getSongListForAlbum(Context context, long id) { 346792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project final String[] ccols = new String[] { MediaStore.Audio.Media._ID }; 347792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String where = MediaStore.Audio.Media.ALBUM_ID + "=" + id + " AND " + 348792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.IS_MUSIC + "=1"; 349792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor cursor = query(context, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 350792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ccols, where, null, MediaStore.Audio.Media.TRACK); 351792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 352792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cursor != null) { 353bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long [] list = getSongListForCursor(cursor); 354792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cursor.close(); 355792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return list; 356792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 357792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return sEmptyList; 358792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 359792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 360bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static long [] getSongListForPlaylist(Context context, long plid) { 361792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project final String[] ccols = new String[] { MediaStore.Audio.Playlists.Members.AUDIO_ID }; 362792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor cursor = query(context, MediaStore.Audio.Playlists.Members.getContentUri("external", plid), 363792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ccols, null, null, MediaStore.Audio.Playlists.Members.DEFAULT_SORT_ORDER); 364792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 365792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cursor != null) { 366bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long [] list = getSongListForCursor(cursor); 367792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cursor.close(); 368792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return list; 369792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 370792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return sEmptyList; 371792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 372792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 373792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void playPlaylist(Context context, long plid) { 374bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long [] list = getSongListForPlaylist(context, plid); 375792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (list != null) { 376792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project playAll(context, list, -1, false); 377792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 378792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 379792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 380bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static long [] getAllSongs(Context context) { 381792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor c = query(context, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 382792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project new String[] {MediaStore.Audio.Media._ID}, MediaStore.Audio.Media.IS_MUSIC + "=1", 383792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project null, null); 384792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 385792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (c == null || c.getCount() == 0) { 386792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return null; 387792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 388792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int len = c.getCount(); 389bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long [] list = new long[len]; 390792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i = 0; i < len; i++) { 391792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c.moveToNext(); 392bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen list[i] = c.getLong(0); 393792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 394792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 395792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return list; 396792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } finally { 397792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (c != null) { 398792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c.close(); 399792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 400792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 401792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 402792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 403792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 404792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Fills out the given submenu with items for "new playlist" and 405792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * any existing playlists. When the user selects an item, the 406792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * application will receive PLAYLIST_SELECTED with the Uri of 407792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * the selected playlist, NEW_PLAYLIST if a new playlist 408792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * should be created, and QUEUE if the "current playlist" was 409792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * selected. 410792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @param context The context to use for creating the menu items 411792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @param sub The submenu to add the items to. 412792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 413792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void makePlaylistMenu(Context context, SubMenu sub) { 414792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String[] cols = new String[] { 415792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Playlists._ID, 416792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Playlists.NAME 417792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project }; 418792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentResolver resolver = context.getContentResolver(); 419792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (resolver == null) { 420792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project System.out.println("resolver = null"); 421792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 422792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String whereclause = MediaStore.Audio.Playlists.NAME + " != ''"; 423792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor cur = resolver.query(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, 424792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cols, whereclause, null, 425792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Playlists.NAME); 426792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sub.clear(); 427792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sub.add(1, Defs.QUEUE, 0, R.string.queue); 428792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sub.add(1, Defs.NEW_PLAYLIST, 0, R.string.new_playlist); 429792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cur != null && cur.getCount() > 0) { 430792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project //sub.addSeparator(1, 0); 431792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cur.moveToFirst(); 432792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project while (! cur.isAfterLast()) { 433792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Intent intent = new Intent(); 434bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen intent.putExtra("playlist", cur.getLong(0)); 435792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project// if (cur.getInt(0) == mLastPlaylistSelected) { 436792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project// sub.add(0, MusicBaseActivity.PLAYLIST_SELECTED, cur.getString(1)).setIntent(intent); 437792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project// } else { 438792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sub.add(1, Defs.PLAYLIST_SELECTED, 0, cur.getString(1)).setIntent(intent); 439792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project// } 440792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cur.moveToNext(); 441792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 442792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 443792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cur != null) { 444792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cur.close(); 445792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 446792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 447792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 448792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 449792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void clearPlaylist(Context context, int plid) { 450792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 451792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", plid); 452792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project context.getContentResolver().delete(uri, null, null); 453792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 454792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 455792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 456bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static void deleteTracks(Context context, long [] list) { 457792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 458792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String [] cols = new String [] { MediaStore.Audio.Media._ID, 459792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.ALBUM_ID }; 460792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project StringBuilder where = new StringBuilder(); 461792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project where.append(MediaStore.Audio.Media._ID + " IN ("); 462792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i = 0; i < list.length; i++) { 463792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project where.append(list[i]); 464792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (i < list.length - 1) { 465792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project where.append(","); 466792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 467792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 468792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project where.append(")"); 469792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor c = query(context, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, cols, 470792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project where.toString(), null, null); 471792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 472792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (c != null) { 473792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 474792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // step 1: remove selected tracks from the current playlist, as well 475792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // as from the album art cache 476792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 477792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c.moveToFirst(); 478792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project while (! c.isAfterLast()) { 479792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // remove from current playlist 480bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long id = c.getLong(0); 481792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sService.removeTrack(id); 482792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // remove from album art cache 483bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long artIndex = c.getLong(2); 484792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized(sArtCache) { 485792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sArtCache.remove(artIndex); 486792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 487792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c.moveToNext(); 488792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 489792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RemoteException ex) { 490792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 491792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 492792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // step 2: remove selected tracks from the database 493792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project context.getContentResolver().delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, where.toString(), null); 494792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 495792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // step 3: remove files from card 496792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c.moveToFirst(); 497792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project while (! c.isAfterLast()) { 498792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String name = c.getString(1); 499792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project File f = new File(name); 500792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { // File.delete can throw a security exception 501792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (!f.delete()) { 502792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // I'm not sure if we'd ever get here (deletion would 503792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // have to fail, but no exception thrown) 504792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Log.e("MusicUtils", "Failed to delete file " + name); 505792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 506792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c.moveToNext(); 507792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (SecurityException ex) { 508792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c.moveToNext(); 509792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 510792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 511792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c.close(); 512792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 513792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 514792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String message = context.getResources().getQuantityString( 515792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project R.plurals.NNNtracksdeleted, list.length, Integer.valueOf(list.length)); 516792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 517792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); 518792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // We deleted a number of tracks, which could affect any number of things 519792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // in the media content domain, so update everything. 520792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project context.getContentResolver().notifyChange(Uri.parse("content://media"), null); 521792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 522792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 523bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static void addToCurrentPlaylist(Context context, long [] list) { 524792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (sService == null) { 525792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 526792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 527792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 528792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sService.enqueue(list, MediaPlaybackService.LAST); 529792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String message = context.getResources().getQuantityString( 530792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project R.plurals.NNNtrackstoplaylist, list.length, Integer.valueOf(list.length)); 531792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); 532792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RemoteException ex) { 533792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 534792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 535f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen 536f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen private static ContentValues[] sContentValuesCache = null; 537f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen 538f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen /** 539f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen * @param ids The source array containing all the ids to be added to the playlist 540f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen * @param offset Where in the 'ids' array we start reading 541f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen * @param len How many items to copy during this pass 542f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen * @param base The play order offset to use for this pass 543f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen */ 544f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen private static void makeInsertItems(long[] ids, int offset, int len, int base) { 545f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen // adjust 'len' if would extend beyond the end of the source array 546f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen if (offset + len > ids.length) { 547f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen len = ids.length - offset; 548f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen } 549f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen // allocate the ContentValues array, or reallocate if it is the wrong size 550f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen if (sContentValuesCache == null || sContentValuesCache.length != len) { 551f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen sContentValuesCache = new ContentValues[len]; 552f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen } 553f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen // fill in the ContentValues array with the right values for this pass 554f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen for (int i = 0; i < len; i++) { 555f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen if (sContentValuesCache[i] == null) { 556f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen sContentValuesCache[i] = new ContentValues(); 557f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen } 558f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen 559f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen sContentValuesCache[i].put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, base + offset + i); 560f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen sContentValuesCache[i].put(MediaStore.Audio.Playlists.Members.AUDIO_ID, ids[offset + i]); 561f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen } 562f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen } 563792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 564bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static void addToPlaylist(Context context, long [] ids, long playlistid) { 565792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (ids == null) { 566792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // this shouldn't happen (the menuitems shouldn't be visible 567792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // unless the selected item represents something playable 568792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Log.e("MusicBase", "ListSelection null"); 569792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 570792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int size = ids.length; 571792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentResolver resolver = context.getContentResolver(); 572792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // need to determine the number of items currently in the playlist, 573792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // so the play_order field can be maintained. 574792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String[] cols = new String[] { 575792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project "count(*)" 576792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project }; 577792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", playlistid); 578792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor cur = resolver.query(uri, cols, null, null, null); 579792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cur.moveToFirst(); 580792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int base = cur.getInt(0); 581792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cur.close(); 582f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen int numinserted = 0; 583f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen for (int i = 0; i < size; i += 1000) { 584f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen makeInsertItems(ids, i, 1000, base); 585f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen numinserted += resolver.bulkInsert(uri, sContentValuesCache); 586792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 587792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String message = context.getResources().getQuantityString( 588f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen R.plurals.NNNtrackstoplaylist, numinserted, numinserted); 589792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); 590792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project //mLastPlaylistSelected = playlistid; 591792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 592792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 593792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 594792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static Cursor query(Context context, Uri uri, String[] projection, 5954248ed203f66145f8be7cda2cfd937ec450c9609Marco Nelissen String selection, String[] selectionArgs, String sortOrder, int limit) { 596792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 597792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentResolver resolver = context.getContentResolver(); 598792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (resolver == null) { 599792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return null; 600792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 6014248ed203f66145f8be7cda2cfd937ec450c9609Marco Nelissen if (limit > 0) { 6024248ed203f66145f8be7cda2cfd937ec450c9609Marco Nelissen uri = uri.buildUpon().appendQueryParameter("limit", "" + limit).build(); 6034248ed203f66145f8be7cda2cfd937ec450c9609Marco Nelissen } 604792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return resolver.query(uri, projection, selection, selectionArgs, sortOrder); 605792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (UnsupportedOperationException ex) { 606792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return null; 607792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 608792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 609792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 6104248ed203f66145f8be7cda2cfd937ec450c9609Marco Nelissen public static Cursor query(Context context, Uri uri, String[] projection, 6114248ed203f66145f8be7cda2cfd937ec450c9609Marco Nelissen String selection, String[] selectionArgs, String sortOrder) { 6124248ed203f66145f8be7cda2cfd937ec450c9609Marco Nelissen return query(context, uri, projection, selection, selectionArgs, sortOrder, 0); 6134248ed203f66145f8be7cda2cfd937ec450c9609Marco Nelissen } 614792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 615792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static boolean isMediaScannerScanning(Context context) { 616792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project boolean result = false; 617792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor cursor = query(context, MediaStore.getMediaScannerUri(), 618792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project new String [] { MediaStore.MEDIA_SCANNER_VOLUME }, null, null, null); 619792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cursor != null) { 620792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cursor.getCount() == 1) { 621792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cursor.moveToFirst(); 622792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project result = "external".equals(cursor.getString(0)); 623792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 624792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cursor.close(); 625792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 626792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 627792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return result; 628792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 629792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 630792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void setSpinnerState(Activity a) { 631792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (isMediaScannerScanning(a)) { 632792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // start the progress spinner 633792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project a.getWindow().setFeatureInt( 634792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Window.FEATURE_INDETERMINATE_PROGRESS, 635792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Window.PROGRESS_INDETERMINATE_ON); 636792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 637792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project a.getWindow().setFeatureInt( 638792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Window.FEATURE_INDETERMINATE_PROGRESS, 639792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Window.PROGRESS_VISIBILITY_ON); 640792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 641792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // stop the progress spinner 642792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project a.getWindow().setFeatureInt( 643792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Window.FEATURE_INDETERMINATE_PROGRESS, 644792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Window.PROGRESS_VISIBILITY_OFF); 645792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 646792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 647792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 6487a05298d5af6f796f3a260fa60b11d1c029b4207Marco Nelissen private static String mLastSdStatus; 6497a05298d5af6f796f3a260fa60b11d1c029b4207Marco Nelissen 650792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void displayDatabaseError(Activity a) { 65198b177710b6a9bb2de7498d68e10a0d7f53c2f06Marco Nelissen if (a.isFinishing()) { 65298b177710b6a9bb2de7498d68e10a0d7f53c2f06Marco Nelissen // When switching tabs really fast, we can end up with a null 65398b177710b6a9bb2de7498d68e10a0d7f53c2f06Marco Nelissen // cursor (not sure why), which will bring us here. 65498b177710b6a9bb2de7498d68e10a0d7f53c2f06Marco Nelissen // Don't bother showing an error message in that case. 65598b177710b6a9bb2de7498d68e10a0d7f53c2f06Marco Nelissen return; 65698b177710b6a9bb2de7498d68e10a0d7f53c2f06Marco Nelissen } 65798b177710b6a9bb2de7498d68e10a0d7f53c2f06Marco Nelissen 658792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String status = Environment.getExternalStorageState(); 659ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer int title, message; 660ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer 661ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer if (android.os.Environment.isExternalStorageRemovable()) { 662ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer title = R.string.sdcard_error_title; 663ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer message = R.string.sdcard_error_message; 664ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer } else { 665ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer title = R.string.sdcard_error_title_nosdcard; 666ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer message = R.string.sdcard_error_message_nosdcard; 667ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer } 668792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 669792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (status.equals(Environment.MEDIA_SHARED) || 670792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project status.equals(Environment.MEDIA_UNMOUNTED)) { 671ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer if (android.os.Environment.isExternalStorageRemovable()) { 672ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer title = R.string.sdcard_busy_title; 673ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer message = R.string.sdcard_busy_message; 674ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer } else { 675ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer title = R.string.sdcard_busy_title_nosdcard; 676ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer message = R.string.sdcard_busy_message_nosdcard; 677ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer } 678792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (status.equals(Environment.MEDIA_REMOVED)) { 679ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer if (android.os.Environment.isExternalStorageRemovable()) { 680ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer title = R.string.sdcard_missing_title; 681ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer message = R.string.sdcard_missing_message; 682ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer } else { 683ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer title = R.string.sdcard_missing_title_nosdcard; 684ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer message = R.string.sdcard_missing_message_nosdcard; 685ecf5b6577ed52056fa8ae6035805bfed9f50c2f3Eric Fischer } 686792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (status.equals(Environment.MEDIA_MOUNTED)){ 687792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // The card is mounted, but we didn't get a valid cursor. 688792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // This probably means the mediascanner hasn't started scanning the 689792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // card yet (there is a small window of time during boot where this 690792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // will happen). 691792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project a.setTitle(""); 692792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Intent intent = new Intent(); 693792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project intent.setClass(a, ScanningProgress.class); 694792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project a.startActivityForResult(intent, Defs.SCAN_DONE); 6957a05298d5af6f796f3a260fa60b11d1c029b4207Marco Nelissen } else if (!TextUtils.equals(mLastSdStatus, status)) { 6967a05298d5af6f796f3a260fa60b11d1c029b4207Marco Nelissen mLastSdStatus = status; 697792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Log.d(TAG, "sd card: " + status); 698792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 699792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 700792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project a.setTitle(title); 701792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project View v = a.findViewById(R.id.sd_message); 702792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (v != null) { 703792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v.setVisibility(View.VISIBLE); 704792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 705792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v = a.findViewById(R.id.sd_icon); 706792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (v != null) { 707792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v.setVisibility(View.VISIBLE); 708792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 709792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v = a.findViewById(android.R.id.list); 710792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (v != null) { 711792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v.setVisibility(View.GONE); 712792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 7139e0f1fde0956ee7f5b76b77df7aea9b936e2c3a9Marco Nelissen v = a.findViewById(R.id.buttonbar); 7149e0f1fde0956ee7f5b76b77df7aea9b936e2c3a9Marco Nelissen if (v != null) { 7159e0f1fde0956ee7f5b76b77df7aea9b936e2c3a9Marco Nelissen v.setVisibility(View.GONE); 7169e0f1fde0956ee7f5b76b77df7aea9b936e2c3a9Marco Nelissen } 717792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project TextView tv = (TextView) a.findViewById(R.id.sd_message); 718792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project tv.setText(message); 719792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 720792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 721792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void hideDatabaseError(Activity a) { 722792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project View v = a.findViewById(R.id.sd_message); 723792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (v != null) { 724792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v.setVisibility(View.GONE); 725792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 726792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v = a.findViewById(R.id.sd_icon); 727792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (v != null) { 728792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v.setVisibility(View.GONE); 729792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 730792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v = a.findViewById(android.R.id.list); 731792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (v != null) { 732792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v.setVisibility(View.VISIBLE); 733792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 734792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 735792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 736792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static protected Uri getContentURIForPath(String path) { 737792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return Uri.fromFile(new File(path)); 738792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 739792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 740792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 741792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /* Try to use String.format() as little as possible, because it creates a 742792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * new Formatter every time you call it, which is very inefficient. 743792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Reusing an existing Formatter more than tripled the speed of 744792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * makeTimeString(). 745792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * This Formatter/StringBuilder are also used by makeAlbumSongsLabel() 746792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 747792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static StringBuilder sFormatBuilder = new StringBuilder(); 748792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static Formatter sFormatter = new Formatter(sFormatBuilder, Locale.getDefault()); 749792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static final Object[] sTimeArgs = new Object[5]; 750792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 751792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static String makeTimeString(Context context, long secs) { 7521e5a567390e41045cba6abac1d2c94eb8f59fc30Marco Nelissen String durationformat = context.getString( 7531e5a567390e41045cba6abac1d2c94eb8f59fc30Marco Nelissen secs < 3600 ? R.string.durationformatshort : R.string.durationformatlong); 754792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 755792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /* Provide multiple arguments so the format can be changed easily 756792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * by modifying the xml. 757792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 758792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sFormatBuilder.setLength(0); 759792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 760792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project final Object[] timeArgs = sTimeArgs; 761792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project timeArgs[0] = secs / 3600; 762792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project timeArgs[1] = secs / 60; 763792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project timeArgs[2] = (secs / 60) % 60; 764792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project timeArgs[3] = secs; 765792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project timeArgs[4] = secs % 60; 766792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 767792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return sFormatter.format(durationformat, timeArgs).toString(); 768792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 769792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 770792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void shuffleAll(Context context, Cursor cursor) { 771792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project playAll(context, cursor, 0, true); 772792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 773792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 774792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void playAll(Context context, Cursor cursor) { 775792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project playAll(context, cursor, 0, false); 776792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 777792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 778792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void playAll(Context context, Cursor cursor, int position) { 779792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project playAll(context, cursor, position, false); 780792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 781792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 782bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static void playAll(Context context, long [] list, int position) { 783792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project playAll(context, list, position, false); 784792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 785792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 786792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static void playAll(Context context, Cursor cursor, int position, boolean force_shuffle) { 787792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 788bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long [] list = getSongListForCursor(cursor); 789792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project playAll(context, list, position, force_shuffle); 790792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 791792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 792bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen private static void playAll(Context context, long [] list, int position, boolean force_shuffle) { 793792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (list.length == 0 || sService == null) { 794792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Log.d("MusicUtils", "attempt to play empty song list"); 795792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Don't try to play empty playlists. Nothing good will come of it. 796792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String message = context.getString(R.string.emptyplaylist, list.length); 797792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); 798792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 799792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 800792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 801792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (force_shuffle) { 802792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sService.setShuffleMode(MediaPlaybackService.SHUFFLE_NORMAL); 803792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 804bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long curid = sService.getAudioId(); 805792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int curpos = sService.getQueuePosition(); 806792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (position != -1 && curpos == position && curid == list[position]) { 807792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // The selected file is the file that's currently playing; 808792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // figure out if we need to restart with a new playlist, 809792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // or just launch the playback activity. 810bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long [] playlist = sService.getQueue(); 811792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (Arrays.equals(list, playlist)) { 812792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // we don't need to set a new list, but we should resume playback if needed 813792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sService.play(); 814792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; // the 'finally' block will still run 815792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 816792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 817792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (position < 0) { 818792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project position = 0; 819792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 820792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sService.open(list, force_shuffle ? -1 : position); 821792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sService.play(); 822792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RemoteException ex) { 823792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } finally { 82438bcd927f46d6477e6bae88795c38bfe92d7a9f9Marco Nelissen Intent intent = new Intent("com.android.music.PLAYBACK_VIEWER") 825792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 826792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project context.startActivity(intent); 827792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 828792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 829792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 830792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void clearQueue() { 831792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 832792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sService.removeTracks(0, Integer.MAX_VALUE); 833792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RemoteException ex) { 834792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 835792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 836792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 837792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // A really simple BitmapDrawable-like class, that doesn't do 838792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // scaling, dithering or filtering. 839792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static class FastBitmapDrawable extends Drawable { 840792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private Bitmap mBitmap; 841792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public FastBitmapDrawable(Bitmap b) { 842792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mBitmap = b; 843792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 844792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 845792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void draw(Canvas canvas) { 846792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project canvas.drawBitmap(mBitmap, 0, 0, null); 847792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 848792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 849792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int getOpacity() { 850792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return PixelFormat.OPAQUE; 851792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 852792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 853792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void setAlpha(int alpha) { 854792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 855792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 856792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void setColorFilter(ColorFilter cf) { 857792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 858792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 859792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 860792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static int sArtId = -2; 861792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static Bitmap mCachedBit = null; 862792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static final BitmapFactory.Options sBitmapOptionsCache = new BitmapFactory.Options(); 863792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static final BitmapFactory.Options sBitmapOptions = new BitmapFactory.Options(); 864792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart"); 865bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen private static final HashMap<Long, Drawable> sArtCache = new HashMap<Long, Drawable>(); 866792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static int sArtCacheId = -1; 867792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 868792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static { 869792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // for the cache, 870792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // 565 is faster to decode and display 871792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // and we don't want to dither here because the image will be scaled down later 872792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sBitmapOptionsCache.inPreferredConfig = Bitmap.Config.RGB_565; 873792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sBitmapOptionsCache.inDither = false; 874792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 875792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565; 876792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sBitmapOptions.inDither = false; 877792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 878792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 879792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void initAlbumArtCache() { 880792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 881792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int id = sService.getMediaMountedCount(); 882792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (id != sArtCacheId) { 883792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project clearAlbumArtCache(); 884792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sArtCacheId = id; 885792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 886792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RemoteException e) { 887792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project e.printStackTrace(); 888792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 889792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 890792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 891792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void clearAlbumArtCache() { 892792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized(sArtCache) { 893792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sArtCache.clear(); 894792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 895792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 896792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 897bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static Drawable getCachedArtwork(Context context, long artIndex, BitmapDrawable defaultArtwork) { 898792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Drawable d = null; 899792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized(sArtCache) { 900792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project d = sArtCache.get(artIndex); 901792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 902792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (d == null) { 903792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project d = defaultArtwork; 904792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project final Bitmap icon = defaultArtwork.getBitmap(); 905792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int w = icon.getWidth(); 906792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int h = icon.getHeight(); 907792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Bitmap b = MusicUtils.getArtworkQuick(context, artIndex, w, h); 908792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (b != null) { 909792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project d = new FastBitmapDrawable(b); 910792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized(sArtCache) { 911792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // the cache may have changed since we checked 912792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Drawable value = sArtCache.get(artIndex); 913792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (value == null) { 914792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sArtCache.put(artIndex, d); 915792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 916792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project d = value; 917792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 918792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 919792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 920792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 921792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return d; 922792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 923792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 924792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Get album art for specified album. This method will not try to 925792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // fall back to getting artwork directly from the file, nor will 926792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // it attempt to repair the database. 927bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen private static Bitmap getArtworkQuick(Context context, long album_id, int w, int h) { 928792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // NOTE: There is in fact a 1 pixel border on the right side in the ImageView 929792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // used to display this drawable. Take it into account now, so we don't have to 930792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // scale later. 931792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project w -= 1; 932792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentResolver res = context.getContentResolver(); 933792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id); 934792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (uri != null) { 935792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ParcelFileDescriptor fd = null; 936792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 937792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project fd = res.openFileDescriptor(uri, "r"); 938792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int sampleSize = 1; 939792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 940792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Compute the closest power-of-two scale factor 941792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // and pass that to sBitmapOptionsCache.inSampleSize, which will 942792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // result in faster decoding and better quality 943792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sBitmapOptionsCache.inJustDecodeBounds = true; 944792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project BitmapFactory.decodeFileDescriptor( 945792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project fd.getFileDescriptor(), null, sBitmapOptionsCache); 946792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int nextWidth = sBitmapOptionsCache.outWidth >> 1; 947792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int nextHeight = sBitmapOptionsCache.outHeight >> 1; 948792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project while (nextWidth>w && nextHeight>h) { 949792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sampleSize <<= 1; 950792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project nextWidth >>= 1; 951792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project nextHeight >>= 1; 952792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 953792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 954792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sBitmapOptionsCache.inSampleSize = sampleSize; 955792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sBitmapOptionsCache.inJustDecodeBounds = false; 956792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Bitmap b = BitmapFactory.decodeFileDescriptor( 957792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project fd.getFileDescriptor(), null, sBitmapOptionsCache); 958792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 959792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (b != null) { 960792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // finally rescale to exactly the size we need 961792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (sBitmapOptionsCache.outWidth != w || sBitmapOptionsCache.outHeight != h) { 962792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Bitmap tmp = Bitmap.createScaledBitmap(b, w, h, true); 963792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Bitmap.createScaledBitmap() can return the same bitmap 964792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (tmp != b) b.recycle(); 965792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project b = tmp; 966792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 967792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 968792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 969792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return b; 970792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (FileNotFoundException e) { 971792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } finally { 972792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 973792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (fd != null) 974792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project fd.close(); 975792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (IOException e) { 976792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 977792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 978792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 979792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return null; 980792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 9813193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen 982792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Get album art for specified album. You should not pass in the album id 983792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * for the "unknown" album here (use -1 instead) 9843193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen * This method always returns the default album art icon when no album art is found. 985792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 986bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static Bitmap getArtwork(Context context, long song_id, long album_id) { 9873193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen return getArtwork(context, song_id, album_id, true); 9883193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen } 9893193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen 9903193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen /** Get album art for specified album. You should not pass in the album id 9913193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen * for the "unknown" album here (use -1 instead) 9923193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen */ 9933193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen public static Bitmap getArtwork(Context context, long song_id, long album_id, 9943193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen boolean allowdefault) { 995792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 996792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (album_id < 0) { 997792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // This is something that is not in the database, so get the album art directly 998792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // from the file. 9997a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen if (song_id >= 0) { 10007a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen Bitmap bm = getArtworkFromFile(context, song_id, -1); 10017a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen if (bm != null) { 10027a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen return bm; 10037a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen } 1004792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 10053193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen if (allowdefault) { 10063193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen return getDefaultArtwork(context); 10073193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen } 10083193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen return null; 1009792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1010792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1011792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentResolver res = context.getContentResolver(); 1012792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id); 1013792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (uri != null) { 1014792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project InputStream in = null; 1015792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 1016792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project in = res.openInputStream(uri); 1017792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return BitmapFactory.decodeStream(in, null, sBitmapOptions); 1018792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (FileNotFoundException ex) { 1019792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // The album art thumbnail does not actually exist. Maybe the user deleted it, or 1020792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // maybe it never existed to begin with. 10217a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen Bitmap bm = getArtworkFromFile(context, song_id, album_id); 1022792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (bm != null) { 1023756c3f57f11a7bb3bf1cf1333ee8ffbc51039748Marco Nelissen if (bm.getConfig() == null) { 1024756c3f57f11a7bb3bf1cf1333ee8ffbc51039748Marco Nelissen bm = bm.copy(Bitmap.Config.RGB_565, false); 10253193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen if (bm == null && allowdefault) { 10267a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen return getDefaultArtwork(context); 1027792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1028792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 10293193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen } else if (allowdefault) { 10307a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen bm = getDefaultArtwork(context); 1031792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1032792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return bm; 1033792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } finally { 1034792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 1035792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (in != null) { 1036792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project in.close(); 1037792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1038792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (IOException ex) { 1039792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1040792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1041792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1042792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1043792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return null; 1044792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1045792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1046792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // get album art for specified file 1047792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static final String sExternalMediaUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI.toString(); 1048bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen private static Bitmap getArtworkFromFile(Context context, long songid, long albumid) { 1049792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Bitmap bm = null; 1050792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project byte [] art = null; 1051792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String path = null; 1052792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 10537a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen if (albumid < 0 && songid < 0) { 10547a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen throw new IllegalArgumentException("Must specify an album or a song id"); 1055792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 10567a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen 10577a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen try { 10587a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen if (albumid < 0) { 10597a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen Uri uri = Uri.parse("content://media/external/audio/media/" + songid + "/albumart"); 10607a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r"); 10617a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen if (pfd != null) { 10627a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen FileDescriptor fd = pfd.getFileDescriptor(); 10637a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen bm = BitmapFactory.decodeFileDescriptor(fd); 1064792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 10657a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen } else { 10667a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen Uri uri = ContentUris.withAppendedId(sArtworkUri, albumid); 10677a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r"); 10687a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen if (pfd != null) { 10697a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen FileDescriptor fd = pfd.getFileDescriptor(); 10707a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen bm = BitmapFactory.decodeFileDescriptor(fd); 1071792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1072792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1073dfc404c527e41c4bbc1804caba6ad5008309ec22Marco Nelissen } catch (IllegalStateException ex) { 10747a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen } catch (FileNotFoundException ex) { 1075792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 10767a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen if (bm != null) { 10777a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen mCachedBit = bm; 1078792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1079792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return bm; 1080792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1081792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1082792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static Bitmap getDefaultArtwork(Context context) { 1083792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project BitmapFactory.Options opts = new BitmapFactory.Options(); 1084792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project opts.inPreferredConfig = Bitmap.Config.ARGB_8888; 1085792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return BitmapFactory.decodeStream( 1086792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project context.getResources().openRawResource(R.drawable.albumart_mp_unknown), null, opts); 1087792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1088792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1089792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static int getIntPref(Context context, String name, int def) { 1090792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project SharedPreferences prefs = 109132b9f974fbbc0269e9293916dda265d0e18d0a29Marco Nelissen context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE); 1092792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return prefs.getInt(name, def); 1093792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1094792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1095792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static void setIntPref(Context context, String name, int value) { 1096792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project SharedPreferences prefs = 109732b9f974fbbc0269e9293916dda265d0e18d0a29Marco Nelissen context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE); 1098792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Editor ed = prefs.edit(); 1099792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ed.putInt(name, value); 110014c3caeb7bc2de0dd7abbb1e5f217dbb6367afbaBrad Fitzpatrick SharedPreferencesCompat.apply(ed); 1101792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1102792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1103792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static void setRingtone(Context context, long id) { 1104792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentResolver resolver = context.getContentResolver(); 1105792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Set the flag in the database to mark this as a ringtone 1106792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Uri ringUri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id); 1107792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 1108792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentValues values = new ContentValues(2); 1109792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project values.put(MediaStore.Audio.Media.IS_RINGTONE, "1"); 1110792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project values.put(MediaStore.Audio.Media.IS_ALARM, "1"); 1111792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project resolver.update(ringUri, values, null, null); 1112792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (UnsupportedOperationException ex) { 1113792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // most likely the card just got unmounted 1114792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Log.e(TAG, "couldn't set ringtone flag for id " + id); 1115792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 1116792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1117792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1118792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String[] cols = new String[] { 1119792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media._ID, 1120792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.DATA, 1121792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.TITLE 1122792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project }; 1123792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1124792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String where = MediaStore.Audio.Media._ID + "=" + id; 1125792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor cursor = query(context, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 1126792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cols, where , null, null); 1127792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 1128792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cursor != null && cursor.getCount() == 1) { 1129792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Set the system setting to make this the current ringtone 1130792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cursor.moveToFirst(); 1131792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Settings.System.putString(resolver, Settings.System.RINGTONE, ringUri.toString()); 1132792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String message = context.getString(R.string.ringtone_set, cursor.getString(2)); 1133792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); 1134792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1135792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } finally { 1136792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cursor != null) { 1137792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cursor.close(); 1138792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1139792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1140792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1141ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 1142ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen static int sActiveTabIndex = -1; 1143ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 114419cea9e16c54364a6a1df53cd617ba0a9c65b386Marco Nelissen static boolean updateButtonBar(Activity a, int highlight) { 1145ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen final TabWidget ll = (TabWidget) a.findViewById(R.id.buttonbar); 1146ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen boolean withtabs = false; 1147ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen Intent intent = a.getIntent(); 1148ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (intent != null) { 1149ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen withtabs = intent.getBooleanExtra("withtabs", false); 1150ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1151ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 1152ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (highlight == 0 || !withtabs) { 1153ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen ll.setVisibility(View.GONE); 115419cea9e16c54364a6a1df53cd617ba0a9c65b386Marco Nelissen return withtabs; 1155ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } else if (withtabs) { 1156ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen ll.setVisibility(View.VISIBLE); 1157ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1158ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen for (int i = ll.getChildCount() - 1; i >= 0; i--) { 1159ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 1160ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen View v = ll.getChildAt(i); 1161ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen boolean isActive = (v.getId() == highlight); 1162ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (isActive) { 1163ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen ll.setCurrentTab(i); 1164ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen sActiveTabIndex = i; 1165ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1166333bf1945f859968dcb9783b694aa64b788fc771Jeff Hamilton v.setTag(i); 1167ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen v.setOnFocusChangeListener(new View.OnFocusChangeListener() { 1168ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 1169ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen public void onFocusChange(View v, boolean hasFocus) { 1170ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (hasFocus) { 1171ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen for (int i = 0; i < ll.getTabCount(); i++) { 1172ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (ll.getChildTabViewAt(i) == v) { 1173ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen ll.setCurrentTab(i); 1174ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen processTabClick((Activity)ll.getContext(), v, ll.getChildAt(sActiveTabIndex).getId()); 1175ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen break; 1176ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1177ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1178ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1179ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen }}); 1180ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 1181ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen v.setOnClickListener(new View.OnClickListener() { 1182ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 1183ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen public void onClick(View v) { 1184ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen processTabClick((Activity)ll.getContext(), v, ll.getChildAt(sActiveTabIndex).getId()); 1185ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen }}); 1186ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 118719cea9e16c54364a6a1df53cd617ba0a9c65b386Marco Nelissen return withtabs; 1188ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1189ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 1190ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen static void processTabClick(Activity a, View v, int current) { 1191ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen int id = v.getId(); 1192ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (id == current) { 1193ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen return; 1194ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1195333bf1945f859968dcb9783b694aa64b788fc771Jeff Hamilton 1196333bf1945f859968dcb9783b694aa64b788fc771Jeff Hamilton final TabWidget ll = (TabWidget) a.findViewById(R.id.buttonbar); 1197333bf1945f859968dcb9783b694aa64b788fc771Jeff Hamilton 1198ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen activateTab(a, id); 1199ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (id != R.id.nowplayingtab) { 120038bcd927f46d6477e6bae88795c38bfe92d7a9f9Marco Nelissen ll.setCurrentTab((Integer) v.getTag()); 1201ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen setIntPref(a, "activetab", id); 1202ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1203ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1204ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 1205ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen static void activateTab(Activity a, int id) { 1206ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen Intent intent = new Intent(Intent.ACTION_PICK); 1207ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen switch (id) { 1208ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen case R.id.artisttab: 1209ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/artistalbum"); 1210ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen break; 1211ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen case R.id.albumtab: 1212ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/album"); 1213ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen break; 1214ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen case R.id.songtab: 1215ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/track"); 1216ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen break; 1217ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen case R.id.playlisttab: 1218ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen intent.setDataAndType(Uri.EMPTY, MediaStore.Audio.Playlists.CONTENT_TYPE); 1219ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen break; 1220ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen case R.id.nowplayingtab: 1221ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen intent = new Intent(a, MediaPlaybackActivity.class); 1222ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen a.startActivity(intent); 1223ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen // fall through and return 1224ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen default: 1225ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen return; 1226ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1227ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen intent.putExtra("withtabs", true); 1228ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 1229ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen a.startActivity(intent); 1230ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen a.finish(); 1231ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen a.overridePendingTransition(0, 0); 1232ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1233ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 1234ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen static void updateNowPlaying(Activity a) { 1235ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen View nowPlayingView = a.findViewById(R.id.nowplaying); 1236ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (nowPlayingView == null) { 1237ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen return; 1238ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1239ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen try { 1240ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen boolean withtabs = false; 1241ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen Intent intent = a.getIntent(); 1242ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (intent != null) { 1243ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen withtabs = intent.getBooleanExtra("withtabs", false); 1244ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1245ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (true && MusicUtils.sService != null && MusicUtils.sService.getAudioId() != -1) { 1246ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen TextView title = (TextView) nowPlayingView.findViewById(R.id.title); 1247ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen TextView artist = (TextView) nowPlayingView.findViewById(R.id.artist); 1248ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen title.setText(MusicUtils.sService.getTrackName()); 1249ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen String artistName = MusicUtils.sService.getArtistName(); 1250f4d4b342061ade12eb7903f454df62814179906fMarco Nelissen if (MediaStore.UNKNOWN_STRING.equals(artistName)) { 1251ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen artistName = a.getString(R.string.unknown_artist_name); 1252ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1253ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen artist.setText(artistName); 1254ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen //mNowPlayingView.setOnFocusChangeListener(mFocuser); 1255ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen //mNowPlayingView.setOnClickListener(this); 1256ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen nowPlayingView.setVisibility(View.VISIBLE); 1257ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen nowPlayingView.setOnClickListener(new View.OnClickListener() { 1258ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 1259ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen public void onClick(View v) { 1260ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen Context c = v.getContext(); 1261ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen c.startActivity(new Intent(c, MediaPlaybackActivity.class)); 1262ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen }}); 1263ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen return; 1264ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1265ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } catch (RemoteException ex) { 1266ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1267ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen nowPlayingView.setVisibility(View.GONE); 1268ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1269ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 12703193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen static void setBackground(View v, Bitmap bm) { 12713193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen 12723193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen if (bm == null) { 12733193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen v.setBackgroundResource(0); 12743193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen return; 12753193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen } 12763193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen 12773193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen int vwidth = v.getWidth(); 12783193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen int vheight = v.getHeight(); 12793193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen int bwidth = bm.getWidth(); 12803193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen int bheight = bm.getHeight(); 12813193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen float scalex = (float) vwidth / bwidth; 12823193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen float scaley = (float) vheight / bheight; 12833193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen float scale = Math.max(scalex, scaley) * 1.3f; 12843193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen 12853193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen Bitmap.Config config = Bitmap.Config.ARGB_8888; 12863193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen Bitmap bg = Bitmap.createBitmap(vwidth, vheight, config); 12873193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen Canvas c = new Canvas(bg); 12883193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen Paint paint = new Paint(); 12893193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen paint.setAntiAlias(true); 12903193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen paint.setFilterBitmap(true); 12913193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen ColorMatrix greymatrix = new ColorMatrix(); 12923193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen greymatrix.setSaturation(0); 12933193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen ColorMatrix darkmatrix = new ColorMatrix(); 12943193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen darkmatrix.setScale(.3f, .3f, .3f, 1.0f); 12953193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen greymatrix.postConcat(darkmatrix); 12963193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen ColorFilter filter = new ColorMatrixColorFilter(greymatrix); 12973193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen paint.setColorFilter(filter); 12983193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen Matrix matrix = new Matrix(); 12993193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen matrix.setTranslate(-bwidth/2, -bheight/2); // move bitmap center to origin 13003193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen matrix.postRotate(10); 13013193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen matrix.postScale(scale, scale); 13023193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen matrix.postTranslate(vwidth/2, vheight/2); // Move bitmap center to view center 13033193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen c.drawBitmap(bm, matrix, paint); 13043193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen v.setBackgroundDrawable(new BitmapDrawable(bg)); 13053193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen } 13063193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen 130787bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen static int getCardId(Context context) { 130887bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen ContentResolver res = context.getContentResolver(); 130987bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen Cursor c = res.query(Uri.parse("content://media/external/fs_id"), null, null, null, null); 131087bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen int id = -1; 131187bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen if (c != null) { 131287bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen c.moveToFirst(); 131387bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen id = c.getInt(0); 131487bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen c.close(); 131587bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen } 131687bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen return id; 131787bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen } 13183988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen 13193988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen static class LogEntry { 13203988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen Object item; 13213988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen long time; 13223988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen 13233988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen LogEntry(Object o) { 13243988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen item = o; 13253988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen time = System.currentTimeMillis(); 13263988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen } 13273988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen 13283988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen void dump(PrintWriter out) { 13293988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen sTime.set(time); 13303988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen out.print(sTime.toString() + " : "); 13313988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen if (item instanceof Exception) { 13323988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen ((Exception)item).printStackTrace(out); 13333988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen } else { 13343988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen out.println(item); 13353988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen } 13363988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen } 13373988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen } 13383988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen 13393988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen private static LogEntry[] sMusicLog = new LogEntry[100]; 13403988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen private static int sLogPtr = 0; 13413988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen private static Time sTime = new Time(); 13423988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen 13433988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen static void debugLog(Object o) { 13443988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen 13453988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen sMusicLog[sLogPtr] = new LogEntry(o); 13463988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen sLogPtr++; 13473988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen if (sLogPtr >= sMusicLog.length) { 13483988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen sLogPtr = 0; 13493988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen } 13503988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen } 13513988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen 13523988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen static void debugDump(PrintWriter out) { 13533988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen for (int i = 0; i < sMusicLog.length; i++) { 13543988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen int idx = (sLogPtr + i); 13553988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen if (idx >= sMusicLog.length) { 13563988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen idx -= sMusicLog.length; 13573988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen } 13583988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen LogEntry entry = sMusicLog[idx]; 13593988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen if (entry != null) { 13603988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen entry.dump(out); 13613988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen } 13623988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen } 13633988890280c37b2b4aa1cb29ce16da8aa38ffa83Marco Nelissen } 1364792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project} 1365