AlbumBrowserActivity.java revision 23b531ec31c406f96fca82bfb9b04e26d05187b4
1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.music; 18 19import android.app.ListActivity; 20import android.app.SearchManager; 21import android.content.AsyncQueryHandler; 22import android.content.BroadcastReceiver; 23import android.content.ComponentName; 24import android.content.ContentResolver; 25import android.content.Context; 26import android.content.Intent; 27import android.content.IntentFilter; 28import android.content.ServiceConnection; 29import android.content.res.Resources; 30import android.database.Cursor; 31import android.graphics.Bitmap; 32import android.graphics.BitmapFactory; 33import android.graphics.drawable.BitmapDrawable; 34import android.graphics.drawable.Drawable; 35import android.media.AudioManager; 36import android.media.MediaFile; 37import android.net.Uri; 38import android.os.Bundle; 39import android.os.Handler; 40import android.os.IBinder; 41import android.os.Message; 42import android.provider.MediaStore; 43import android.util.Log; 44import android.view.ContextMenu; 45import android.view.Menu; 46import android.view.MenuItem; 47import android.view.SubMenu; 48import android.view.View; 49import android.view.ViewGroup; 50import android.view.Window; 51import android.view.ContextMenu.ContextMenuInfo; 52import android.widget.Adapter; 53import android.widget.AlphabetIndexer; 54import android.widget.CursorAdapter; 55import android.widget.ExpandableListView; 56import android.widget.ImageView; 57import android.widget.ListAdapter; 58import android.widget.ListView; 59import android.widget.SectionIndexer; 60import android.widget.SimpleCursorAdapter; 61import android.widget.TextView; 62import android.widget.AdapterView.AdapterContextMenuInfo; 63 64import java.text.Collator; 65 66public class AlbumBrowserActivity extends ListActivity 67 implements View.OnCreateContextMenuListener, MusicUtils.Defs, ServiceConnection 68{ 69 private String mCurrentAlbumId; 70 private String mCurrentAlbumName; 71 private String mCurrentArtistNameForAlbum; 72 boolean mIsUnknownArtist; 73 boolean mIsUnknownAlbum; 74 private AlbumListAdapter mAdapter; 75 private boolean mAdapterSent; 76 private final static int SEARCH = CHILD_MENU_BASE; 77 private static int mLastListPosCourse = -1; 78 private static int mLastListPosFine = -1; 79 80 public AlbumBrowserActivity() 81 { 82 } 83 84 /** Called when the activity is first created. */ 85 @Override 86 public void onCreate(Bundle icicle) 87 { 88 if (icicle != null) { 89 mCurrentAlbumId = icicle.getString("selectedalbum"); 90 mArtistId = icicle.getString("artist"); 91 } else { 92 mArtistId = getIntent().getStringExtra("artist"); 93 } 94 super.onCreate(icicle); 95 requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); 96 requestWindowFeature(Window.FEATURE_NO_TITLE); 97 setVolumeControlStream(AudioManager.STREAM_MUSIC); 98 MusicUtils.bindToService(this, this); 99 100 IntentFilter f = new IntentFilter(); 101 f.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED); 102 f.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED); 103 f.addAction(Intent.ACTION_MEDIA_UNMOUNTED); 104 f.addDataScheme("file"); 105 registerReceiver(mScanListener, f); 106 107 setContentView(R.layout.media_picker_activity); 108 MusicUtils.updateButtonBar(this, R.id.albumtab); 109 ListView lv = getListView(); 110 lv.setOnCreateContextMenuListener(this); 111 lv.setTextFilterEnabled(true); 112 113 mAdapter = (AlbumListAdapter) getLastNonConfigurationInstance(); 114 if (mAdapter == null) { 115 //Log.i("@@@", "starting query"); 116 mAdapter = new AlbumListAdapter( 117 getApplication(), 118 this, 119 R.layout.track_list_item, 120 mAlbumCursor, 121 new String[] {}, 122 new int[] {}); 123 setListAdapter(mAdapter); 124 setTitle(R.string.working_albums); 125 getAlbumCursor(mAdapter.getQueryHandler(), null); 126 } else { 127 mAdapter.setActivity(this); 128 setListAdapter(mAdapter); 129 mAlbumCursor = mAdapter.getCursor(); 130 if (mAlbumCursor != null) { 131 init(mAlbumCursor); 132 } else { 133 getAlbumCursor(mAdapter.getQueryHandler(), null); 134 } 135 } 136 } 137 138 @Override 139 public Object onRetainNonConfigurationInstance() { 140 mAdapterSent = true; 141 return mAdapter; 142 } 143 144 @Override 145 public void onSaveInstanceState(Bundle outcicle) { 146 // need to store the selected item so we don't lose it in case 147 // of an orientation switch. Otherwise we could lose it while 148 // in the middle of specifying a playlist to add the item to. 149 outcicle.putString("selectedalbum", mCurrentAlbumId); 150 outcicle.putString("artist", mArtistId); 151 super.onSaveInstanceState(outcicle); 152 } 153 154 @Override 155 public void onDestroy() { 156 ListView lv = getListView(); 157 if (lv != null) { 158 mLastListPosCourse = lv.getFirstVisiblePosition(); 159 View cv = lv.getChildAt(0); 160 if (cv != null) { 161 mLastListPosFine = cv.getTop(); 162 } 163 } 164 MusicUtils.unbindFromService(this); 165 if (!mAdapterSent) { 166 Cursor c = mAdapter.getCursor(); 167 if (c != null) { 168 c.close(); 169 } 170 } 171 // Because we pass the adapter to the next activity, we need to make 172 // sure it doesn't keep a reference to this activity. We can do this 173 // by clearing its DatasetObservers, which setListAdapter(null) does. 174 setListAdapter(null); 175 mAdapter = null; 176 unregisterReceiver(mScanListener); 177 super.onDestroy(); 178 } 179 180 @Override 181 public void onResume() { 182 super.onResume(); 183 IntentFilter f = new IntentFilter(); 184 f.addAction(MediaPlaybackService.META_CHANGED); 185 f.addAction(MediaPlaybackService.QUEUE_CHANGED); 186 registerReceiver(mTrackListListener, f); 187 mTrackListListener.onReceive(null, null); 188 189 MusicUtils.setSpinnerState(this); 190 } 191 192 private BroadcastReceiver mTrackListListener = new BroadcastReceiver() { 193 @Override 194 public void onReceive(Context context, Intent intent) { 195 getListView().invalidateViews(); 196 MusicUtils.updateNowPlaying(AlbumBrowserActivity.this); 197 } 198 }; 199 private BroadcastReceiver mScanListener = new BroadcastReceiver() { 200 @Override 201 public void onReceive(Context context, Intent intent) { 202 MusicUtils.setSpinnerState(AlbumBrowserActivity.this); 203 mReScanHandler.sendEmptyMessage(0); 204 if (intent.getAction().equals(Intent.ACTION_MEDIA_UNMOUNTED)) { 205 MusicUtils.clearAlbumArtCache(); 206 } 207 } 208 }; 209 210 private Handler mReScanHandler = new Handler() { 211 @Override 212 public void handleMessage(Message msg) { 213 if (mAdapter != null) { 214 getAlbumCursor(mAdapter.getQueryHandler(), null); 215 } 216 } 217 }; 218 219 @Override 220 public void onPause() { 221 unregisterReceiver(mTrackListListener); 222 mReScanHandler.removeCallbacksAndMessages(null); 223 super.onPause(); 224 } 225 226 public void init(Cursor c) { 227 228 if (mAdapter == null) { 229 return; 230 } 231 mAdapter.changeCursor(c); // also sets mAlbumCursor 232 233 if (mAlbumCursor == null) { 234 MusicUtils.displayDatabaseError(this); 235 closeContextMenu(); 236 mReScanHandler.sendEmptyMessageDelayed(0, 1000); 237 return; 238 } 239 240 // restore previous position 241 if (mLastListPosCourse >= 0) { 242 getListView().setSelectionFromTop(mLastListPosCourse, mLastListPosFine); 243 mLastListPosCourse = -1; 244 } 245 246 MusicUtils.hideDatabaseError(this); 247 MusicUtils.updateButtonBar(this, R.id.albumtab); 248 setTitle(); 249 } 250 251 private void setTitle() { 252 CharSequence fancyName = ""; 253 if (mAlbumCursor != null && mAlbumCursor.getCount() > 0) { 254 mAlbumCursor.moveToFirst(); 255 fancyName = mAlbumCursor.getString( 256 mAlbumCursor.getColumnIndex(MediaStore.Audio.Albums.ARTIST)); 257 if (fancyName == null || fancyName.equals(MediaFile.UNKNOWN_STRING)) 258 fancyName = getText(R.string.unknown_artist_name); 259 } 260 261 if (mArtistId != null && fancyName != null) 262 setTitle(fancyName); 263 else 264 setTitle(R.string.albums_title); 265 } 266 267 @Override 268 public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfoIn) { 269 menu.add(0, PLAY_SELECTION, 0, R.string.play_selection); 270 SubMenu sub = menu.addSubMenu(0, ADD_TO_PLAYLIST, 0, R.string.add_to_playlist); 271 MusicUtils.makePlaylistMenu(this, sub); 272 menu.add(0, DELETE_ITEM, 0, R.string.delete_item); 273 274 AdapterContextMenuInfo mi = (AdapterContextMenuInfo) menuInfoIn; 275 mAlbumCursor.moveToPosition(mi.position); 276 mCurrentAlbumId = mAlbumCursor.getString(mAlbumCursor.getColumnIndexOrThrow(MediaStore.Audio.Albums._ID)); 277 mCurrentAlbumName = mAlbumCursor.getString(mAlbumCursor.getColumnIndexOrThrow(MediaStore.Audio.Albums.ALBUM)); 278 mCurrentArtistNameForAlbum = mAlbumCursor.getString( 279 mAlbumCursor.getColumnIndexOrThrow(MediaStore.Audio.Albums.ARTIST)); 280 mIsUnknownArtist = mCurrentArtistNameForAlbum == null || 281 mCurrentArtistNameForAlbum.equals(MediaFile.UNKNOWN_STRING); 282 mIsUnknownAlbum = mCurrentAlbumName == null || 283 mCurrentAlbumName.equals(MediaFile.UNKNOWN_STRING); 284 if (mIsUnknownAlbum) { 285 menu.setHeaderTitle(getString(R.string.unknown_album_name)); 286 } else { 287 menu.setHeaderTitle(mCurrentAlbumName); 288 } 289 if (!mIsUnknownAlbum || !mIsUnknownArtist) { 290 menu.add(0, SEARCH, 0, R.string.search_title); 291 } 292 } 293 294 @Override 295 public boolean onContextItemSelected(MenuItem item) { 296 switch (item.getItemId()) { 297 case PLAY_SELECTION: { 298 // play the selected album 299 long [] list = MusicUtils.getSongListForAlbum(this, Long.parseLong(mCurrentAlbumId)); 300 MusicUtils.playAll(this, list, 0); 301 return true; 302 } 303 304 case QUEUE: { 305 long [] list = MusicUtils.getSongListForAlbum(this, Long.parseLong(mCurrentAlbumId)); 306 MusicUtils.addToCurrentPlaylist(this, list); 307 return true; 308 } 309 310 case NEW_PLAYLIST: { 311 Intent intent = new Intent(); 312 intent.setClass(this, CreatePlaylist.class); 313 startActivityForResult(intent, NEW_PLAYLIST); 314 return true; 315 } 316 317 case PLAYLIST_SELECTED: { 318 long [] list = MusicUtils.getSongListForAlbum(this, Long.parseLong(mCurrentAlbumId)); 319 long playlist = item.getIntent().getLongExtra("playlist", 0); 320 MusicUtils.addToPlaylist(this, list, playlist); 321 return true; 322 } 323 case DELETE_ITEM: { 324 long [] list = MusicUtils.getSongListForAlbum(this, Long.parseLong(mCurrentAlbumId)); 325 String f = getString(R.string.delete_album_desc); 326 String desc = String.format(f, mCurrentAlbumName); 327 Bundle b = new Bundle(); 328 b.putString("description", desc); 329 b.putLongArray("items", list); 330 Intent intent = new Intent(); 331 intent.setClass(this, DeleteItems.class); 332 intent.putExtras(b); 333 startActivityForResult(intent, -1); 334 return true; 335 } 336 case SEARCH: 337 doSearch(); 338 return true; 339 340 } 341 return super.onContextItemSelected(item); 342 } 343 344 void doSearch() { 345 CharSequence title = null; 346 String query = ""; 347 348 Intent i = new Intent(); 349 i.setAction(MediaStore.INTENT_ACTION_MEDIA_SEARCH); 350 i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 351 352 title = ""; 353 if (!mIsUnknownAlbum) { 354 query = mCurrentAlbumName; 355 i.putExtra(MediaStore.EXTRA_MEDIA_ALBUM, mCurrentAlbumName); 356 title = mCurrentAlbumName; 357 } 358 if(!mIsUnknownArtist) { 359 query = query + " " + mCurrentArtistNameForAlbum; 360 i.putExtra(MediaStore.EXTRA_MEDIA_ARTIST, mCurrentArtistNameForAlbum); 361 title = title + " " + mCurrentArtistNameForAlbum; 362 } 363 // Since we hide the 'search' menu item when both album and artist are 364 // unknown, the query and title strings will have at least one of those. 365 i.putExtra(MediaStore.EXTRA_MEDIA_FOCUS, MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE); 366 title = getString(R.string.mediasearch, title); 367 i.putExtra(SearchManager.QUERY, query); 368 369 startActivity(Intent.createChooser(i, title)); 370 } 371 372 @Override 373 protected void onActivityResult(int requestCode, int resultCode, Intent intent) { 374 switch (requestCode) { 375 case SCAN_DONE: 376 if (resultCode == RESULT_CANCELED) { 377 finish(); 378 } else { 379 getAlbumCursor(mAdapter.getQueryHandler(), null); 380 } 381 break; 382 383 case NEW_PLAYLIST: 384 if (resultCode == RESULT_OK) { 385 Uri uri = intent.getData(); 386 if (uri != null) { 387 long [] list = MusicUtils.getSongListForAlbum(this, Long.parseLong(mCurrentAlbumId)); 388 MusicUtils.addToPlaylist(this, list, Long.parseLong(uri.getLastPathSegment())); 389 } 390 } 391 break; 392 } 393 } 394 395 @Override 396 protected void onListItemClick(ListView l, View v, int position, long id) 397 { 398 Intent intent = new Intent(Intent.ACTION_PICK); 399 intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/track"); 400 intent.putExtra("album", Long.valueOf(id).toString()); 401 intent.putExtra("artist", mArtistId); 402 startActivity(intent); 403 } 404 405 @Override 406 public boolean onCreateOptionsMenu(Menu menu) { 407 super.onCreateOptionsMenu(menu); 408 menu.add(0, PARTY_SHUFFLE, 0, R.string.party_shuffle); // icon will be set in onPrepareOptionsMenu() 409 menu.add(0, SHUFFLE_ALL, 0, R.string.shuffle_all).setIcon(R.drawable.ic_menu_shuffle); 410 return true; 411 } 412 413 @Override 414 public boolean onPrepareOptionsMenu(Menu menu) { 415 MusicUtils.setPartyShuffleMenuIcon(menu); 416 return super.onPrepareOptionsMenu(menu); 417 } 418 419 @Override 420 public boolean onOptionsItemSelected(MenuItem item) { 421 Intent intent; 422 Cursor cursor; 423 switch (item.getItemId()) { 424 case PARTY_SHUFFLE: 425 MusicUtils.togglePartyShuffle(); 426 break; 427 428 case SHUFFLE_ALL: 429 cursor = MusicUtils.query(this, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 430 new String [] { MediaStore.Audio.Media._ID}, 431 MediaStore.Audio.Media.IS_MUSIC + "=1", null, 432 MediaStore.Audio.Media.DEFAULT_SORT_ORDER); 433 if (cursor != null) { 434 MusicUtils.shuffleAll(this, cursor); 435 cursor.close(); 436 } 437 return true; 438 } 439 return super.onOptionsItemSelected(item); 440 } 441 442 private Cursor getAlbumCursor(AsyncQueryHandler async, String filter) { 443 StringBuilder where = new StringBuilder(); 444 where.append(MediaStore.Audio.Albums.ALBUM + " != ''"); 445 446 // Add in the filtering constraints 447 String [] keywords = null; 448 if (filter != null) { 449 String [] searchWords = filter.split(" "); 450 keywords = new String[searchWords.length]; 451 Collator col = Collator.getInstance(); 452 col.setStrength(Collator.PRIMARY); 453 for (int i = 0; i < searchWords.length; i++) { 454 keywords[i] = '%' + MediaStore.Audio.keyFor(searchWords[i]) + '%'; 455 } 456 for (int i = 0; i < searchWords.length; i++) { 457 where.append(" AND "); 458 where.append(MediaStore.Audio.Media.ARTIST_KEY + "||"); 459 where.append(MediaStore.Audio.Media.ALBUM_KEY + " LIKE ?"); 460 } 461 } 462 463 String whereclause = where.toString(); 464 465 String[] cols = new String[] { 466 MediaStore.Audio.Albums._ID, 467 MediaStore.Audio.Albums.ARTIST, 468 MediaStore.Audio.Albums.ALBUM, 469 MediaStore.Audio.Albums.ALBUM_ART 470 }; 471 Cursor ret = null; 472 if (mArtistId != null) { 473 if (async != null) { 474 async.startQuery(0, null, 475 MediaStore.Audio.Artists.Albums.getContentUri("external", 476 Long.valueOf(mArtistId)), 477 cols, whereclause, keywords, MediaStore.Audio.Albums.DEFAULT_SORT_ORDER); 478 } else { 479 ret = MusicUtils.query(this, 480 MediaStore.Audio.Artists.Albums.getContentUri("external", 481 Long.valueOf(mArtistId)), 482 cols, whereclause, keywords, MediaStore.Audio.Albums.DEFAULT_SORT_ORDER); 483 } 484 } else { 485 if (async != null) { 486 async.startQuery(0, null, 487 MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, 488 cols, whereclause, keywords, MediaStore.Audio.Albums.DEFAULT_SORT_ORDER); 489 } else { 490 ret = MusicUtils.query(this, MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, 491 cols, whereclause, keywords, MediaStore.Audio.Albums.DEFAULT_SORT_ORDER); 492 } 493 } 494 return ret; 495 } 496 497 static class AlbumListAdapter extends SimpleCursorAdapter implements SectionIndexer { 498 499 private final Drawable mNowPlayingOverlay; 500 private final BitmapDrawable mDefaultAlbumIcon; 501 private int mAlbumIdx; 502 private int mArtistIdx; 503 private int mAlbumArtIndex; 504 private final Resources mResources; 505 private final StringBuilder mStringBuilder = new StringBuilder(); 506 private final String mUnknownAlbum; 507 private final String mUnknownArtist; 508 private final String mAlbumSongSeparator; 509 private final Object[] mFormatArgs = new Object[1]; 510 private AlphabetIndexer mIndexer; 511 private AlbumBrowserActivity mActivity; 512 private AsyncQueryHandler mQueryHandler; 513 private String mConstraint = null; 514 private boolean mConstraintIsValid = false; 515 516 static class ViewHolder { 517 TextView line1; 518 TextView line2; 519 ImageView play_indicator; 520 ImageView icon; 521 } 522 523 class QueryHandler extends AsyncQueryHandler { 524 QueryHandler(ContentResolver res) { 525 super(res); 526 } 527 528 @Override 529 protected void onQueryComplete(int token, Object cookie, Cursor cursor) { 530 //Log.i("@@@", "query complete"); 531 mActivity.init(cursor); 532 } 533 } 534 535 AlbumListAdapter(Context context, AlbumBrowserActivity currentactivity, 536 int layout, Cursor cursor, String[] from, int[] to) { 537 super(context, layout, cursor, from, to); 538 539 mActivity = currentactivity; 540 mQueryHandler = new QueryHandler(context.getContentResolver()); 541 542 mUnknownAlbum = context.getString(R.string.unknown_album_name); 543 mUnknownArtist = context.getString(R.string.unknown_artist_name); 544 mAlbumSongSeparator = context.getString(R.string.albumsongseparator); 545 546 Resources r = context.getResources(); 547 mNowPlayingOverlay = r.getDrawable(R.drawable.indicator_ic_mp_playing_list); 548 549 Bitmap b = BitmapFactory.decodeResource(r, R.drawable.albumart_mp_unknown_list); 550 mDefaultAlbumIcon = new BitmapDrawable(context.getResources(), b); 551 // no filter or dither, it's a lot faster and we can't tell the difference 552 mDefaultAlbumIcon.setFilterBitmap(false); 553 mDefaultAlbumIcon.setDither(false); 554 getColumnIndices(cursor); 555 mResources = context.getResources(); 556 } 557 558 private void getColumnIndices(Cursor cursor) { 559 if (cursor != null) { 560 mAlbumIdx = cursor.getColumnIndexOrThrow(MediaStore.Audio.Albums.ALBUM); 561 mArtistIdx = cursor.getColumnIndexOrThrow(MediaStore.Audio.Albums.ARTIST); 562 mAlbumArtIndex = cursor.getColumnIndexOrThrow(MediaStore.Audio.Albums.ALBUM_ART); 563 564 if (mIndexer != null) { 565 mIndexer.setCursor(cursor); 566 } else { 567 mIndexer = new MusicAlphabetIndexer(cursor, mAlbumIdx, mResources.getString( 568 com.android.internal.R.string.fast_scroll_alphabet)); 569 } 570 } 571 } 572 573 public void setActivity(AlbumBrowserActivity newactivity) { 574 mActivity = newactivity; 575 } 576 577 public AsyncQueryHandler getQueryHandler() { 578 return mQueryHandler; 579 } 580 581 @Override 582 public View newView(Context context, Cursor cursor, ViewGroup parent) { 583 View v = super.newView(context, cursor, parent); 584 ViewHolder vh = new ViewHolder(); 585 vh.line1 = (TextView) v.findViewById(R.id.line1); 586 vh.line2 = (TextView) v.findViewById(R.id.line2); 587 vh.play_indicator = (ImageView) v.findViewById(R.id.play_indicator); 588 vh.icon = (ImageView) v.findViewById(R.id.icon); 589 vh.icon.setBackgroundDrawable(mDefaultAlbumIcon); 590 vh.icon.setPadding(0, 0, 1, 0); 591 v.setTag(vh); 592 return v; 593 } 594 595 @Override 596 public void bindView(View view, Context context, Cursor cursor) { 597 598 ViewHolder vh = (ViewHolder) view.getTag(); 599 600 String name = cursor.getString(mAlbumIdx); 601 String displayname = name; 602 boolean unknown = name == null || name.equals(MediaFile.UNKNOWN_STRING); 603 if (unknown) { 604 displayname = mUnknownAlbum; 605 } 606 vh.line1.setText(displayname); 607 608 name = cursor.getString(mArtistIdx); 609 displayname = name; 610 if (name == null || name.equals(MediaFile.UNKNOWN_STRING)) { 611 displayname = mUnknownArtist; 612 } 613 vh.line2.setText(displayname); 614 615 ImageView iv = vh.icon; 616 // We don't actually need the path to the thumbnail file, 617 // we just use it to see if there is album art or not 618 String art = cursor.getString(mAlbumArtIndex); 619 long aid = cursor.getLong(0); 620 if (unknown || art == null || art.length() == 0) { 621 iv.setImageDrawable(null); 622 } else { 623 Drawable d = MusicUtils.getCachedArtwork(context, aid, mDefaultAlbumIcon); 624 iv.setImageDrawable(d); 625 } 626 627 long currentalbumid = MusicUtils.getCurrentAlbumId(); 628 iv = vh.play_indicator; 629 if (currentalbumid == aid) { 630 iv.setImageDrawable(mNowPlayingOverlay); 631 } else { 632 iv.setImageDrawable(null); 633 } 634 } 635 636 @Override 637 public void changeCursor(Cursor cursor) { 638 if (cursor != mActivity.mAlbumCursor) { 639 mActivity.mAlbumCursor = cursor; 640 getColumnIndices(cursor); 641 super.changeCursor(cursor); 642 } 643 } 644 645 @Override 646 public Cursor runQueryOnBackgroundThread(CharSequence constraint) { 647 String s = constraint.toString(); 648 if (mConstraintIsValid && ( 649 (s == null && mConstraint == null) || 650 (s != null && s.equals(mConstraint)))) { 651 return getCursor(); 652 } 653 Cursor c = mActivity.getAlbumCursor(null, s); 654 mConstraint = s; 655 mConstraintIsValid = true; 656 return c; 657 } 658 659 public Object[] getSections() { 660 return mIndexer.getSections(); 661 } 662 663 public int getPositionForSection(int section) { 664 return mIndexer.getPositionForSection(section); 665 } 666 667 public int getSectionForPosition(int position) { 668 return 0; 669 } 670 } 671 672 private Cursor mAlbumCursor; 673 private String mArtistId; 674 675 public void onServiceConnected(ComponentName name, IBinder service) { 676 MusicUtils.updateNowPlaying(this); 677 } 678 679 public void onServiceDisconnected(ComponentName name) { 680 finish(); 681 } 682} 683 684