Implement the ability to add media to playlists.
This commit is contained in:
parent
0e7bfd8ad3
commit
7c082f4856
51
res/layout/new_playlist_dialog.xml
Normal file
51
res/layout/new_playlist_dialog.xml
Normal file
@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2010 Christopher Eby <kreed@kreed.org>
|
||||
|
||||
This file is part of Vanilla Music Player.
|
||||
|
||||
Vanilla Music Player is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Library General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
Vanilla Music Player is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<EditText
|
||||
android:id="@+id/playlist_name"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:layout_marginBottom="8dip"
|
||||
android:layout_marginLeft="8dip"
|
||||
android:layout_marginRight="8dip">
|
||||
<requestFocus />
|
||||
</EditText>
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="6dip"
|
||||
android:background="#fff" >
|
||||
<Button android:id="@+id/create"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/create"
|
||||
android:singleLine="true" />
|
||||
<Button android:id="@+id/cancel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/cancel"
|
||||
android:singleLine="true" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
@ -37,15 +37,27 @@
|
||||
<!-- Widgets -->
|
||||
<string name="starting">Starting up...</string>
|
||||
|
||||
<!-- New Playlist Dialog -->
|
||||
<string name="choose_playlist_name">Choose Playlist Name</string>
|
||||
<string name="create">Create</string>
|
||||
<string name="overwrite">Overwrite</string>
|
||||
<string name="cancel">Cancel</string>
|
||||
|
||||
<!-- Song Chooser -->
|
||||
<string name="enqueue">Enqueue</string>
|
||||
<string name="play">Play</string>
|
||||
<string name="add_to_playlist">Add to Playlist...</string>
|
||||
<string name="new_playlist">New Playlist...</string>
|
||||
<string name="expand">Expand</string>
|
||||
<string name="playback_view">Now Playing</string>
|
||||
<string name="search">Search</string>
|
||||
|
||||
<string name="enqueued">Enqueued %s</string>
|
||||
<string name="playing">Playing %s</string>
|
||||
<plurals name="added_to_playlist">
|
||||
<item quantity="one">1 song added to playlist %2$s.</item>
|
||||
<item quantity="other">%d songs added to playlist %s.</item>
|
||||
</plurals>
|
||||
|
||||
<string name="artists">Artists</string>
|
||||
<string name="albums">Albums</string>
|
||||
|
@ -176,7 +176,7 @@ public class MediaAdapter extends CursorAdapter implements FilterQueryProvider {
|
||||
public void filter(CharSequence constraint, Filter.FilterListener listener)
|
||||
{
|
||||
mConstraint = constraint;
|
||||
getFilter().filter(constraint, listener);
|
||||
super.getFilter().filter(constraint, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -292,14 +292,6 @@ public class MediaAdapter extends CursorAdapter implements FilterQueryProvider {
|
||||
return resolver.query(mStore, projection, selection.toString(), selectionArgs, getSortOrder());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if views has expander arrows displayed.
|
||||
*/
|
||||
public final boolean hasExpanders()
|
||||
{
|
||||
return mExpandable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the limiter for the adapter. A limiter is intended to restrict
|
||||
* displayed media to only those that are children of a given parent
|
||||
@ -315,7 +307,7 @@ public class MediaAdapter extends CursorAdapter implements FilterQueryProvider {
|
||||
{
|
||||
mLimiter = limiter;
|
||||
if (async)
|
||||
getFilter().filter(mConstraint);
|
||||
super.getFilter().filter(mConstraint);
|
||||
else
|
||||
requery();
|
||||
}
|
||||
@ -543,6 +535,14 @@ public class MediaAdapter extends CursorAdapter implements FilterQueryProvider {
|
||||
return mExpanderPressed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if views has expander arrows displayed.
|
||||
*/
|
||||
public final boolean hasExpanders()
|
||||
{
|
||||
return mExpandable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the fields in this view with the data from the given Cursor.
|
||||
*
|
||||
|
119
src/org/kreed/vanilla/NewPlaylistDialog.java
Normal file
119
src/org/kreed/vanilla/NewPlaylistDialog.java
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Christopher Eby <kreed@kreed.org>
|
||||
*
|
||||
* This file is part of Vanilla Music Player.
|
||||
*
|
||||
* Vanilla Music Player is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Vanilla Music Player is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.kreed.vanilla;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
|
||||
/**
|
||||
* Simple dialog to prompt to user to enter a playlist name. Has an EditText to
|
||||
* enter the name and two buttons, create and cancel. Create changes to
|
||||
* overwrite if a name that already exists is selected.
|
||||
*/
|
||||
public class NewPlaylistDialog extends Dialog implements TextWatcher, View.OnClickListener {
|
||||
/**
|
||||
* The create/overwrite button.
|
||||
*/
|
||||
private Button mPositiveButton;
|
||||
/**
|
||||
* The text entry view.
|
||||
*/
|
||||
private EditText mText;
|
||||
/**
|
||||
* Whether the dialog has been accepted. The dialog is accepted if create
|
||||
* was clicked.
|
||||
*/
|
||||
private boolean mAccepted;
|
||||
|
||||
public NewPlaylistDialog(Context context)
|
||||
{
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle state)
|
||||
{
|
||||
super.onCreate(state);
|
||||
|
||||
setContentView(R.layout.new_playlist_dialog);
|
||||
|
||||
setTitle(R.string.choose_playlist_name);
|
||||
|
||||
mText = (EditText)findViewById(R.id.playlist_name);
|
||||
mText.addTextChangedListener(this);
|
||||
|
||||
mPositiveButton = (Button)findViewById(R.id.create);
|
||||
View negativeButton = findViewById(R.id.cancel);
|
||||
mPositiveButton.setOnClickListener(this);
|
||||
negativeButton.setOnClickListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the playlist name currently entered in the dialog.
|
||||
*/
|
||||
public String getText()
|
||||
{
|
||||
return mText.getText().toString();
|
||||
}
|
||||
|
||||
public void afterTextChanged(Editable s)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count)
|
||||
{
|
||||
// Update the action button based on whether there is an
|
||||
// existing playlist with the given name.
|
||||
int res = Song.getPlaylist(s.toString()) == -1 ? R.string.create : R.string.overwrite;
|
||||
mPositiveButton.setText(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the dialog has been accepted. The dialog is accepted
|
||||
* when the create/overwrite button is clicked.
|
||||
*/
|
||||
public boolean isAccepted()
|
||||
{
|
||||
return mAccepted;
|
||||
}
|
||||
|
||||
public void onClick(View view)
|
||||
{
|
||||
switch (view.getId()) {
|
||||
case R.id.create:
|
||||
mAccepted = true;
|
||||
// fall through
|
||||
case R.id.cancel:
|
||||
dismiss();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@
|
||||
package org.kreed.vanilla;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
@ -200,14 +201,13 @@ public class Song implements Parcelable {
|
||||
* Return a cursor containing the ids of all the songs with artist or
|
||||
* album of the specified id.
|
||||
*
|
||||
* @param resolver The ContentResolver to run the query with.
|
||||
* @param type TYPE_ARTIST or TYPE_ALBUM, indicating the the id represents
|
||||
* an artist or album
|
||||
* @param id The MediaStore id of the artist or album
|
||||
*/
|
||||
private static Cursor getMediaCursor(ContentResolver resolver, int type, long id)
|
||||
private static Cursor getMediaCursor(int type, long id)
|
||||
{
|
||||
String selection = '=' + id + " AND " + MediaStore.Audio.Media.IS_MUSIC + "!=0";
|
||||
String selection = "=" + id + " AND " + MediaStore.Audio.Media.IS_MUSIC + "!=0";
|
||||
|
||||
switch (type) {
|
||||
case TYPE_ARTIST:
|
||||
@ -220,7 +220,7 @@ public class Song implements Parcelable {
|
||||
throw new IllegalArgumentException("Invalid type specified: " + type);
|
||||
}
|
||||
|
||||
|
||||
ContentResolver resolver = ContextApplication.getContext().getContentResolver();
|
||||
Uri media = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
||||
String[] projection = { MediaStore.Audio.Media._ID };
|
||||
String sort = MediaStore.Audio.Media.ARTIST_KEY + ',' + MediaStore.Audio.Media.ALBUM_KEY + ',' + MediaStore.Audio.Media.TRACK;
|
||||
@ -231,15 +231,151 @@ public class Song implements Parcelable {
|
||||
* Return a cursor containing the ids of all the songs in the playlist
|
||||
* with the given id.
|
||||
*
|
||||
* @param resolver The ContentResolver to run the query with.
|
||||
* @param id The id of the playlist in MediaStore.Audio.Playlists.
|
||||
*/
|
||||
private static Cursor getPlaylistCursor(ContentResolver resolver, long id)
|
||||
private static Cursor getPlaylistCursor(long id)
|
||||
{
|
||||
ContentResolver resolver = ContextApplication.getContext().getContentResolver();
|
||||
Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", id);
|
||||
String[] projection = new String[] { MediaStore.Audio.Playlists.Members.AUDIO_ID };
|
||||
return resolver.query(uri, projection, null, null,
|
||||
MediaStore.Audio.Playlists.Members.DEFAULT_SORT_ORDER);
|
||||
String sort = MediaStore.Audio.Playlists.Members.PLAY_ORDER;
|
||||
return resolver.query(uri, projection, null, null, sort);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class simply containing metadata about a playlist.
|
||||
*/
|
||||
public static class Playlist {
|
||||
/**
|
||||
* Create a Playlist with the given id and name.
|
||||
*/
|
||||
public Playlist(long id, String name)
|
||||
{
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The MediaStore.Audio.Playlists id of the playlist.
|
||||
*/
|
||||
public long id;
|
||||
/**
|
||||
* The name of the playlist.
|
||||
*/
|
||||
public String name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries all the playlists known to the MediaStore.
|
||||
*
|
||||
* @return An array of Playlists
|
||||
* @see Playlist
|
||||
*/
|
||||
public static Playlist[] getPlaylists()
|
||||
{
|
||||
ContentResolver resolver = ContextApplication.getContext().getContentResolver();
|
||||
Uri media = MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI;
|
||||
String[] projection = { MediaStore.Audio.Playlists._ID, MediaStore.Audio.Playlists.NAME };
|
||||
String sort = MediaStore.Audio.Playlists.NAME;
|
||||
Cursor cursor = resolver.query(media, projection, null, null, sort);
|
||||
|
||||
if (cursor == null)
|
||||
return null;
|
||||
|
||||
int count = cursor.getCount();
|
||||
if (count == 0)
|
||||
return null;
|
||||
|
||||
Playlist[] playlists = new Playlist[count];
|
||||
for (int i = 0; i != count; ++i) {
|
||||
if (!cursor.moveToNext())
|
||||
return null;
|
||||
playlists[i] = new Playlist(cursor.getLong(0), cursor.getString(1));
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
return playlists;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the id for a playlist with the given name.
|
||||
*
|
||||
* @param name The name of the playlist.
|
||||
* @return The id of the playlist, or -1 if there is no playlist with the
|
||||
* given name.
|
||||
*/
|
||||
public static long getPlaylist(String name)
|
||||
{
|
||||
long id = -1;
|
||||
|
||||
ContentResolver resolver = ContextApplication.getContext().getContentResolver();
|
||||
Cursor cursor = resolver.query(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
|
||||
new String[] { MediaStore.Audio.Playlists._ID },
|
||||
MediaStore.Audio.Playlists.NAME + "=?",
|
||||
new String[] { name }, null);
|
||||
|
||||
if (cursor != null) {
|
||||
if (cursor.moveToNext())
|
||||
id = cursor.getLong(0);
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new playlist with the given name. If a playlist with the given
|
||||
* name already exists, it will be overwritten.
|
||||
*
|
||||
* @param name The name of the playlist.
|
||||
* @return The id of the new playlist.
|
||||
*/
|
||||
public static long createPlaylist(String name)
|
||||
{
|
||||
ContentResolver resolver = ContextApplication.getContext().getContentResolver();
|
||||
long id = getPlaylist(name);
|
||||
|
||||
if (id == -1) {
|
||||
// We need to create a new playlist.
|
||||
ContentValues values = new ContentValues(1);
|
||||
values.put(MediaStore.Audio.Playlists.NAME, name);
|
||||
Uri uri = resolver.insert(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, values);
|
||||
id = Long.parseLong(uri.getLastPathSegment());
|
||||
} else {
|
||||
// We are overwriting an existing playlist. Clear existing songs.
|
||||
Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", id);
|
||||
resolver.delete(uri, null, null);
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given set of song ids to the playlist with the given id.
|
||||
*
|
||||
* @param playlistId The MediaStore.Audio.Playlist id of the playlist to
|
||||
* modify.
|
||||
* @param toAdd The MediaStore ids of all the songs to be added to the
|
||||
* playlist.
|
||||
*/
|
||||
public static void addToPlaylist(long playlistId, long[] toAdd)
|
||||
{
|
||||
ContentResolver resolver = ContextApplication.getContext().getContentResolver();
|
||||
Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId);
|
||||
String[] projection = new String[] { MediaStore.Audio.Playlists.Members.PLAY_ORDER };
|
||||
Cursor cursor = resolver.query(uri, projection, null, null, null);
|
||||
int base = 0;
|
||||
if (cursor.moveToLast())
|
||||
base = cursor.getInt(0) + 1;
|
||||
cursor.close();
|
||||
|
||||
ContentValues[] values = new ContentValues[toAdd.length];
|
||||
for (int i = 0; i != values.length; ++i) {
|
||||
values[i] = new ContentValues(1);
|
||||
values[i].put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, Integer.valueOf(base + i));
|
||||
values[i].put(MediaStore.Audio.Playlists.Members.AUDIO_ID, toAdd[i]);
|
||||
}
|
||||
resolver.bulkInsert(uri, values);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -252,7 +388,6 @@ public class Song implements Parcelable {
|
||||
*/
|
||||
public static long[] getAllSongIdsWith(int type, long id)
|
||||
{
|
||||
ContentResolver resolver = ContextApplication.getContext().getContentResolver();
|
||||
Cursor cursor;
|
||||
|
||||
switch (type) {
|
||||
@ -260,10 +395,10 @@ public class Song implements Parcelable {
|
||||
return new long[] { id };
|
||||
case TYPE_ARTIST:
|
||||
case TYPE_ALBUM:
|
||||
cursor = getMediaCursor(resolver, type, id);
|
||||
cursor = getMediaCursor(type, id);
|
||||
break;
|
||||
case TYPE_PLAYLIST:
|
||||
cursor = getPlaylistCursor(resolver, id);
|
||||
cursor = getPlaylistCursor(id);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Specified type not valid: " + type);
|
||||
|
@ -40,6 +40,7 @@ import android.view.ContextMenu;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.SubMenu;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewStub;
|
||||
@ -102,6 +103,11 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
|
||||
|
||||
mLimiterViews = (ViewGroup)findViewById(R.id.limiter_layout);
|
||||
|
||||
setupView(R.id.artist_list, new MediaAdapter(this, Song.TYPE_ARTIST, true, false));
|
||||
setupView(R.id.album_list, new MediaAdapter(this, Song.TYPE_ALBUM, true, false));
|
||||
setupView(R.id.song_list, new SongMediaAdapter(this, false, false));
|
||||
setupView(R.id.playlist_list, new MediaAdapter(this, Song.TYPE_PLAYLIST, false, true));
|
||||
|
||||
mHandler.sendEmptyMessage(MSG_INIT);
|
||||
}
|
||||
|
||||
@ -201,7 +207,7 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the PlaybackService that we are finished enqueuing songs.
|
||||
* Tell the PlaybackService that we are finished enqueueing songs.
|
||||
*/
|
||||
private void sendFinishEnqueueing()
|
||||
{
|
||||
@ -321,25 +327,64 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
|
||||
private static final int MENU_PLAY = 0;
|
||||
private static final int MENU_ENQUEUE = 1;
|
||||
private static final int MENU_EXPAND = 2;
|
||||
private static final int MENU_ADD_TO_PLAYLIST = 3;
|
||||
private static final int MENU_NEW_PLAYLIST = 4;
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo absInfo)
|
||||
public void onCreateContextMenu(ContextMenu menu, View listView, ContextMenu.ContextMenuInfo absInfo)
|
||||
{
|
||||
menu.setHeaderTitle(((MediaAdapter.MediaView)((AdapterView.AdapterContextMenuInfo)absInfo).targetView).getTitle());
|
||||
MediaAdapter.MediaView view = (MediaAdapter.MediaView)((AdapterView.AdapterContextMenuInfo)absInfo).targetView;
|
||||
int type = view.getMediaType();
|
||||
int id = (int)view.getMediaId();
|
||||
|
||||
menu.setHeaderTitle(view.getTitle());
|
||||
menu.add(0, MENU_PLAY, 0, R.string.play);
|
||||
menu.add(0, MENU_ENQUEUE, 0, R.string.enqueue);
|
||||
if (((MediaAdapter)((ListView)view).getAdapter()).hasExpanders())
|
||||
SubMenu playlistMenu = menu.addSubMenu(0, MENU_ADD_TO_PLAYLIST, 0, R.string.add_to_playlist);
|
||||
if (view.hasExpanders())
|
||||
menu.add(0, MENU_EXPAND, 0, R.string.expand);
|
||||
|
||||
playlistMenu.add(type, MENU_NEW_PLAYLIST, id, R.string.new_playlist);
|
||||
Song.Playlist[] playlists = Song.getPlaylists();
|
||||
for (int i = 0; i != playlists.length; ++i)
|
||||
playlistMenu.add(type, (int)playlists[i].id + 100, id, playlists[i].name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a set of songs to a playlists. Sets can be all songs from an artist,
|
||||
* album, playlist, or a single song. Displays a Toast notifying of
|
||||
* success.
|
||||
*
|
||||
* @param playlistId The MediaStore.Audio.Playlists id of the playlist to
|
||||
* be modified.
|
||||
* @param type The type of media the mediaId represents; one of the
|
||||
* Song.TYPE_* constants.
|
||||
* @param mediaId The MediaStore id of the element to be added.
|
||||
* @param title The title of the playlist being added to (used for the
|
||||
* Toast).
|
||||
*/
|
||||
private void addToPlaylist(long playlistId, int type, long mediaId, CharSequence title)
|
||||
{
|
||||
long[] ids = Song.getAllSongIdsWith(type, mediaId);
|
||||
Song.addToPlaylist(playlistId, ids);
|
||||
|
||||
String message = getResources().getQuantityString(R.plurals.added_to_playlist, ids.length, ids.length, title);
|
||||
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onContextItemSelected(MenuItem item)
|
||||
{
|
||||
MediaAdapter.MediaView view = (MediaAdapter.MediaView)((AdapterView.AdapterContextMenuInfo)item.getMenuInfo()).targetView;
|
||||
String action = PlaybackService.ACTION_PLAY_ITEMS;
|
||||
switch (item.getItemId()) {
|
||||
int id = item.getItemId();
|
||||
final int type = item.getGroupId();
|
||||
final int mediaId = item.getOrder();
|
||||
|
||||
switch (id) {
|
||||
case MENU_EXPAND:
|
||||
expand(view);
|
||||
expand((MediaAdapter.MediaView)((AdapterView.AdapterContextMenuInfo)item.getMenuInfo()).targetView);
|
||||
break;
|
||||
case MENU_ADD_TO_PLAYLIST:
|
||||
break;
|
||||
case MENU_ENQUEUE:
|
||||
action = PlaybackService.ACTION_ENQUEUE_ITEMS;
|
||||
@ -347,15 +392,24 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
|
||||
case MENU_PLAY:
|
||||
if (mDefaultIsLastAction)
|
||||
mDefaultAction = action;
|
||||
sendSongIntent(view, action);
|
||||
sendSongIntent((MediaAdapter.MediaView)((AdapterView.AdapterContextMenuInfo)item.getMenuInfo()).targetView, action);
|
||||
break;
|
||||
case MENU_NEW_PLAYLIST:
|
||||
NewPlaylistDialog dialog = new NewPlaylistDialog(this);
|
||||
Message message = mHandler.obtainMessage(MSG_NEW_PLAYLIST, type, mediaId);
|
||||
message.obj = dialog;
|
||||
dialog.setDismissMessage(message);
|
||||
dialog.show();
|
||||
break;
|
||||
default:
|
||||
if (id > 100)
|
||||
addToPlaylist(id - 100, type, mediaId, item.getTitle());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
@ -398,32 +452,41 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
|
||||
final ListView view = (ListView)findViewById(id);
|
||||
view.setOnItemClickListener(this);
|
||||
view.setOnCreateContextMenuListener(this);
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run()
|
||||
{
|
||||
view.setAdapter(adapter);
|
||||
}
|
||||
});
|
||||
view.setAdapter(adapter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the initialization that may be done in the background outside
|
||||
* of onCreate.
|
||||
*/
|
||||
private static final int MSG_INIT = 10;
|
||||
/**
|
||||
* Call addToPlaylist with the paramaters from the given message. The
|
||||
* message must contain the type and id of the media to be added in
|
||||
* arg1 and arg2, respectively. The obj field must be a NewPlaylistDialog
|
||||
* that the name will be taken from.
|
||||
*/
|
||||
private static final int MSG_NEW_PLAYLIST = 11;
|
||||
|
||||
@Override
|
||||
public boolean handleMessage(Message message)
|
||||
{
|
||||
switch (message.what) {
|
||||
case MSG_INIT:
|
||||
setupView(R.id.artist_list, new MediaAdapter(this, Song.TYPE_ARTIST, true, false));
|
||||
setupView(R.id.album_list, new MediaAdapter(this, Song.TYPE_ALBUM, true, false));
|
||||
setupView(R.id.song_list, new SongMediaAdapter(this, false, false));
|
||||
setupView(R.id.playlist_list, new MediaAdapter(this, Song.TYPE_PLAYLIST, false, true));
|
||||
|
||||
ContentResolver resolver = getContentResolver();
|
||||
Observer observer = new Observer(mHandler);
|
||||
resolver.registerContentObserver(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, true, observer);
|
||||
break;
|
||||
case MSG_NEW_PLAYLIST:
|
||||
NewPlaylistDialog dialog = (NewPlaylistDialog)message.obj;
|
||||
if (dialog.isAccepted()) {
|
||||
String name = dialog.getText();
|
||||
long playlistId = Song.createPlaylist(name);
|
||||
addToPlaylist(playlistId, message.arg1, message.arg2, name);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
return super.handleMessage(message);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user