import android.app.SearchManager;
import android.content.AsyncQueryHandler;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.ServiceConnection;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Message;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import java.util.ArrayList;
-public class QueryBrowserActivity extends ListActivity implements MusicUtils.Defs
+public class QueryBrowserActivity extends ListActivity
+implements MusicUtils.Defs, ServiceConnection
{
private final static int PLAY_NOW = 0;
private final static int ADD_TO_QUEUE = 1;
{
super.onCreate(icicle);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
- MusicUtils.bindToService(this);
+ mAdapter = (QueryListAdapter) getLastNonConfigurationInstance();
+ MusicUtils.bindToService(this, this);
+ // defer the real work until we're bound to the service
+ }
+
+
+ public void onServiceConnected(ComponentName name, IBinder service) {
IntentFilter f = new IntentFilter();
f.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
f.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
f.addDataScheme("file");
registerReceiver(mScanListener, f);
- if (icicle == null) {
- Intent intent = getIntent();
-
- if (intent.getAction().equals(Intent.ACTION_VIEW)) {
- // this is something we got from the search bar
- Uri uri = intent.getData();
- String path = uri.toString();
- if (path.startsWith("content://media/external/audio/media/")) {
- // This is a specific file
- String id = uri.getLastPathSegment();
- int [] list = new int[] { Integer.valueOf(id) };
- MusicUtils.playAll(this, list, 0);
- finish();
- return;
- } else if (path.startsWith("content://media/external/audio/albums/")) {
- // This is an album, show the songs on it
- Intent i = new Intent(Intent.ACTION_PICK);
- i.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/track");
- i.putExtra("album", uri.getLastPathSegment());
- startActivity(i);
- finish();
- return;
- } else if (path.startsWith("content://media/external/audio/artists/")) {
- // This is an artist, show the albums for that artist
- Intent i = new Intent(Intent.ACTION_PICK);
- i.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/album");
- i.putExtra("artist", uri.getLastPathSegment());
- startActivity(i);
- finish();
- return;
+ Intent intent = getIntent();
+ String action = intent != null ? intent.getAction() : null;
+
+ if (Intent.ACTION_VIEW.equals(action)) {
+ // this is something we got from the search bar
+ Uri uri = intent.getData();
+ String path = uri.toString();
+ if (path.startsWith("content://media/external/audio/media/")) {
+ // This is a specific file
+ String id = uri.getLastPathSegment();
+ long [] list = new long[] { Long.valueOf(id) };
+ MusicUtils.playAll(this, list, 0);
+ finish();
+ return;
+ } else if (path.startsWith("content://media/external/audio/albums/")) {
+ // This is an album, show the songs on it
+ Intent i = new Intent(Intent.ACTION_PICK);
+ i.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/track");
+ i.putExtra("album", uri.getLastPathSegment());
+ startActivity(i);
+ finish();
+ return;
+ } else if (path.startsWith("content://media/external/audio/artists/")) {
+ // This is an artist, show the albums for that artist
+ Intent i = new Intent(Intent.ACTION_PICK);
+ i.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/album");
+ i.putExtra("artist", uri.getLastPathSegment());
+ startActivity(i);
+ finish();
+ return;
+ }
+ }
+
+ mFilterString = intent.getStringExtra(SearchManager.QUERY);
+ if (MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)) {
+ String focus = intent.getStringExtra(MediaStore.EXTRA_MEDIA_FOCUS);
+ String artist = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ARTIST);
+ String album = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ALBUM);
+ String title = intent.getStringExtra(MediaStore.EXTRA_MEDIA_TITLE);
+ if (focus != null) {
+ if (focus.startsWith("audio/") && title != null) {
+ mFilterString = title;
+ } else if (focus.equals(MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE)) {
+ if (album != null) {
+ mFilterString = album;
+ if (artist != null) {
+ mFilterString = mFilterString + " " + artist;
+ }
+ }
+ } else if (focus.equals(MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE)) {
+ if (artist != null) {
+ mFilterString = artist;
+ }
}
}
- mFilterString = intent.getStringExtra(SearchManager.QUERY);
}
setContentView(R.layout.query_activity);
mTrackList = getListView();
mTrackList.setTextFilterEnabled(true);
- mAdapter = (QueryListAdapter) getLastNonConfigurationInstance();
if (mAdapter == null) {
mAdapter = new QueryListAdapter(
getApplication(),
}
}
}
-
+
+ public void onServiceDisconnected(ComponentName name) {
+
+ }
+
@Override
public Object onRetainNonConfigurationInstance() {
mAdapterSent = true;
public void onDestroy() {
MusicUtils.unbindFromService(this);
unregisterReceiver(mScanListener);
- super.onDestroy();
+ // If we have an adapter and didn't send it off to another activity yet, we should
+ // close its cursor, which we do by assigning a null cursor to it. Doing this
+ // instead of closing the cursor directly keeps the framework from accessing
+ // the closed cursor later.
if (!mAdapterSent && mAdapter != null) {
- Cursor c = mAdapter.getCursor();
- if (c != null) {
- c.close();
- }
+ mAdapter.changeCursor(null);
}
+ // Because we pass the adapter to the next activity, we need to make
+ // sure it doesn't keep a reference to this activity. We can do this
+ // by clearing its DatasetObservers, which setListAdapter(null) does.
+ setListAdapter(null);
+ mAdapter = null;
+ super.onDestroy();
}
/*
private Handler mReScanHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
- getQueryCursor(mAdapter.getQueryHandler(), null);
+ if (mAdapter != null) {
+ getQueryCursor(mAdapter.getQueryHandler(), null);
+ }
// if the query results in a null cursor, onQueryComplete() will
// call init(), which will post a delayed message to this handler
// in order to try again.
}
public void init(Cursor c) {
-
+
+ if (mAdapter == null) {
+ return;
+ }
mAdapter.changeCursor(c);
if (mQueryCursor == null) {
if ("artist".equals(selectedType)) {
Intent intent = new Intent(Intent.ACTION_PICK);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/album");
intent.putExtra("artist", Long.valueOf(id).toString());
startActivity(intent);
} else if ("album".equals(selectedType)) {
Intent intent = new Intent(Intent.ACTION_PICK);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/track");
intent.putExtra("album", Long.valueOf(id).toString());
startActivity(intent);
} else if (position >= 0 && id >= 0){
- int [] list = new int[] { (int) id };
+ long [] list = new long[] { id };
MusicUtils.playAll(this, list, 0);
} else {
Log.e("QueryBrowser", "invalid position/id: " + position + "/" + id);
}
@Override
public void changeCursor(Cursor cursor) {
+ if (mActivity.isFinishing() && cursor != null) {
+ cursor.close();
+ cursor = null;
+ }
if (cursor != mActivity.mQueryCursor) {
mActivity.mQueryCursor = cursor;
super.changeCursor(cursor);