MusicUtils.java revision 3b55356662437499c38418629a38c8fb08880302
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; 50792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.util.Log; 51ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissenimport android.view.Menu; 52ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissenimport android.view.MenuItem; 53792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.view.SubMenu; 54792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.view.View; 55ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissenimport android.view.ViewGroup; 56792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.view.Window; 57f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissenimport android.view.MenuItem.OnMenuItemClickListener; 58ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissenimport android.widget.TabWidget; 59792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.widget.TextView; 60792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.widget.Toast; 61792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 627a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissenimport java.io.File; 637a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissenimport java.io.FileDescriptor; 647a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissenimport java.io.FileNotFoundException; 657a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissenimport java.io.IOException; 667a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissenimport java.io.InputStream; 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; 90792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public final static int CHILD_MENU_BASE = 13; // this should be the last item 91792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 92792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 93792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static String makeAlbumsLabel(Context context, int numalbums, int numsongs, boolean isUnknown) { 94792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // There are two formats for the albums/songs information: 95792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // "N Song(s)" - used for unknown artist/album 96792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // "N Album(s)" - used for known albums 97792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 98792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project StringBuilder songs_albums = new StringBuilder(); 99792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 100792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Resources r = context.getResources(); 101792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (isUnknown) { 102792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (numsongs == 1) { 103792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project songs_albums.append(context.getString(R.string.onesong)); 104792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 105792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String f = r.getQuantityText(R.plurals.Nsongs, numsongs).toString(); 106792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sFormatBuilder.setLength(0); 107792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sFormatter.format(f, Integer.valueOf(numsongs)); 108792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project songs_albums.append(sFormatBuilder); 109792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 110792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 111792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String f = r.getQuantityText(R.plurals.Nalbums, numalbums).toString(); 112792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sFormatBuilder.setLength(0); 113792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sFormatter.format(f, Integer.valueOf(numalbums)); 114792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project songs_albums.append(sFormatBuilder); 115792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project songs_albums.append(context.getString(R.string.albumsongseparator)); 116792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 117792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return songs_albums.toString(); 118792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 119792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 120792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 121792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * This is now only used for the query screen 122792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 123792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static String makeAlbumsSongsLabel(Context context, int numalbums, int numsongs, boolean isUnknown) { 124792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // There are several formats for the albums/songs information: 125792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // "1 Song" - used if there is only 1 song 126792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // "N Songs" - used for the "unknown artist" item 127792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // "1 Album"/"N Songs" 128792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // "N Album"/"M Songs" 129792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Depending on locale, these may need to be further subdivided 130792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 131792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project StringBuilder songs_albums = new StringBuilder(); 132792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 133792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (numsongs == 1) { 134792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project songs_albums.append(context.getString(R.string.onesong)); 135792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 136792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Resources r = context.getResources(); 137792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (! isUnknown) { 138792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String f = r.getQuantityText(R.plurals.Nalbums, numalbums).toString(); 139792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sFormatBuilder.setLength(0); 140792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sFormatter.format(f, Integer.valueOf(numalbums)); 141792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project songs_albums.append(sFormatBuilder); 142792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project songs_albums.append(context.getString(R.string.albumsongseparator)); 143792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 144792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String f = r.getQuantityText(R.plurals.Nsongs, numsongs).toString(); 145792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sFormatBuilder.setLength(0); 146792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sFormatter.format(f, Integer.valueOf(numsongs)); 147792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project songs_albums.append(sFormatBuilder); 148792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 149792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return songs_albums.toString(); 150792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 151792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 152792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static IMediaPlaybackService sService = null; 153792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static HashMap<Context, ServiceBinder> sConnectionMap = new HashMap<Context, ServiceBinder>(); 154792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 155f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen public static class ServiceToken { 156f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen ContextWrapper mWrappedContext; 157f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen ServiceToken(ContextWrapper context) { 158f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen mWrappedContext = context; 159f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen } 160f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen } 161f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen 1623b55356662437499c38418629a38c8fb08880302Marco Nelissen public static ServiceToken bindToService(Activity context) { 163792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return bindToService(context, null); 164792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 165792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1663b55356662437499c38418629a38c8fb08880302Marco Nelissen public static ServiceToken bindToService(Activity context, ServiceConnection callback) { 1673b55356662437499c38418629a38c8fb08880302Marco Nelissen Activity realActivity = context.getParent(); 1683b55356662437499c38418629a38c8fb08880302Marco Nelissen if (realActivity == null) { 1693b55356662437499c38418629a38c8fb08880302Marco Nelissen realActivity = context; 1703b55356662437499c38418629a38c8fb08880302Marco Nelissen } 1713b55356662437499c38418629a38c8fb08880302Marco Nelissen ContextWrapper cw = new ContextWrapper(realActivity); 172f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen cw.startService(new Intent(cw, MediaPlaybackService.class)); 173792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ServiceBinder sb = new ServiceBinder(callback); 174f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen if (cw.bindService((new Intent()).setClass(cw, MediaPlaybackService.class), sb, 0)) { 175f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen sConnectionMap.put(cw, sb); 176f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen return new ServiceToken(cw); 177f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen } 1783b55356662437499c38418629a38c8fb08880302Marco Nelissen Log.e("Music", "Failed to bind to service"); 179f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen return null; 180792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 181f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen 182f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen public static void unbindFromService(ServiceToken token) { 1833b55356662437499c38418629a38c8fb08880302Marco Nelissen if (token == null) { 1843b55356662437499c38418629a38c8fb08880302Marco Nelissen Log.e("MusicUtils", "Trying to unbind with null token"); 1853b55356662437499c38418629a38c8fb08880302Marco Nelissen return; 1863b55356662437499c38418629a38c8fb08880302Marco Nelissen } 187f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen ContextWrapper cw = token.mWrappedContext; 188f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen ServiceBinder sb = sConnectionMap.remove(cw); 189792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (sb == null) { 190792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Log.e("MusicUtils", "Trying to unbind for unknown Context"); 191792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 192792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 193f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen cw.unbindService(sb); 194792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (sConnectionMap.isEmpty()) { 195792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // presumably there is nobody interested in the service at this point, 196792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // so don't hang on to the ServiceConnection 197792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sService = null; 198792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 199792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 200792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 201792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static class ServiceBinder implements ServiceConnection { 202792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ServiceConnection mCallback; 203792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ServiceBinder(ServiceConnection callback) { 204792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCallback = callback; 205792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 206792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 207792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void onServiceConnected(ComponentName className, android.os.IBinder service) { 208792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sService = IMediaPlaybackService.Stub.asInterface(service); 209792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project initAlbumArtCache(); 210792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mCallback != null) { 211792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCallback.onServiceConnected(className, service); 212792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 213792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 214792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 215792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void onServiceDisconnected(ComponentName className) { 216792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mCallback != null) { 217792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCallback.onServiceDisconnected(className); 218792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 219792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sService = null; 220792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 221792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 222792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 223bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static long getCurrentAlbumId() { 224792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (sService != null) { 225792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 226792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return sService.getAlbumId(); 227792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RemoteException ex) { 228792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 229792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 230792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return -1; 231792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 232792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 233bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static long getCurrentArtistId() { 234792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (MusicUtils.sService != null) { 235792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 236792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return sService.getArtistId(); 237792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RemoteException ex) { 238792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 239792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 240792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return -1; 241792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 242792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 243bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static long getCurrentAudioId() { 244792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (MusicUtils.sService != null) { 245792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 246792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return sService.getAudioId(); 247792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RemoteException ex) { 248792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 249792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 250792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return -1; 251792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 252792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 253792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static int getCurrentShuffleMode() { 254792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int mode = MediaPlaybackService.SHUFFLE_NONE; 255792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (sService != null) { 256792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 257792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mode = sService.getShuffleMode(); 258792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RemoteException ex) { 259792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 260792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 261792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mode; 262792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 263792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 264ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen public static void togglePartyShuffle() { 265ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (sService != null) { 266ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen int shuffle = getCurrentShuffleMode(); 267ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen try { 268ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (shuffle == MediaPlaybackService.SHUFFLE_AUTO) { 269ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen sService.setShuffleMode(MediaPlaybackService.SHUFFLE_NONE); 270ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } else { 271ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen sService.setShuffleMode(MediaPlaybackService.SHUFFLE_AUTO); 272ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 273ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } catch (RemoteException ex) { 274ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 275ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 276ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 277ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 278ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen public static void setPartyShuffleMenuIcon(Menu menu) { 279ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen MenuItem item = menu.findItem(Defs.PARTY_SHUFFLE); 280ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (item != null) { 281ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen int shuffle = MusicUtils.getCurrentShuffleMode(); 282ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (shuffle == MediaPlaybackService.SHUFFLE_AUTO) { 283ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen item.setIcon(R.drawable.ic_menu_party_shuffle); 284ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen item.setTitle(R.string.party_shuffle_off); 285ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } else { 286ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen item.setIcon(R.drawable.ic_menu_party_shuffle); 287ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen item.setTitle(R.string.party_shuffle); 288ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 289ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 290ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 291ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 292792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /* 293792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Returns true if a file is currently opened for playback (regardless 294792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * of whether it's playing or paused). 295792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 296792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static boolean isMusicLoaded() { 297792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (MusicUtils.sService != null) { 298792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 299792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return sService.getPath() != null; 300792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RemoteException ex) { 301792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 302792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 303792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return false; 304792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 305792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 306bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen private final static long [] sEmptyList = new long[0]; 307f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen 308bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static long [] getSongListForCursor(Cursor cursor) { 309792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cursor == null) { 310792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return sEmptyList; 311792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 312792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int len = cursor.getCount(); 313bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long [] list = new long[len]; 314792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cursor.moveToFirst(); 315792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int colidx = -1; 316792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 317792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project colidx = cursor.getColumnIndexOrThrow(MediaStore.Audio.Playlists.Members.AUDIO_ID); 318792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (IllegalArgumentException ex) { 319792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project colidx = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID); 320792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 321792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i = 0; i < len; i++) { 322bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen list[i] = cursor.getLong(colidx); 323792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cursor.moveToNext(); 324792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 325792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return list; 326792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 327792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 328bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static long [] getSongListForArtist(Context context, long id) { 329792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project final String[] ccols = new String[] { MediaStore.Audio.Media._ID }; 330792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String where = MediaStore.Audio.Media.ARTIST_ID + "=" + id + " AND " + 331792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.IS_MUSIC + "=1"; 332792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor cursor = query(context, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 333792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ccols, where, null, 334792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.ALBUM_KEY + "," + MediaStore.Audio.Media.TRACK); 335792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 336792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cursor != null) { 337bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long [] list = getSongListForCursor(cursor); 338792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cursor.close(); 339792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return list; 340792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 341792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return sEmptyList; 342792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 343792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 344bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static long [] getSongListForAlbum(Context context, long id) { 345792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project final String[] ccols = new String[] { MediaStore.Audio.Media._ID }; 346792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String where = MediaStore.Audio.Media.ALBUM_ID + "=" + id + " AND " + 347792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.IS_MUSIC + "=1"; 348792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor cursor = query(context, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 349792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ccols, where, null, MediaStore.Audio.Media.TRACK); 350792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 351792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cursor != null) { 352bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long [] list = getSongListForCursor(cursor); 353792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cursor.close(); 354792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return list; 355792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 356792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return sEmptyList; 357792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 358792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 359bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static long [] getSongListForPlaylist(Context context, long plid) { 360792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project final String[] ccols = new String[] { MediaStore.Audio.Playlists.Members.AUDIO_ID }; 361792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor cursor = query(context, MediaStore.Audio.Playlists.Members.getContentUri("external", plid), 362792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ccols, null, null, MediaStore.Audio.Playlists.Members.DEFAULT_SORT_ORDER); 363792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 364792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cursor != null) { 365bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long [] list = getSongListForCursor(cursor); 366792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cursor.close(); 367792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return list; 368792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 369792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return sEmptyList; 370792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 371792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 372792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void playPlaylist(Context context, long plid) { 373bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long [] list = getSongListForPlaylist(context, plid); 374792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (list != null) { 375792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project playAll(context, list, -1, false); 376792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 377792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 378792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 379bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static long [] getAllSongs(Context context) { 380792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor c = query(context, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 381792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project new String[] {MediaStore.Audio.Media._ID}, MediaStore.Audio.Media.IS_MUSIC + "=1", 382792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project null, null); 383792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 384792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (c == null || c.getCount() == 0) { 385792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return null; 386792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 387792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int len = c.getCount(); 388bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long [] list = new long[len]; 389792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i = 0; i < len; i++) { 390792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c.moveToNext(); 391bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen list[i] = c.getLong(0); 392792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 393792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 394792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return list; 395792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } finally { 396792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (c != null) { 397792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c.close(); 398792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 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 * Fills out the given submenu with items for "new playlist" and 404792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * any existing playlists. When the user selects an item, the 405792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * application will receive PLAYLIST_SELECTED with the Uri of 406792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * the selected playlist, NEW_PLAYLIST if a new playlist 407792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * should be created, and QUEUE if the "current playlist" was 408792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * selected. 409792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @param context The context to use for creating the menu items 410792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @param sub The submenu to add the items to. 411792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 412792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void makePlaylistMenu(Context context, SubMenu sub) { 413792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String[] cols = new String[] { 414792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Playlists._ID, 415792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Playlists.NAME 416792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project }; 417792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentResolver resolver = context.getContentResolver(); 418792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (resolver == null) { 419792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project System.out.println("resolver = null"); 420792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 421792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String whereclause = MediaStore.Audio.Playlists.NAME + " != ''"; 422792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor cur = resolver.query(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, 423792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cols, whereclause, null, 424792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Playlists.NAME); 425792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sub.clear(); 426792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sub.add(1, Defs.QUEUE, 0, R.string.queue); 427792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sub.add(1, Defs.NEW_PLAYLIST, 0, R.string.new_playlist); 428792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cur != null && cur.getCount() > 0) { 429792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project //sub.addSeparator(1, 0); 430792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cur.moveToFirst(); 431792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project while (! cur.isAfterLast()) { 432792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Intent intent = new Intent(); 433bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen intent.putExtra("playlist", cur.getLong(0)); 434792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project// if (cur.getInt(0) == mLastPlaylistSelected) { 435792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project// sub.add(0, MusicBaseActivity.PLAYLIST_SELECTED, cur.getString(1)).setIntent(intent); 436792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project// } else { 437792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sub.add(1, Defs.PLAYLIST_SELECTED, 0, cur.getString(1)).setIntent(intent); 438792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project// } 439792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cur.moveToNext(); 440792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 441792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 442792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cur != null) { 443792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cur.close(); 444792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 445792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 446792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 447792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 448792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void clearPlaylist(Context context, int plid) { 449792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 450792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", plid); 451792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project context.getContentResolver().delete(uri, null, null); 452792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 453792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 454792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 455bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static void deleteTracks(Context context, long [] list) { 456792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 457792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String [] cols = new String [] { MediaStore.Audio.Media._ID, 458792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.ALBUM_ID }; 459792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project StringBuilder where = new StringBuilder(); 460792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project where.append(MediaStore.Audio.Media._ID + " IN ("); 461792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i = 0; i < list.length; i++) { 462792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project where.append(list[i]); 463792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (i < list.length - 1) { 464792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project where.append(","); 465792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 466792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 467792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project where.append(")"); 468792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor c = query(context, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, cols, 469792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project where.toString(), null, null); 470792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 471792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (c != null) { 472792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 473792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // step 1: remove selected tracks from the current playlist, as well 474792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // as from the album art cache 475792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 476792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c.moveToFirst(); 477792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project while (! c.isAfterLast()) { 478792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // remove from current playlist 479bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long id = c.getLong(0); 480792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sService.removeTrack(id); 481792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // remove from album art cache 482bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long artIndex = c.getLong(2); 483792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized(sArtCache) { 484792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sArtCache.remove(artIndex); 485792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 486792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c.moveToNext(); 487792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 488792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RemoteException ex) { 489792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 490792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 491792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // step 2: remove selected tracks from the database 492792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project context.getContentResolver().delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, where.toString(), null); 493792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 494792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // step 3: remove files from card 495792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c.moveToFirst(); 496792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project while (! c.isAfterLast()) { 497792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String name = c.getString(1); 498792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project File f = new File(name); 499792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { // File.delete can throw a security exception 500792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (!f.delete()) { 501792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // I'm not sure if we'd ever get here (deletion would 502792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // have to fail, but no exception thrown) 503792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Log.e("MusicUtils", "Failed to delete file " + name); 504792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 505792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c.moveToNext(); 506792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (SecurityException ex) { 507792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c.moveToNext(); 508792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 509792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 510792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c.close(); 511792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 512792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 513792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String message = context.getResources().getQuantityString( 514792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project R.plurals.NNNtracksdeleted, list.length, Integer.valueOf(list.length)); 515792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 516792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); 517792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // We deleted a number of tracks, which could affect any number of things 518792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // in the media content domain, so update everything. 519792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project context.getContentResolver().notifyChange(Uri.parse("content://media"), null); 520792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 521792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 522bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static void addToCurrentPlaylist(Context context, long [] list) { 523792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (sService == null) { 524792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 525792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 526792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 527792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sService.enqueue(list, MediaPlaybackService.LAST); 528792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String message = context.getResources().getQuantityString( 529792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project R.plurals.NNNtrackstoplaylist, list.length, Integer.valueOf(list.length)); 530792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); 531792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RemoteException ex) { 532792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 533792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 534f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen 535f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen private static ContentValues[] sContentValuesCache = null; 536f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen 537f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen /** 538f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen * @param ids The source array containing all the ids to be added to the playlist 539f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen * @param offset Where in the 'ids' array we start reading 540f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen * @param len How many items to copy during this pass 541f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen * @param base The play order offset to use for this pass 542f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen */ 543f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen private static void makeInsertItems(long[] ids, int offset, int len, int base) { 544f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen // adjust 'len' if would extend beyond the end of the source array 545f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen if (offset + len > ids.length) { 546f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen len = ids.length - offset; 547f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen } 548f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen // allocate the ContentValues array, or reallocate if it is the wrong size 549f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen if (sContentValuesCache == null || sContentValuesCache.length != len) { 550f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen sContentValuesCache = new ContentValues[len]; 551f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen } 552f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen // fill in the ContentValues array with the right values for this pass 553f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen for (int i = 0; i < len; i++) { 554f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen if (sContentValuesCache[i] == null) { 555f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen sContentValuesCache[i] = new ContentValues(); 556f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen } 557f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen 558f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen sContentValuesCache[i].put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, base + offset + i); 559f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen sContentValuesCache[i].put(MediaStore.Audio.Playlists.Members.AUDIO_ID, ids[offset + i]); 560f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen } 561f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen } 562792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 563bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static void addToPlaylist(Context context, long [] ids, long playlistid) { 564792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (ids == null) { 565792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // this shouldn't happen (the menuitems shouldn't be visible 566792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // unless the selected item represents something playable 567792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Log.e("MusicBase", "ListSelection null"); 568792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 569792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int size = ids.length; 570792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentResolver resolver = context.getContentResolver(); 571792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // need to determine the number of items currently in the playlist, 572792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // so the play_order field can be maintained. 573792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String[] cols = new String[] { 574792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project "count(*)" 575792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project }; 576792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", playlistid); 577792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor cur = resolver.query(uri, cols, null, null, null); 578792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cur.moveToFirst(); 579792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int base = cur.getInt(0); 580792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cur.close(); 581f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen int numinserted = 0; 582f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen for (int i = 0; i < size; i += 1000) { 583f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen makeInsertItems(ids, i, 1000, base); 584f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen numinserted += resolver.bulkInsert(uri, sContentValuesCache); 585792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 586792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String message = context.getResources().getQuantityString( 587f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen R.plurals.NNNtrackstoplaylist, numinserted, numinserted); 588792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); 589792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project //mLastPlaylistSelected = playlistid; 590792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 591792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 592792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 593792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static Cursor query(Context context, Uri uri, String[] projection, 5944248ed203f66145f8be7cda2cfd937ec450c9609Marco Nelissen String selection, String[] selectionArgs, String sortOrder, int limit) { 595792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 596792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentResolver resolver = context.getContentResolver(); 597792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (resolver == null) { 598792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return null; 599792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 6004248ed203f66145f8be7cda2cfd937ec450c9609Marco Nelissen if (limit > 0) { 6014248ed203f66145f8be7cda2cfd937ec450c9609Marco Nelissen uri = uri.buildUpon().appendQueryParameter("limit", "" + limit).build(); 6024248ed203f66145f8be7cda2cfd937ec450c9609Marco Nelissen } 603792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return resolver.query(uri, projection, selection, selectionArgs, sortOrder); 604792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (UnsupportedOperationException ex) { 605792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return null; 606792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 607792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 608792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 6094248ed203f66145f8be7cda2cfd937ec450c9609Marco Nelissen public static Cursor query(Context context, Uri uri, String[] projection, 6104248ed203f66145f8be7cda2cfd937ec450c9609Marco Nelissen String selection, String[] selectionArgs, String sortOrder) { 6114248ed203f66145f8be7cda2cfd937ec450c9609Marco Nelissen return query(context, uri, projection, selection, selectionArgs, sortOrder, 0); 6124248ed203f66145f8be7cda2cfd937ec450c9609Marco Nelissen } 613792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 614792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static boolean isMediaScannerScanning(Context context) { 615792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project boolean result = false; 616792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor cursor = query(context, MediaStore.getMediaScannerUri(), 617792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project new String [] { MediaStore.MEDIA_SCANNER_VOLUME }, null, null, null); 618792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cursor != null) { 619792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cursor.getCount() == 1) { 620792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cursor.moveToFirst(); 621792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project result = "external".equals(cursor.getString(0)); 622792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 623792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cursor.close(); 624792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 625792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 626792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return result; 627792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 628792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 629792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void setSpinnerState(Activity a) { 630792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (isMediaScannerScanning(a)) { 631792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // start the progress spinner 632792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project a.getWindow().setFeatureInt( 633792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Window.FEATURE_INDETERMINATE_PROGRESS, 634792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Window.PROGRESS_INDETERMINATE_ON); 635792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 636792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project a.getWindow().setFeatureInt( 637792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Window.FEATURE_INDETERMINATE_PROGRESS, 638792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Window.PROGRESS_VISIBILITY_ON); 639792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 640792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // stop the progress spinner 641792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project a.getWindow().setFeatureInt( 642792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Window.FEATURE_INDETERMINATE_PROGRESS, 643792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Window.PROGRESS_VISIBILITY_OFF); 644792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 645792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 646792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 6477a05298d5af6f796f3a260fa60b11d1c029b4207Marco Nelissen private static String mLastSdStatus; 6487a05298d5af6f796f3a260fa60b11d1c029b4207Marco Nelissen 649792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void displayDatabaseError(Activity a) { 65098b177710b6a9bb2de7498d68e10a0d7f53c2f06Marco Nelissen if (a.isFinishing()) { 65198b177710b6a9bb2de7498d68e10a0d7f53c2f06Marco Nelissen // When switching tabs really fast, we can end up with a null 65298b177710b6a9bb2de7498d68e10a0d7f53c2f06Marco Nelissen // cursor (not sure why), which will bring us here. 65398b177710b6a9bb2de7498d68e10a0d7f53c2f06Marco Nelissen // Don't bother showing an error message in that case. 65498b177710b6a9bb2de7498d68e10a0d7f53c2f06Marco Nelissen return; 65598b177710b6a9bb2de7498d68e10a0d7f53c2f06Marco Nelissen } 65698b177710b6a9bb2de7498d68e10a0d7f53c2f06Marco Nelissen 657792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String status = Environment.getExternalStorageState(); 658792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int title = R.string.sdcard_error_title; 659792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int message = R.string.sdcard_error_message; 660792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 661792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (status.equals(Environment.MEDIA_SHARED) || 662792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project status.equals(Environment.MEDIA_UNMOUNTED)) { 663792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project title = R.string.sdcard_busy_title; 664792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project message = R.string.sdcard_busy_message; 665792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (status.equals(Environment.MEDIA_REMOVED)) { 666792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project title = R.string.sdcard_missing_title; 667792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project message = R.string.sdcard_missing_message; 668792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (status.equals(Environment.MEDIA_MOUNTED)){ 669792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // The card is mounted, but we didn't get a valid cursor. 670792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // This probably means the mediascanner hasn't started scanning the 671792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // card yet (there is a small window of time during boot where this 672792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // will happen). 673792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project a.setTitle(""); 674792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Intent intent = new Intent(); 675792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project intent.setClass(a, ScanningProgress.class); 676792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project a.startActivityForResult(intent, Defs.SCAN_DONE); 6777a05298d5af6f796f3a260fa60b11d1c029b4207Marco Nelissen } else if (!TextUtils.equals(mLastSdStatus, status)) { 6787a05298d5af6f796f3a260fa60b11d1c029b4207Marco Nelissen mLastSdStatus = status; 679792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Log.d(TAG, "sd card: " + status); 680792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 681792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 682792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project a.setTitle(title); 683792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project View v = a.findViewById(R.id.sd_message); 684792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (v != null) { 685792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v.setVisibility(View.VISIBLE); 686792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 687792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v = a.findViewById(R.id.sd_icon); 688792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (v != null) { 689792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v.setVisibility(View.VISIBLE); 690792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 691792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v = a.findViewById(android.R.id.list); 692792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (v != null) { 693792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v.setVisibility(View.GONE); 694792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 6959e0f1fde0956ee7f5b76b77df7aea9b936e2c3a9Marco Nelissen v = a.findViewById(R.id.buttonbar); 6969e0f1fde0956ee7f5b76b77df7aea9b936e2c3a9Marco Nelissen if (v != null) { 6979e0f1fde0956ee7f5b76b77df7aea9b936e2c3a9Marco Nelissen v.setVisibility(View.GONE); 6989e0f1fde0956ee7f5b76b77df7aea9b936e2c3a9Marco Nelissen } 699792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project TextView tv = (TextView) a.findViewById(R.id.sd_message); 700792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project tv.setText(message); 701792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 702792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 703792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void hideDatabaseError(Activity a) { 704792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project View v = a.findViewById(R.id.sd_message); 705792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (v != null) { 706792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v.setVisibility(View.GONE); 707792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 708792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v = a.findViewById(R.id.sd_icon); 709792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (v != null) { 710792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v.setVisibility(View.GONE); 711792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 712792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v = a.findViewById(android.R.id.list); 713792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (v != null) { 714792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v.setVisibility(View.VISIBLE); 715792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 716792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 717792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 718792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static protected Uri getContentURIForPath(String path) { 719792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return Uri.fromFile(new File(path)); 720792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 721792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 722792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 723792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /* Try to use String.format() as little as possible, because it creates a 724792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * new Formatter every time you call it, which is very inefficient. 725792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Reusing an existing Formatter more than tripled the speed of 726792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * makeTimeString(). 727792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * This Formatter/StringBuilder are also used by makeAlbumSongsLabel() 728792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 729792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static StringBuilder sFormatBuilder = new StringBuilder(); 730792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static Formatter sFormatter = new Formatter(sFormatBuilder, Locale.getDefault()); 731792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static final Object[] sTimeArgs = new Object[5]; 732792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 733792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static String makeTimeString(Context context, long secs) { 7341e5a567390e41045cba6abac1d2c94eb8f59fc30Marco Nelissen String durationformat = context.getString( 7351e5a567390e41045cba6abac1d2c94eb8f59fc30Marco Nelissen secs < 3600 ? R.string.durationformatshort : R.string.durationformatlong); 736792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 737792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /* Provide multiple arguments so the format can be changed easily 738792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * by modifying the xml. 739792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 740792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sFormatBuilder.setLength(0); 741792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 742792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project final Object[] timeArgs = sTimeArgs; 743792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project timeArgs[0] = secs / 3600; 744792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project timeArgs[1] = secs / 60; 745792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project timeArgs[2] = (secs / 60) % 60; 746792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project timeArgs[3] = secs; 747792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project timeArgs[4] = secs % 60; 748792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 749792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return sFormatter.format(durationformat, timeArgs).toString(); 750792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 751792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 752792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void shuffleAll(Context context, Cursor cursor) { 753792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project playAll(context, cursor, 0, true); 754792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 755792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 756792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void playAll(Context context, Cursor cursor) { 757792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project playAll(context, cursor, 0, false); 758792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 759792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 760792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void playAll(Context context, Cursor cursor, int position) { 761792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project playAll(context, cursor, position, false); 762792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 763792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 764bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static void playAll(Context context, long [] list, int position) { 765792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project playAll(context, list, position, false); 766792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 767792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 768792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static void playAll(Context context, Cursor cursor, int position, boolean force_shuffle) { 769792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 770bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long [] list = getSongListForCursor(cursor); 771792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project playAll(context, list, position, force_shuffle); 772792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 773792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 774bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen private static void playAll(Context context, long [] list, int position, boolean force_shuffle) { 775792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (list.length == 0 || sService == null) { 776792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Log.d("MusicUtils", "attempt to play empty song list"); 777792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Don't try to play empty playlists. Nothing good will come of it. 778792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String message = context.getString(R.string.emptyplaylist, list.length); 779792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); 780792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 781792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 782792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 783792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (force_shuffle) { 784792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sService.setShuffleMode(MediaPlaybackService.SHUFFLE_NORMAL); 785792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 786bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long curid = sService.getAudioId(); 787792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int curpos = sService.getQueuePosition(); 788792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (position != -1 && curpos == position && curid == list[position]) { 789792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // The selected file is the file that's currently playing; 790792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // figure out if we need to restart with a new playlist, 791792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // or just launch the playback activity. 792bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen long [] playlist = sService.getQueue(); 793792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (Arrays.equals(list, playlist)) { 794792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // we don't need to set a new list, but we should resume playback if needed 795792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sService.play(); 796792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; // the 'finally' block will still run 797792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 798792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 799792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (position < 0) { 800792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project position = 0; 801792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 802792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sService.open(list, force_shuffle ? -1 : position); 803792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sService.play(); 804792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RemoteException ex) { 805792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } finally { 806ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen Intent intent = new Intent(context, MediaPlaybackActivity.class) 807792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 808792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project context.startActivity(intent); 809792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 810792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 811792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 812792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void clearQueue() { 813792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 814792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sService.removeTracks(0, Integer.MAX_VALUE); 815792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RemoteException ex) { 816792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 817792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 818792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 819792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // A really simple BitmapDrawable-like class, that doesn't do 820792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // scaling, dithering or filtering. 821792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static class FastBitmapDrawable extends Drawable { 822792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private Bitmap mBitmap; 823792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public FastBitmapDrawable(Bitmap b) { 824792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mBitmap = b; 825792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 826792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 827792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void draw(Canvas canvas) { 828792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project canvas.drawBitmap(mBitmap, 0, 0, null); 829792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 830792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 831792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int getOpacity() { 832792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return PixelFormat.OPAQUE; 833792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 834792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 835792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void setAlpha(int alpha) { 836792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 837792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 838792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void setColorFilter(ColorFilter cf) { 839792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 840792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 841792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 842792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static int sArtId = -2; 843792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static Bitmap mCachedBit = null; 844792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static final BitmapFactory.Options sBitmapOptionsCache = new BitmapFactory.Options(); 845792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static final BitmapFactory.Options sBitmapOptions = new BitmapFactory.Options(); 846792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart"); 847bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen private static final HashMap<Long, Drawable> sArtCache = new HashMap<Long, Drawable>(); 848792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static int sArtCacheId = -1; 849792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 850792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static { 851792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // for the cache, 852792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // 565 is faster to decode and display 853792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // and we don't want to dither here because the image will be scaled down later 854792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sBitmapOptionsCache.inPreferredConfig = Bitmap.Config.RGB_565; 855792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sBitmapOptionsCache.inDither = false; 856792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 857792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565; 858792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sBitmapOptions.inDither = false; 859792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 860792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 861792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void initAlbumArtCache() { 862792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 863792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int id = sService.getMediaMountedCount(); 864792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (id != sArtCacheId) { 865792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project clearAlbumArtCache(); 866792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sArtCacheId = id; 867792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 868792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RemoteException e) { 869792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project e.printStackTrace(); 870792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 871792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 872792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 873792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static void clearAlbumArtCache() { 874792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized(sArtCache) { 875792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sArtCache.clear(); 876792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 877792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 878792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 879bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static Drawable getCachedArtwork(Context context, long artIndex, BitmapDrawable defaultArtwork) { 880792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Drawable d = null; 881792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized(sArtCache) { 882792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project d = sArtCache.get(artIndex); 883792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 884792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (d == null) { 885792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project d = defaultArtwork; 886792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project final Bitmap icon = defaultArtwork.getBitmap(); 887792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int w = icon.getWidth(); 888792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int h = icon.getHeight(); 889792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Bitmap b = MusicUtils.getArtworkQuick(context, artIndex, w, h); 890792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (b != null) { 891792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project d = new FastBitmapDrawable(b); 892792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized(sArtCache) { 893792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // the cache may have changed since we checked 894792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Drawable value = sArtCache.get(artIndex); 895792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (value == null) { 896792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sArtCache.put(artIndex, d); 897792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 898792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project d = value; 899792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 900792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 901792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 902792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 903792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return d; 904792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 905792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 906792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Get album art for specified album. This method will not try to 907792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // fall back to getting artwork directly from the file, nor will 908792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // it attempt to repair the database. 909bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen private static Bitmap getArtworkQuick(Context context, long album_id, int w, int h) { 910792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // NOTE: There is in fact a 1 pixel border on the right side in the ImageView 911792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // used to display this drawable. Take it into account now, so we don't have to 912792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // scale later. 913792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project w -= 1; 914792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentResolver res = context.getContentResolver(); 915792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id); 916792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (uri != null) { 917792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ParcelFileDescriptor fd = null; 918792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 919792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project fd = res.openFileDescriptor(uri, "r"); 920792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int sampleSize = 1; 921792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 922792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Compute the closest power-of-two scale factor 923792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // and pass that to sBitmapOptionsCache.inSampleSize, which will 924792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // result in faster decoding and better quality 925792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sBitmapOptionsCache.inJustDecodeBounds = true; 926792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project BitmapFactory.decodeFileDescriptor( 927792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project fd.getFileDescriptor(), null, sBitmapOptionsCache); 928792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int nextWidth = sBitmapOptionsCache.outWidth >> 1; 929792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int nextHeight = sBitmapOptionsCache.outHeight >> 1; 930792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project while (nextWidth>w && nextHeight>h) { 931792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sampleSize <<= 1; 932792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project nextWidth >>= 1; 933792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project nextHeight >>= 1; 934792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 935792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 936792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sBitmapOptionsCache.inSampleSize = sampleSize; 937792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sBitmapOptionsCache.inJustDecodeBounds = false; 938792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Bitmap b = BitmapFactory.decodeFileDescriptor( 939792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project fd.getFileDescriptor(), null, sBitmapOptionsCache); 940792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 941792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (b != null) { 942792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // finally rescale to exactly the size we need 943792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (sBitmapOptionsCache.outWidth != w || sBitmapOptionsCache.outHeight != h) { 944792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Bitmap tmp = Bitmap.createScaledBitmap(b, w, h, true); 945792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Bitmap.createScaledBitmap() can return the same bitmap 946792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (tmp != b) b.recycle(); 947792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project b = tmp; 948792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 949792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 950792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 951792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return b; 952792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (FileNotFoundException e) { 953792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } finally { 954792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 955792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (fd != null) 956792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project fd.close(); 957792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (IOException e) { 958792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 959792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 960792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 961792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return null; 962792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 9633193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen 964792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Get album art for specified album. You should not pass in the album id 965792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * for the "unknown" album here (use -1 instead) 9663193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen * This method always returns the default album art icon when no album art is found. 967792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 968bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen public static Bitmap getArtwork(Context context, long song_id, long album_id) { 9693193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen return getArtwork(context, song_id, album_id, true); 9703193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen } 9713193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen 9723193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen /** Get album art for specified album. You should not pass in the album id 9733193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen * for the "unknown" album here (use -1 instead) 9743193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen */ 9753193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen public static Bitmap getArtwork(Context context, long song_id, long album_id, 9763193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen boolean allowdefault) { 977792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 978792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (album_id < 0) { 979792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // This is something that is not in the database, so get the album art directly 980792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // from the file. 9817a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen if (song_id >= 0) { 9827a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen Bitmap bm = getArtworkFromFile(context, song_id, -1); 9837a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen if (bm != null) { 9847a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen return bm; 9857a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen } 986792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 9873193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen if (allowdefault) { 9883193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen return getDefaultArtwork(context); 9893193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen } 9903193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen return null; 991792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 992792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 993792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentResolver res = context.getContentResolver(); 994792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id); 995792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (uri != null) { 996792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project InputStream in = null; 997792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 998792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project in = res.openInputStream(uri); 999792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return BitmapFactory.decodeStream(in, null, sBitmapOptions); 1000792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (FileNotFoundException ex) { 1001792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // The album art thumbnail does not actually exist. Maybe the user deleted it, or 1002792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // maybe it never existed to begin with. 10037a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen Bitmap bm = getArtworkFromFile(context, song_id, album_id); 1004792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (bm != null) { 1005756c3f57f11a7bb3bf1cf1333ee8ffbc51039748Marco Nelissen if (bm.getConfig() == null) { 1006756c3f57f11a7bb3bf1cf1333ee8ffbc51039748Marco Nelissen bm = bm.copy(Bitmap.Config.RGB_565, false); 10073193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen if (bm == null && allowdefault) { 10087a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen return getDefaultArtwork(context); 1009792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1010792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 10113193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen } else if (allowdefault) { 10127a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen bm = getDefaultArtwork(context); 1013792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1014792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return bm; 1015792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } finally { 1016792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 1017792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (in != null) { 1018792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project in.close(); 1019792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1020792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (IOException ex) { 1021792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1022792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1023792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1024792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1025792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return null; 1026792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1027792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1028792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // get album art for specified file 1029792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static final String sExternalMediaUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI.toString(); 1030bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen private static Bitmap getArtworkFromFile(Context context, long songid, long albumid) { 1031792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Bitmap bm = null; 1032792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project byte [] art = null; 1033792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String path = null; 1034792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 10357a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen if (albumid < 0 && songid < 0) { 10367a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen throw new IllegalArgumentException("Must specify an album or a song id"); 1037792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 10387a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen 10397a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen try { 10407a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen if (albumid < 0) { 10417a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen Uri uri = Uri.parse("content://media/external/audio/media/" + songid + "/albumart"); 10427a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r"); 10437a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen if (pfd != null) { 10447a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen FileDescriptor fd = pfd.getFileDescriptor(); 10457a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen bm = BitmapFactory.decodeFileDescriptor(fd); 1046792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 10477a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen } else { 10487a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen Uri uri = ContentUris.withAppendedId(sArtworkUri, albumid); 10497a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r"); 10507a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen if (pfd != null) { 10517a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen FileDescriptor fd = pfd.getFileDescriptor(); 10527a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen bm = BitmapFactory.decodeFileDescriptor(fd); 1053792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1054792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 10557a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen } catch (FileNotFoundException ex) { 10567a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen // 1057792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 10587a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen if (bm != null) { 10597a16cc726fd83eff0095f3f82364d1438773218fMarco Nelissen mCachedBit = bm; 1060792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1061792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return bm; 1062792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1063792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1064792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static Bitmap getDefaultArtwork(Context context) { 1065792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project BitmapFactory.Options opts = new BitmapFactory.Options(); 1066792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project opts.inPreferredConfig = Bitmap.Config.ARGB_8888; 1067792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return BitmapFactory.decodeStream( 1068792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project context.getResources().openRawResource(R.drawable.albumart_mp_unknown), null, opts); 1069792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1070792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1071792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static int getIntPref(Context context, String name, int def) { 1072792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project SharedPreferences prefs = 1073792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project context.getSharedPreferences("com.android.music", Context.MODE_PRIVATE); 1074792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return prefs.getInt(name, def); 1075792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1076792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1077792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static void setIntPref(Context context, String name, int value) { 1078792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project SharedPreferences prefs = 1079792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project context.getSharedPreferences("com.android.music", Context.MODE_PRIVATE); 1080792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Editor ed = prefs.edit(); 1081792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ed.putInt(name, value); 1082792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ed.commit(); 1083792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1084792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1085792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static void setRingtone(Context context, long id) { 1086792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentResolver resolver = context.getContentResolver(); 1087792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Set the flag in the database to mark this as a ringtone 1088792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Uri ringUri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id); 1089792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 1090792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentValues values = new ContentValues(2); 1091792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project values.put(MediaStore.Audio.Media.IS_RINGTONE, "1"); 1092792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project values.put(MediaStore.Audio.Media.IS_ALARM, "1"); 1093792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project resolver.update(ringUri, values, null, null); 1094792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (UnsupportedOperationException ex) { 1095792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // most likely the card just got unmounted 1096792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Log.e(TAG, "couldn't set ringtone flag for id " + id); 1097792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 1098792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1099792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1100792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String[] cols = new String[] { 1101792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media._ID, 1102792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.DATA, 1103792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.TITLE 1104792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project }; 1105792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1106792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String where = MediaStore.Audio.Media._ID + "=" + id; 1107792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor cursor = query(context, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 1108792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cols, where , null, null); 1109792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 1110792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cursor != null && cursor.getCount() == 1) { 1111792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Set the system setting to make this the current ringtone 1112792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cursor.moveToFirst(); 1113792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Settings.System.putString(resolver, Settings.System.RINGTONE, ringUri.toString()); 1114792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String message = context.getString(R.string.ringtone_set, cursor.getString(2)); 1115792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); 1116792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1117792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } finally { 1118792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cursor != null) { 1119792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cursor.close(); 1120792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1121792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1122792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1123ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 1124ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen static int sActiveTabIndex = -1; 1125ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 112619cea9e16c54364a6a1df53cd617ba0a9c65b386Marco Nelissen static boolean updateButtonBar(Activity a, int highlight) { 1127ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen final TabWidget ll = (TabWidget) a.findViewById(R.id.buttonbar); 1128ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen boolean withtabs = false; 1129ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen Intent intent = a.getIntent(); 1130ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (intent != null) { 1131ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen withtabs = intent.getBooleanExtra("withtabs", false); 1132ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1133ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 1134ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (highlight == 0 || !withtabs) { 1135ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen ll.setVisibility(View.GONE); 113619cea9e16c54364a6a1df53cd617ba0a9c65b386Marco Nelissen return withtabs; 1137ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } else if (withtabs) { 1138ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen ll.setVisibility(View.VISIBLE); 1139ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1140ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen for (int i = ll.getChildCount() - 1; i >= 0; i--) { 1141ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 1142ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen View v = ll.getChildAt(i); 1143ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen boolean isActive = (v.getId() == highlight); 1144ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (isActive) { 1145ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen ll.setCurrentTab(i); 1146ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen sActiveTabIndex = i; 1147ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1148333bf1945f859968dcb9783b694aa64b788fc771Jeff Hamilton v.setTag(i); 1149ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen v.setOnFocusChangeListener(new View.OnFocusChangeListener() { 1150ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 1151ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen public void onFocusChange(View v, boolean hasFocus) { 1152ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (hasFocus) { 1153ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen for (int i = 0; i < ll.getTabCount(); i++) { 1154ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (ll.getChildTabViewAt(i) == v) { 1155ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen ll.setCurrentTab(i); 1156ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen processTabClick((Activity)ll.getContext(), v, ll.getChildAt(sActiveTabIndex).getId()); 1157ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen break; 1158ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1159ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1160ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1161ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen }}); 1162ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 1163ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen v.setOnClickListener(new View.OnClickListener() { 1164ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 1165ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen public void onClick(View v) { 1166ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen processTabClick((Activity)ll.getContext(), v, ll.getChildAt(sActiveTabIndex).getId()); 1167ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen }}); 1168ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 116919cea9e16c54364a6a1df53cd617ba0a9c65b386Marco Nelissen return withtabs; 1170ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1171ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 1172ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen static void processTabClick(Activity a, View v, int current) { 1173ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen int id = v.getId(); 1174ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (id == current) { 1175ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen return; 1176ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1177333bf1945f859968dcb9783b694aa64b788fc771Jeff Hamilton 1178333bf1945f859968dcb9783b694aa64b788fc771Jeff Hamilton final TabWidget ll = (TabWidget) a.findViewById(R.id.buttonbar); 1179333bf1945f859968dcb9783b694aa64b788fc771Jeff Hamilton ll.setCurrentTab((Integer) v.getTag()); 1180333bf1945f859968dcb9783b694aa64b788fc771Jeff Hamilton 1181ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen activateTab(a, id); 1182ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (id != R.id.nowplayingtab) { 1183ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen setIntPref(a, "activetab", id); 1184ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1185ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1186ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 1187ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen static void activateTab(Activity a, int id) { 1188ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen Intent intent = new Intent(Intent.ACTION_PICK); 1189ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen switch (id) { 1190ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen case R.id.artisttab: 1191ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/artistalbum"); 1192ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen break; 1193ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen case R.id.albumtab: 1194ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/album"); 1195ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen break; 1196ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen case R.id.songtab: 1197ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/track"); 1198ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen break; 1199ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen case R.id.playlisttab: 1200ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen intent.setDataAndType(Uri.EMPTY, MediaStore.Audio.Playlists.CONTENT_TYPE); 1201ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen break; 1202ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen case R.id.nowplayingtab: 1203ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen intent = new Intent(a, MediaPlaybackActivity.class); 1204ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen a.startActivity(intent); 1205ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen // fall through and return 1206ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen default: 1207ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen return; 1208ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1209ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen intent.putExtra("withtabs", true); 1210ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 1211ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen a.startActivity(intent); 1212ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen a.finish(); 1213ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen a.overridePendingTransition(0, 0); 1214ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1215ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 1216ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen static void updateNowPlaying(Activity a) { 1217ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen View nowPlayingView = a.findViewById(R.id.nowplaying); 1218ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (nowPlayingView == null) { 1219ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen return; 1220ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1221ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen try { 1222ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen boolean withtabs = false; 1223ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen Intent intent = a.getIntent(); 1224ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (intent != null) { 1225ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen withtabs = intent.getBooleanExtra("withtabs", false); 1226ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1227ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen if (true && MusicUtils.sService != null && MusicUtils.sService.getAudioId() != -1) { 1228ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen TextView title = (TextView) nowPlayingView.findViewById(R.id.title); 1229ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen TextView artist = (TextView) nowPlayingView.findViewById(R.id.artist); 1230ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen title.setText(MusicUtils.sService.getTrackName()); 1231ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen String artistName = MusicUtils.sService.getArtistName(); 1232f4d4b342061ade12eb7903f454df62814179906fMarco Nelissen if (MediaStore.UNKNOWN_STRING.equals(artistName)) { 1233ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen artistName = a.getString(R.string.unknown_artist_name); 1234ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1235ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen artist.setText(artistName); 1236ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen //mNowPlayingView.setOnFocusChangeListener(mFocuser); 1237ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen //mNowPlayingView.setOnClickListener(this); 1238ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen nowPlayingView.setVisibility(View.VISIBLE); 1239ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen nowPlayingView.setOnClickListener(new View.OnClickListener() { 1240ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 1241ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen public void onClick(View v) { 1242ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen Context c = v.getContext(); 1243ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen c.startActivity(new Intent(c, MediaPlaybackActivity.class)); 1244ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen }}); 1245ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen return; 1246ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1247ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } catch (RemoteException ex) { 1248ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1249ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen nowPlayingView.setVisibility(View.GONE); 1250ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen } 1251ec0c57a414c3563ebbf5767d92787a6a3f4a8820Marco Nelissen 12523193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen static void setBackground(View v, Bitmap bm) { 12533193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen 12543193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen if (bm == null) { 12553193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen v.setBackgroundResource(0); 12563193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen return; 12573193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen } 12583193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen 12593193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen int vwidth = v.getWidth(); 12603193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen int vheight = v.getHeight(); 12613193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen int bwidth = bm.getWidth(); 12623193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen int bheight = bm.getHeight(); 12633193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen float scalex = (float) vwidth / bwidth; 12643193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen float scaley = (float) vheight / bheight; 12653193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen float scale = Math.max(scalex, scaley) * 1.3f; 12663193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen 12673193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen Bitmap.Config config = Bitmap.Config.ARGB_8888; 12683193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen Bitmap bg = Bitmap.createBitmap(vwidth, vheight, config); 12693193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen Canvas c = new Canvas(bg); 12703193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen Paint paint = new Paint(); 12713193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen paint.setAntiAlias(true); 12723193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen paint.setFilterBitmap(true); 12733193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen ColorMatrix greymatrix = new ColorMatrix(); 12743193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen greymatrix.setSaturation(0); 12753193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen ColorMatrix darkmatrix = new ColorMatrix(); 12763193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen darkmatrix.setScale(.3f, .3f, .3f, 1.0f); 12773193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen greymatrix.postConcat(darkmatrix); 12783193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen ColorFilter filter = new ColorMatrixColorFilter(greymatrix); 12793193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen paint.setColorFilter(filter); 12803193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen Matrix matrix = new Matrix(); 12813193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen matrix.setTranslate(-bwidth/2, -bheight/2); // move bitmap center to origin 12823193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen matrix.postRotate(10); 12833193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen matrix.postScale(scale, scale); 12843193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen matrix.postTranslate(vwidth/2, vheight/2); // Move bitmap center to view center 12853193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen c.drawBitmap(bm, matrix, paint); 12863193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen v.setBackgroundDrawable(new BitmapDrawable(bg)); 12873193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen } 12883193d7dda28d5c31b318b024db4df40b949071d5Marco Nelissen 128987bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen static int getCardId(Context context) { 129087bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen ContentResolver res = context.getContentResolver(); 129187bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen Cursor c = res.query(Uri.parse("content://media/external/fs_id"), null, null, null, null); 129287bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen int id = -1; 129387bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen if (c != null) { 129487bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen c.moveToFirst(); 129587bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen id = c.getInt(0); 129687bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen c.close(); 129787bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen } 129887bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen return id; 129987bbf3c40cd044c3daa9fad28fb94e8570fcae05Marco Nelissen } 1300792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project} 1301