blob: fb719b210af7ad4e17ac5235cddc2a0d41c5168b [file] [log] [blame]
The Android Open Source Project792a2202009-03-03 19:32:30 -08001/*
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 java.text.Collator;
20import java.util.ArrayList;
21
22import android.app.ListActivity;
23import android.content.AsyncQueryHandler;
24import android.content.BroadcastReceiver;
25import android.content.ComponentName;
26import android.content.ContentResolver;
27import android.content.ContentUris;
28import android.content.Context;
29import android.content.Intent;
30import android.content.IntentFilter;
31import android.content.ServiceConnection;
32
33import com.android.internal.database.ArrayListCursor;
34
35import android.database.Cursor;
36import android.database.MergeCursor;
37import android.database.sqlite.SQLiteException;
38import android.media.AudioManager;
39import android.net.Uri;
40import android.os.Bundle;
41import android.os.Handler;
42import android.os.IBinder;
43import android.os.Message;
44import android.provider.MediaStore;
45import android.util.Log;
46import android.view.ContextMenu;
47import android.view.Menu;
48import android.view.MenuItem;
49import android.view.View;
50import android.view.ViewGroup;
51import android.view.Window;
52import android.view.ContextMenu.ContextMenuInfo;
53import android.widget.ImageView;
54import android.widget.ListView;
55import android.widget.SimpleCursorAdapter;
56import android.widget.TextView;
57import android.widget.Toast;
58import android.widget.AdapterView.AdapterContextMenuInfo;
59
60public class PlaylistBrowserActivity extends ListActivity
61 implements View.OnCreateContextMenuListener, MusicUtils.Defs
62{
63 private static final String TAG = "PlaylistBrowserActivity";
64 private static final int DELETE_PLAYLIST = CHILD_MENU_BASE + 1;
65 private static final int EDIT_PLAYLIST = CHILD_MENU_BASE + 2;
66 private static final int RENAME_PLAYLIST = CHILD_MENU_BASE + 3;
67 private static final int CHANGE_WEEKS = CHILD_MENU_BASE + 4;
68 private static final long RECENTLY_ADDED_PLAYLIST = -1;
69 private static final long ALL_SONGS_PLAYLIST = -2;
70 private static final long PODCASTS_PLAYLIST = -3;
71 private PlaylistListAdapter mAdapter;
72 boolean mAdapterSent;
Marco Nelissenec0c57a2009-12-12 12:27:11 -080073 private static int mLastListPosCourse = -1;
74 private static int mLastListPosFine = -1;
The Android Open Source Project792a2202009-03-03 19:32:30 -080075
76 private boolean mCreateShortcut;
77
78 public PlaylistBrowserActivity()
79 {
80 }
81
82 /** Called when the activity is first created. */
83 @Override
84 public void onCreate(Bundle icicle)
85 {
86 super.onCreate(icicle);
87
88 final Intent intent = getIntent();
89 final String action = intent.getAction();
90 if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) {
91 mCreateShortcut = true;
92 }
93
94 requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
Marco Nelissenec0c57a2009-12-12 12:27:11 -080095 requestWindowFeature(Window.FEATURE_NO_TITLE);
The Android Open Source Project792a2202009-03-03 19:32:30 -080096 setVolumeControlStream(AudioManager.STREAM_MUSIC);
97 MusicUtils.bindToService(this, new ServiceConnection() {
98 public void onServiceConnected(ComponentName classname, IBinder obj) {
99 if (Intent.ACTION_VIEW.equals(action)) {
100 long id = Long.parseLong(intent.getExtras().getString("playlist"));
101 if (id == RECENTLY_ADDED_PLAYLIST) {
102 playRecentlyAdded();
103 } else if (id == PODCASTS_PLAYLIST) {
104 playPodcasts();
105 } else if (id == ALL_SONGS_PLAYLIST) {
Marco Nelissenbd447b62009-06-29 14:52:05 -0700106 long [] list = MusicUtils.getAllSongs(PlaylistBrowserActivity.this);
The Android Open Source Project792a2202009-03-03 19:32:30 -0800107 if (list != null) {
108 MusicUtils.playAll(PlaylistBrowserActivity.this, list, 0);
109 }
110 } else {
111 MusicUtils.playPlaylist(PlaylistBrowserActivity.this, id);
112 }
113 finish();
Marco Nelissenec0c57a2009-12-12 12:27:11 -0800114 return;
The Android Open Source Project792a2202009-03-03 19:32:30 -0800115 }
Marco Nelissenec0c57a2009-12-12 12:27:11 -0800116 MusicUtils.updateNowPlaying(PlaylistBrowserActivity.this);
The Android Open Source Project792a2202009-03-03 19:32:30 -0800117 }
118
119 public void onServiceDisconnected(ComponentName classname) {
120 }
121
122 });
123 IntentFilter f = new IntentFilter();
124 f.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
125 f.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
126 f.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
127 f.addDataScheme("file");
128 registerReceiver(mScanListener, f);
129
130 setContentView(R.layout.media_picker_activity);
Marco Nelissenec0c57a2009-12-12 12:27:11 -0800131 MusicUtils.updateButtonBar(this, R.id.playlisttab);
The Android Open Source Project792a2202009-03-03 19:32:30 -0800132 ListView lv = getListView();
133 lv.setOnCreateContextMenuListener(this);
134 lv.setTextFilterEnabled(true);
135
136 mAdapter = (PlaylistListAdapter) getLastNonConfigurationInstance();
137 if (mAdapter == null) {
138 //Log.i("@@@", "starting query");
139 mAdapter = new PlaylistListAdapter(
140 getApplication(),
141 this,
142 R.layout.track_list_item,
143 mPlaylistCursor,
144 new String[] { MediaStore.Audio.Playlists.NAME},
145 new int[] { android.R.id.text1 });
146 setListAdapter(mAdapter);
147 setTitle(R.string.working_playlists);
148 getPlaylistCursor(mAdapter.getQueryHandler(), null);
149 } else {
150 mAdapter.setActivity(this);
151 setListAdapter(mAdapter);
152 mPlaylistCursor = mAdapter.getCursor();
153 // If mPlaylistCursor is null, this can be because it doesn't have
154 // a cursor yet (because the initial query that sets its cursor
155 // is still in progress), or because the query failed.
156 // In order to not flash the error dialog at the user for the
157 // first case, simply retry the query when the cursor is null.
158 // Worst case, we end up doing the same query twice.
159 if (mPlaylistCursor != null) {
160 init(mPlaylistCursor);
161 } else {
162 setTitle(R.string.working_playlists);
163 getPlaylistCursor(mAdapter.getQueryHandler(), null);
164 }
165 }
166 }
167
168 @Override
169 public Object onRetainNonConfigurationInstance() {
170 PlaylistListAdapter a = mAdapter;
171 mAdapterSent = true;
172 return a;
173 }
174
175 @Override
176 public void onDestroy() {
Marco Nelissenec0c57a2009-12-12 12:27:11 -0800177 ListView lv = getListView();
178 mLastListPosCourse = lv.getFirstVisiblePosition();
179 mLastListPosFine = lv.getChildAt(0).getTop();
The Android Open Source Project792a2202009-03-03 19:32:30 -0800180 MusicUtils.unbindFromService(this);
181 if (!mAdapterSent) {
182 Cursor c = mAdapter.getCursor();
183 if (c != null) {
184 c.close();
185 }
186 }
Marco Nelissen0164ebf2009-08-13 09:58:43 -0700187 // Because we pass the adapter to the next activity, we need to make
188 // sure it doesn't keep a reference to this activity. We can do this
189 // by clearing its DatasetObservers, which setListAdapter(null) does.
190 setListAdapter(null);
191 mAdapter = null;
The Android Open Source Project792a2202009-03-03 19:32:30 -0800192 unregisterReceiver(mScanListener);
193 super.onDestroy();
194 }
195
196 @Override
197 public void onResume() {
198 super.onResume();
199
200 MusicUtils.setSpinnerState(this);
Marco Nelissenec0c57a2009-12-12 12:27:11 -0800201 MusicUtils.updateNowPlaying(PlaylistBrowserActivity.this);
The Android Open Source Project792a2202009-03-03 19:32:30 -0800202 }
203 @Override
204 public void onPause() {
205 mReScanHandler.removeCallbacksAndMessages(null);
206 super.onPause();
207 }
208 private BroadcastReceiver mScanListener = new BroadcastReceiver() {
209 @Override
210 public void onReceive(Context context, Intent intent) {
211 MusicUtils.setSpinnerState(PlaylistBrowserActivity.this);
212 mReScanHandler.sendEmptyMessage(0);
213 }
214 };
215
216 private Handler mReScanHandler = new Handler() {
Marco Nelissen42bcc212009-09-01 13:22:19 -0700217 @Override
The Android Open Source Project792a2202009-03-03 19:32:30 -0800218 public void handleMessage(Message msg) {
Marco Nelissen42bcc212009-09-01 13:22:19 -0700219 if (mAdapter != null) {
220 getPlaylistCursor(mAdapter.getQueryHandler(), null);
221 }
The Android Open Source Project792a2202009-03-03 19:32:30 -0800222 }
223 };
224 public void init(Cursor cursor) {
225
Marco Nelissen42bcc212009-09-01 13:22:19 -0700226 if (mAdapter == null) {
227 return;
228 }
The Android Open Source Project792a2202009-03-03 19:32:30 -0800229 mAdapter.changeCursor(cursor);
230
231 if (mPlaylistCursor == null) {
232 MusicUtils.displayDatabaseError(this);
233 closeContextMenu();
234 mReScanHandler.sendEmptyMessageDelayed(0, 1000);
235 return;
236 }
237
Marco Nelissenec0c57a2009-12-12 12:27:11 -0800238 // restore previous position
239 if (mLastListPosCourse >= 0) {
240 getListView().setSelectionFromTop(mLastListPosCourse, mLastListPosFine);
241 mLastListPosCourse = -1;
242 }
The Android Open Source Project792a2202009-03-03 19:32:30 -0800243 MusicUtils.hideDatabaseError(this);
244 setTitle();
245 }
246
247 private void setTitle() {
248 setTitle(R.string.playlists_title);
249 }
250
251 @Override
252 public boolean onCreateOptionsMenu(Menu menu) {
253 if (!mCreateShortcut) {
Marco Nelissenec0c57a2009-12-12 12:27:11 -0800254 menu.add(0, PARTY_SHUFFLE, 0, R.string.party_shuffle); // icon will be set in onPrepareOptionsMenu()
The Android Open Source Project792a2202009-03-03 19:32:30 -0800255 }
256 return super.onCreateOptionsMenu(menu);
257 }
258
259 @Override
Marco Nelissenec0c57a2009-12-12 12:27:11 -0800260 public boolean onPrepareOptionsMenu(Menu menu) {
261 MusicUtils.setPartyShuffleMenuIcon(menu);
262 return super.onPrepareOptionsMenu(menu);
263 }
264
265 @Override
The Android Open Source Project792a2202009-03-03 19:32:30 -0800266 public boolean onOptionsItemSelected(MenuItem item) {
267 Intent intent;
268 switch (item.getItemId()) {
Marco Nelissenec0c57a2009-12-12 12:27:11 -0800269 case PARTY_SHUFFLE:
270 MusicUtils.togglePartyShuffle();
271 break;
The Android Open Source Project792a2202009-03-03 19:32:30 -0800272 }
273 return super.onOptionsItemSelected(item);
274 }
275
276 public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfoIn) {
277 if (mCreateShortcut) {
278 return;
279 }
280
281 AdapterContextMenuInfo mi = (AdapterContextMenuInfo) menuInfoIn;
282
283 menu.add(0, PLAY_SELECTION, 0, R.string.play_selection);
284
285 if (mi.id >= 0 /*|| mi.id == PODCASTS_PLAYLIST*/) {
286 menu.add(0, DELETE_PLAYLIST, 0, R.string.delete_playlist_menu);
287 }
288
289 if (mi.id == RECENTLY_ADDED_PLAYLIST) {
290 menu.add(0, EDIT_PLAYLIST, 0, R.string.edit_playlist_menu);
291 }
292
293 if (mi.id >= 0) {
294 menu.add(0, RENAME_PLAYLIST, 0, R.string.rename_playlist_menu);
295 }
296
297 mPlaylistCursor.moveToPosition(mi.position);
298 menu.setHeaderTitle(mPlaylistCursor.getString(mPlaylistCursor.getColumnIndexOrThrow(
299 MediaStore.Audio.Playlists.NAME)));
300 }
301
302 @Override
303 public boolean onContextItemSelected(MenuItem item) {
304 AdapterContextMenuInfo mi = (AdapterContextMenuInfo) item.getMenuInfo();
305 switch (item.getItemId()) {
306 case PLAY_SELECTION:
307 if (mi.id == RECENTLY_ADDED_PLAYLIST) {
308 playRecentlyAdded();
309 } else if (mi.id == PODCASTS_PLAYLIST) {
310 playPodcasts();
311 } else {
312 MusicUtils.playPlaylist(this, mi.id);
313 }
314 break;
315 case DELETE_PLAYLIST:
316 Uri uri = ContentUris.withAppendedId(
317 MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, mi.id);
318 getContentResolver().delete(uri, null, null);
319 Toast.makeText(this, R.string.playlist_deleted_message, Toast.LENGTH_SHORT).show();
320 if (mPlaylistCursor.getCount() == 0) {
321 setTitle(R.string.no_playlists_title);
322 }
323 break;
324 case EDIT_PLAYLIST:
325 if (mi.id == RECENTLY_ADDED_PLAYLIST) {
326 Intent intent = new Intent();
327 intent.setClass(this, WeekSelector.class);
328 startActivityForResult(intent, CHANGE_WEEKS);
329 return true;
330 } else {
331 Log.e(TAG, "should not be here");
332 }
333 break;
334 case RENAME_PLAYLIST:
335 Intent intent = new Intent();
336 intent.setClass(this, RenamePlaylist.class);
337 intent.putExtra("rename", mi.id);
338 startActivityForResult(intent, RENAME_PLAYLIST);
339 break;
340 }
341 return true;
342 }
343
344 @Override
345 protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
346 switch (requestCode) {
347 case SCAN_DONE:
348 if (resultCode == RESULT_CANCELED) {
349 finish();
Marco Nelissen42bcc212009-09-01 13:22:19 -0700350 } else if (mAdapter != null) {
The Android Open Source Project792a2202009-03-03 19:32:30 -0800351 getPlaylistCursor(mAdapter.getQueryHandler(), null);
352 }
353 break;
354 }
355 }
356
357 @Override
358 protected void onListItemClick(ListView l, View v, int position, long id)
359 {
360 if (mCreateShortcut) {
361 final Intent shortcut = new Intent();
362 shortcut.setAction(Intent.ACTION_VIEW);
363 shortcut.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/playlist");
364 shortcut.putExtra("playlist", String.valueOf(id));
365
366 final Intent intent = new Intent();
367 intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcut);
368 intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, ((TextView) v.findViewById(R.id.line1)).getText());
369 intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(
Romain Guye013d772009-03-24 18:10:17 -0700370 this, R.drawable.ic_launcher_shortcut_music_playlist));
The Android Open Source Project792a2202009-03-03 19:32:30 -0800371
372 setResult(RESULT_OK, intent);
373 finish();
374 return;
375 }
376 if (id == RECENTLY_ADDED_PLAYLIST) {
377 Intent intent = new Intent(Intent.ACTION_PICK);
378 intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/track");
379 intent.putExtra("playlist", "recentlyadded");
380 startActivity(intent);
381 } else if (id == PODCASTS_PLAYLIST) {
382 Intent intent = new Intent(Intent.ACTION_PICK);
383 intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/track");
384 intent.putExtra("playlist", "podcasts");
385 startActivity(intent);
386 } else {
387 Intent intent = new Intent(Intent.ACTION_EDIT);
388 intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/track");
389 intent.putExtra("playlist", Long.valueOf(id).toString());
390 startActivity(intent);
391 }
392 }
393
394 private void playRecentlyAdded() {
395 // do a query for all songs added in the last X weeks
396 int X = MusicUtils.getIntPref(this, "numweeks", 2) * (3600 * 24 * 7);
397 final String[] ccols = new String[] { MediaStore.Audio.Media._ID};
398 String where = MediaStore.MediaColumns.DATE_ADDED + ">" + (System.currentTimeMillis() / 1000 - X);
399 Cursor cursor = MusicUtils.query(this, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
400 ccols, where, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
401
402 if (cursor == null) {
403 // Todo: show a message
404 return;
405 }
406 try {
407 int len = cursor.getCount();
Marco Nelissenbd447b62009-06-29 14:52:05 -0700408 long [] list = new long[len];
The Android Open Source Project792a2202009-03-03 19:32:30 -0800409 for (int i = 0; i < len; i++) {
410 cursor.moveToNext();
Marco Nelissenbd447b62009-06-29 14:52:05 -0700411 list[i] = cursor.getLong(0);
The Android Open Source Project792a2202009-03-03 19:32:30 -0800412 }
413 MusicUtils.playAll(this, list, 0);
414 } catch (SQLiteException ex) {
415 } finally {
416 cursor.close();
417 }
418 }
419
420 private void playPodcasts() {
421 // do a query for all files that are podcasts
422 final String[] ccols = new String[] { MediaStore.Audio.Media._ID};
423 Cursor cursor = MusicUtils.query(this, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
424 ccols, MediaStore.Audio.Media.IS_PODCAST + "=1",
425 null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
426
427 if (cursor == null) {
428 // Todo: show a message
429 return;
430 }
431 try {
432 int len = cursor.getCount();
Marco Nelissenbd447b62009-06-29 14:52:05 -0700433 long [] list = new long[len];
The Android Open Source Project792a2202009-03-03 19:32:30 -0800434 for (int i = 0; i < len; i++) {
435 cursor.moveToNext();
Marco Nelissenbd447b62009-06-29 14:52:05 -0700436 list[i] = cursor.getLong(0);
The Android Open Source Project792a2202009-03-03 19:32:30 -0800437 }
438 MusicUtils.playAll(this, list, 0);
439 } catch (SQLiteException ex) {
440 } finally {
441 cursor.close();
442 }
443 }
444
445
446 String[] mCols = new String[] {
447 MediaStore.Audio.Playlists._ID,
448 MediaStore.Audio.Playlists.NAME
449 };
450
451 private Cursor getPlaylistCursor(AsyncQueryHandler async, String filterstring) {
452
453 StringBuilder where = new StringBuilder();
454 where.append(MediaStore.Audio.Playlists.NAME + " != ''");
455
456 // Add in the filtering constraints
457 String [] keywords = null;
458 if (filterstring != null) {
459 String [] searchWords = filterstring.split(" ");
460 keywords = new String[searchWords.length];
461 Collator col = Collator.getInstance();
462 col.setStrength(Collator.PRIMARY);
463 for (int i = 0; i < searchWords.length; i++) {
464 keywords[i] = '%' + searchWords[i] + '%';
465 }
466 for (int i = 0; i < searchWords.length; i++) {
467 where.append(" AND ");
468 where.append(MediaStore.Audio.Playlists.NAME + " LIKE ?");
469 }
470 }
471
472 String whereclause = where.toString();
473
474
475 if (async != null) {
476 async.startQuery(0, null, MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
477 mCols, whereclause, keywords, MediaStore.Audio.Playlists.NAME);
478 return null;
479 }
480 Cursor c = null;
481 c = MusicUtils.query(this, MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
482 mCols, whereclause, keywords, MediaStore.Audio.Playlists.NAME);
483
484 return mergedCursor(c);
485 }
486
487 private Cursor mergedCursor(Cursor c) {
488 if (c == null) {
489 return null;
490 }
491 if (c instanceof MergeCursor) {
492 // this shouldn't happen, but fail gracefully
493 Log.d("PlaylistBrowserActivity", "Already wrapped");
494 return c;
495 }
496 ArrayList<ArrayList> autoplaylists = new ArrayList<ArrayList>();
497 if (mCreateShortcut) {
498 ArrayList<Object> all = new ArrayList<Object>(2);
499 all.add(ALL_SONGS_PLAYLIST);
500 all.add(getString(R.string.play_all));
501 autoplaylists.add(all);
502 }
503 ArrayList<Object> recent = new ArrayList<Object>(2);
504 recent.add(RECENTLY_ADDED_PLAYLIST);
505 recent.add(getString(R.string.recentlyadded));
506 autoplaylists.add(recent);
507
508 // check if there are any podcasts
509 Cursor counter = MusicUtils.query(this, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
510 new String[] {"count(*)"}, "is_podcast=1", null, null);
511 if (counter != null) {
512 counter.moveToFirst();
513 int numpodcasts = counter.getInt(0);
514 counter.close();
515 if (numpodcasts > 0) {
516 ArrayList<Object> podcasts = new ArrayList<Object>(2);
517 podcasts.add(PODCASTS_PLAYLIST);
518 podcasts.add(getString(R.string.podcasts_listitem));
519 autoplaylists.add(podcasts);
520 }
521 }
522
523 ArrayListCursor autoplaylistscursor = new ArrayListCursor(mCols, autoplaylists);
524
525 Cursor cc = new MergeCursor(new Cursor [] {autoplaylistscursor, c});
526 return cc;
527 }
528
529 static class PlaylistListAdapter extends SimpleCursorAdapter {
530 int mTitleIdx;
531 int mIdIdx;
532 private PlaylistBrowserActivity mActivity = null;
533 private AsyncQueryHandler mQueryHandler;
534 private String mConstraint = null;
535 private boolean mConstraintIsValid = false;
536
537 class QueryHandler extends AsyncQueryHandler {
538 QueryHandler(ContentResolver res) {
539 super(res);
540 }
541
542 @Override
543 protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
544 //Log.i("@@@", "query complete: " + cursor.getCount() + " " + mActivity);
545 if (cursor != null) {
546 cursor = mActivity.mergedCursor(cursor);
547 }
548 mActivity.init(cursor);
549 }
550 }
551
552 PlaylistListAdapter(Context context, PlaylistBrowserActivity currentactivity,
553 int layout, Cursor cursor, String[] from, int[] to) {
554 super(context, layout, cursor, from, to);
555 mActivity = currentactivity;
556 getColumnIndices(cursor);
557 mQueryHandler = new QueryHandler(context.getContentResolver());
558 }
559 private void getColumnIndices(Cursor cursor) {
560 if (cursor != null) {
561 mTitleIdx = cursor.getColumnIndexOrThrow(MediaStore.Audio.Playlists.NAME);
562 mIdIdx = cursor.getColumnIndexOrThrow(MediaStore.Audio.Playlists._ID);
563 }
564 }
565
566 public void setActivity(PlaylistBrowserActivity newactivity) {
567 mActivity = newactivity;
568 }
569
570 public AsyncQueryHandler getQueryHandler() {
571 return mQueryHandler;
572 }
573
574 @Override
575 public void bindView(View view, Context context, Cursor cursor) {
576
577 TextView tv = (TextView) view.findViewById(R.id.line1);
578
579 String name = cursor.getString(mTitleIdx);
580 tv.setText(name);
581
582 long id = cursor.getLong(mIdIdx);
583
584 ImageView iv = (ImageView) view.findViewById(R.id.icon);
585 if (id == RECENTLY_ADDED_PLAYLIST) {
586 iv.setImageResource(R.drawable.ic_mp_playlist_recently_added_list);
587 } else {
588 iv.setImageResource(R.drawable.ic_mp_playlist_list);
589 }
590 ViewGroup.LayoutParams p = iv.getLayoutParams();
591 p.width = ViewGroup.LayoutParams.WRAP_CONTENT;
592 p.height = ViewGroup.LayoutParams.WRAP_CONTENT;
593
594 iv = (ImageView) view.findViewById(R.id.play_indicator);
595 iv.setVisibility(View.GONE);
596
597 view.findViewById(R.id.line2).setVisibility(View.GONE);
598 }
599
600 @Override
601 public void changeCursor(Cursor cursor) {
602 if (cursor != mActivity.mPlaylistCursor) {
603 mActivity.mPlaylistCursor = cursor;
604 super.changeCursor(cursor);
605 getColumnIndices(cursor);
606 }
607 }
608
609 @Override
610 public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
611 String s = constraint.toString();
612 if (mConstraintIsValid && (
613 (s == null && mConstraint == null) ||
614 (s != null && s.equals(mConstraint)))) {
615 return getCursor();
616 }
617 Cursor c = mActivity.getPlaylistCursor(null, s);
618 mConstraint = s;
619 mConstraintIsValid = true;
620 return c;
621 }
622 }
623
624 private Cursor mPlaylistCursor;
625}
626