import android.app.Activity;
import android.app.AlertDialog;
+import android.app.KeyguardManager;
import android.app.SearchManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
+import android.content.res.Configuration;
+import android.database.Cursor;
import android.graphics.Bitmap;
import android.media.AudioManager;
-import android.media.MediaFile;
import android.net.Uri;
import android.os.Bundle;
-import android.os.RemoteException;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.RemoteException;
import android.os.SystemClock;
import android.provider.MediaStore;
import android.text.Layout;
private boolean mOneShot = false;
private boolean mSeeking = false;
- private boolean mTrackball;
+ private boolean mDeviceHasDpad;
private long mStartSeekPos = 0;
private long mLastSeekEventTime;
private IMediaPlaybackService mService = null;
private Worker mAlbumArtWorker;
private AlbumArtHandler mAlbumArtHandler;
private Toast mToast;
- private boolean mRelaunchAfterConfigChange;
private int mTouchSlop;
public MediaPlaybackActivity()
mNextButton.setRepeatListener(mFfwdListener, 260);
seekmethod = 1;
- mTrackball = true; /* (See bug 1044348) (getResources().getConfiguration().navigation ==
- Resources.Configuration.NAVIGATION_TRACKBALL);*/
+ mDeviceHasDpad = (getResources().getConfiguration().navigation ==
+ Configuration.NAVIGATION_DPAD);
mQueueButton = (ImageButton) findViewById(R.id.curplaylist);
mQueueButton.setOnClickListener(mQueueListener);
mProgress.setMax(1000);
if (icicle != null) {
- mRelaunchAfterConfigChange = icicle.getBoolean("configchange");
mOneShot = icicle.getBoolean("oneshot");
} else {
mOneShot = getIntent().getBooleanExtra("oneshot", false);
String artist;
String album;
String song;
+ long audioid;
try {
artist = mService.getArtistName();
album = mService.getAlbumName();
song = mService.getTrackName();
+ audioid = mService.getAudioId();
} catch (RemoteException ex) {
return true;
+ } catch (NullPointerException ex) {
+ // we might not actually have the service yet
+ return true;
}
-
+
+ if (MediaStore.UNKNOWN_STRING.equals(album) &&
+ MediaStore.UNKNOWN_STRING.equals(artist) &&
+ song != null &&
+ song.startsWith("recording")) {
+ // not music
+ return false;
+ }
+
+ if (audioid < 0) {
+ return false;
+ }
+
+ Cursor c = MusicUtils.query(this,
+ ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, audioid),
+ new String[] {MediaStore.Audio.Media.IS_MUSIC}, null, null, null);
+ boolean ismusic = true;
+ if (c != null) {
+ if (c.moveToFirst()) {
+ ismusic = c.getInt(0) != 0;
+ }
+ c.close();
+ }
+ if (!ismusic) {
+ return false;
+ }
+
boolean knownartist =
- (artist != null) && !MediaFile.UNKNOWN_STRING.equals(artist);
+ (artist != null) && !MediaStore.UNKNOWN_STRING.equals(artist);
boolean knownalbum =
- (album != null) && !MediaFile.UNKNOWN_STRING.equals(album);
+ (album != null) && !MediaStore.UNKNOWN_STRING.equals(album);
if (knownartist && view.equals(mArtistName.getParent())) {
title = artist;
- query = artist.toString();
+ query = artist;
mime = MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE;
} else if (knownalbum && view.equals(mAlbumName.getParent())) {
title = album;
}
mime = MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE;
} else if (view.equals(mTrackName.getParent()) || !knownartist || !knownalbum) {
- if ((song == null) || MediaFile.UNKNOWN_STRING.equals(song)) {
+ if ((song == null) || MediaStore.UNKNOWN_STRING.equals(song)) {
// A popup of the form "Search for null/'' using ..." is pretty
// unhelpful, plus, we won't find any way to buy it anyway.
return true;
mHandler.removeMessages(REFRESH);
unregisterReceiver(mStatusListener);
MusicUtils.unbindFromService(this);
+ mService = null;
super.onStop();
}
@Override
public void onSaveInstanceState(Bundle outState) {
- outState.putBoolean("configchange", getChangingConfigurations() != 0);
outState.putBoolean("oneshot", mOneShot);
super.onSaveInstanceState(outState);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
- // Don't show the menu items if we got launched by path/filedescriptor, since
- // those tend to not be in the media database.
- if (MusicUtils.getCurrentAudioId() >= 0) {
- if (!mOneShot) {
- menu.add(0, GOTO_START, 0, R.string.goto_start).setIcon(R.drawable.ic_menu_music_library);
- menu.add(0, PARTY_SHUFFLE, 0, R.string.party_shuffle); // icon will be set in onPrepareOptionsMenu()
- }
+ // Don't show the menu items if we got launched by path/filedescriptor, or
+ // if we're in one shot mode. In most cases, these menu items are not
+ // useful in those modes, so for consistency we never show them in these
+ // modes, instead of tailoring them to the specific file being played.
+ if (MusicUtils.getCurrentAudioId() >= 0 && !mOneShot) {
+ menu.add(0, GOTO_START, 0, R.string.goto_start).setIcon(R.drawable.ic_menu_music_library);
+ menu.add(0, PARTY_SHUFFLE, 0, R.string.party_shuffle); // icon will be set in onPrepareOptionsMenu()
SubMenu sub = menu.addSubMenu(0, ADD_TO_PLAYLIST, 0,
R.string.add_to_playlist).setIcon(android.R.drawable.ic_menu_add);
- MusicUtils.makePlaylistMenu(this, sub);
- menu.add(0, USE_AS_RINGTONE, 0, R.string.ringtone_menu_short).setIcon(R.drawable.ic_menu_set_as_ringtone);
- menu.add(0, DELETE_ITEM, 0, R.string.delete_item).setIcon(R.drawable.ic_menu_delete);
+ // these next two are in a separate group, so they can be shown/hidden as needed
+ // based on the keyguard state
+ menu.add(1, USE_AS_RINGTONE, 0, R.string.ringtone_menu_short)
+ .setIcon(R.drawable.ic_menu_set_as_ringtone);
+ menu.add(1, DELETE_ITEM, 0, R.string.delete_item)
+ .setIcon(R.drawable.ic_menu_delete);
+ return true;
}
- return true;
+ return false;
}
@Override
item.setTitle(R.string.party_shuffle);
}
}
+
+ item = menu.findItem(ADD_TO_PLAYLIST);
+ if (item != null) {
+ SubMenu sub = item.getSubMenu();
+ MusicUtils.makePlaylistMenu(this, sub);
+ }
+
+ KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
+ menu.setGroupVisible(1, !km.inKeyguardRestrictedInputMode());
+
return true;
}
case GOTO_START:
intent = new Intent();
intent.setClass(this, MusicBrowserActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
+ finish();
break;
case USE_AS_RINGTONE: {
// Set the system setting to make this the current ringtone
return true;
}
case PARTY_SHUFFLE:
- if (mService != null) {
- int shuffle = mService.getShuffleMode();
- if (shuffle == MediaPlaybackService.SHUFFLE_AUTO) {
- mService.setShuffleMode(MediaPlaybackService.SHUFFLE_NONE);
- } else {
- mService.setShuffleMode(MediaPlaybackService.SHUFFLE_AUTO);
- }
- }
+ MusicUtils.togglePartyShuffle();
setShuffleButtonImage();
break;
}
case PLAYLIST_SELECTED: {
- int [] list = new int[1];
+ long [] list = new long[1];
list[0] = MusicUtils.getCurrentAudioId();
- int playlist = item.getIntent().getIntExtra("playlist", 0);
+ long playlist = item.getIntent().getLongExtra("playlist", 0);
MusicUtils.addToPlaylist(this, list, playlist);
return true;
}
case DELETE_ITEM: {
if (mService != null) {
- int [] list = new int[1];
+ long [] list = new long[1];
list[0] = MusicUtils.getCurrentAudioId();
Bundle b = new Bundle();
b.putString("description", getString(R.string.delete_song_desc,
mService.getTrackName()));
- b.putIntArray("items", list);
+ b.putLongArray("items", list);
intent = new Intent();
intent.setClass(this, DeleteItems.class);
intent.putExtras(b);
case NEW_PLAYLIST:
Uri uri = intent.getData();
if (uri != null) {
- int [] list = new int[1];
+ long [] list = new long[1];
list[0] = MusicUtils.getCurrentAudioId();
int playlist = Integer.parseInt(uri.getLastPathSegment());
MusicUtils.addToPlaylist(this, list, playlist);
private boolean seekMethod1(int keyCode)
{
+ if (mService == null) return false;
for(int x=0;x<10;x++) {
for(int y=0;y<3;y++) {
if(keyboard[y][x] == keyCode) {
switch(keyCode)
{
case KeyEvent.KEYCODE_DPAD_LEFT:
- if (mTrackball) {
+ if (!useDpadMusicControl()) {
break;
}
if (mService != null) {
mPosOverride = -1;
return true;
case KeyEvent.KEYCODE_DPAD_RIGHT:
- if (mTrackball) {
+ if (!useDpadMusicControl()) {
break;
}
if (mService != null) {
return super.onKeyUp(keyCode, event);
}
+ private boolean useDpadMusicControl() {
+ if (mDeviceHasDpad && (mPrevButton.isFocused() ||
+ mNextButton.isFocused() ||
+ mPauseButton.isFocused())) {
+ return true;
+ }
+ return false;
+ }
+
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
return true;
case KeyEvent.KEYCODE_DPAD_LEFT:
- if (mTrackball) {
+ if (!useDpadMusicControl()) {
break;
}
if (!mPrevButton.hasFocus()) {
scanBackward(repcnt, event.getEventTime() - event.getDownTime());
return true;
case KeyEvent.KEYCODE_DPAD_RIGHT:
- if (mTrackball) {
+ if (!useDpadMusicControl()) {
break;
}
if (!mNextButton.hasFocus()) {
filename = uri.toString();
}
try {
- mOneShot = true;
- if (! mRelaunchAfterConfigChange) {
- mService.stop();
- mService.openfile(filename);
- mService.play();
+ if (! ContentResolver.SCHEME_CONTENT.equals(scheme) ||
+ ! MediaStore.AUTHORITY.equals(uri.getAuthority())) {
+ mOneShot = true;
}
+ mService.stop();
+ mService.openFile(filename, mOneShot);
+ mService.play();
+ setIntent(new Intent());
} catch (Exception ex) {
Log.d("MediaPlaybackActivity", "couldn't start playback: " + ex);
}
private ServiceConnection osc = new ServiceConnection() {
public void onServiceConnected(ComponentName classname, IBinder obj) {
mService = IMediaPlaybackService.Stub.asInterface(obj);
- if (MusicUtils.sService == null) {
- MusicUtils.sService = mService;
- }
startPlayback();
try {
// Assume something is playing when the service says it is,
}
};
+ private static class AlbumSongIdWrapper {
+ public long albumid;
+ public long songid;
+ AlbumSongIdWrapper(long aid, long sid) {
+ albumid = aid;
+ songid = sid;
+ }
+ }
+
private void updateTrackInfo() {
if (mService == null) {
return;
return;
}
- if (mService.getAudioId() < 0 && path.toLowerCase().startsWith("http://")) {
+ long songid = mService.getAudioId();
+ if (songid < 0 && path.toLowerCase().startsWith("http://")) {
+ // Once we can get album art and meta data from MediaPlayer, we
+ // can show that info again when streaming.
((View) mArtistName.getParent()).setVisibility(View.INVISIBLE);
((View) mAlbumName.getParent()).setVisibility(View.INVISIBLE);
mAlbum.setVisibility(View.GONE);
mTrackName.setText(path);
mAlbumArtHandler.removeMessages(GET_ALBUM_ART);
- mAlbumArtHandler.obtainMessage(GET_ALBUM_ART, -1, 0).sendToTarget();
+ mAlbumArtHandler.obtainMessage(GET_ALBUM_ART, new AlbumSongIdWrapper(-1, -1)).sendToTarget();
} else {
((View) mArtistName.getParent()).setVisibility(View.VISIBLE);
((View) mAlbumName.getParent()).setVisibility(View.VISIBLE);
String artistName = mService.getArtistName();
- if (MediaFile.UNKNOWN_STRING.equals(artistName)) {
+ if (MediaStore.UNKNOWN_STRING.equals(artistName)) {
artistName = getString(R.string.unknown_artist_name);
}
mArtistName.setText(artistName);
String albumName = mService.getAlbumName();
- int albumid = mService.getAlbumId();
- if (MediaFile.UNKNOWN_STRING.equals(albumName)) {
+ long albumid = mService.getAlbumId();
+ if (MediaStore.UNKNOWN_STRING.equals(albumName)) {
albumName = getString(R.string.unknown_album_name);
albumid = -1;
}
mAlbumName.setText(albumName);
mTrackName.setText(mService.getTrackName());
mAlbumArtHandler.removeMessages(GET_ALBUM_ART);
- mAlbumArtHandler.obtainMessage(GET_ALBUM_ART, albumid, 0).sendToTarget();
+ mAlbumArtHandler.obtainMessage(GET_ALBUM_ART, new AlbumSongIdWrapper(albumid, songid)).sendToTarget();
mAlbum.setVisibility(View.VISIBLE);
}
mDuration = mService.duration();
}
public class AlbumArtHandler extends Handler {
- private int mAlbumId = -1;
+ private long mAlbumId = -1;
public AlbumArtHandler(Looper looper) {
super(looper);
}
+ @Override
public void handleMessage(Message msg)
{
- int albumid = msg.arg1;
+ long albumid = ((AlbumSongIdWrapper) msg.obj).albumid;
+ long songid = ((AlbumSongIdWrapper) msg.obj).songid;
if (msg.what == GET_ALBUM_ART && (mAlbumId != albumid || albumid < 0)) {
// while decoding the new image, show the default album art
Message numsg = mHandler.obtainMessage(ALBUM_ART_DECODED, null);
mHandler.removeMessages(ALBUM_ART_DECODED);
mHandler.sendMessageDelayed(numsg, 300);
- Bitmap bm = MusicUtils.getArtwork(MediaPlaybackActivity.this, albumid);
+ Bitmap bm = MusicUtils.getArtwork(MediaPlaybackActivity.this, songid, albumid);
if (bm == null) {
- bm = MusicUtils.getArtwork(MediaPlaybackActivity.this, -1);
+ bm = MusicUtils.getArtwork(MediaPlaybackActivity.this, songid, -1);
albumid = -1;
}
if (bm != null) {
}
}
- private class Worker implements Runnable {
+ private static class Worker implements Runnable {
private final Object mLock = new Object();
private Looper mLooper;