diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8ff76a6c..3d95db89 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,7 @@ - + diff --git a/app/src/main/java/com/kabouzeid/materialmusic/adapter/PlayingQueueAdapter.java b/app/src/main/java/com/kabouzeid/materialmusic/adapter/PlayingQueueAdapter.java index fcb5d7f0..6baccce8 100644 --- a/app/src/main/java/com/kabouzeid/materialmusic/adapter/PlayingQueueAdapter.java +++ b/app/src/main/java/com/kabouzeid/materialmusic/adapter/PlayingQueueAdapter.java @@ -1,17 +1,26 @@ package com.kabouzeid.materialmusic.adapter; import android.content.Context; +import android.content.Intent; import android.view.LayoutInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; +import android.widget.PopupMenu; import android.widget.TextView; import com.kabouzeid.materialmusic.App; import com.kabouzeid.materialmusic.R; +import com.kabouzeid.materialmusic.adapter.songadapter.SongAdapter; +import com.kabouzeid.materialmusic.helper.SongDetailDialogHelper; +import com.kabouzeid.materialmusic.loader.SongFileLoader; +import com.kabouzeid.materialmusic.misc.AppKeys; import com.kabouzeid.materialmusic.model.Song; +import com.kabouzeid.materialmusic.ui.activities.tageditor.SongTagEditorActivity; +import java.io.File; import java.util.List; /** @@ -20,11 +29,13 @@ import java.util.List; public class PlayingQueueAdapter extends ArrayAdapter { private Context context; private App app; + private SongAdapter.GoToAble goToAble; - public PlayingQueueAdapter(Context context, List playList) { + public PlayingQueueAdapter(Context context, SongAdapter.GoToAble goToAble, List playList) { super(context, R.layout.item_playlist, playList); this.context = context; app = (App) context.getApplicationContext(); + this.goToAble = goToAble; } @Override @@ -35,6 +46,7 @@ public class PlayingQueueAdapter extends ArrayAdapter { } final TextView title = (TextView) convertView.findViewById(R.id.song_title); final ImageView playingIndicator = (ImageView) convertView.findViewById(R.id.playing_indicator); + final ImageView overflowButton = (ImageView) convertView.findViewById(R.id.menu); title.setText(song.title); if (app.getMusicPlayerRemote().getPosition() == position) { @@ -44,6 +56,43 @@ public class PlayingQueueAdapter extends ArrayAdapter { playingIndicator.setVisibility(View.GONE); playingIndicator.setImageBitmap(null); } + + overflowButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(final View v) { + PopupMenu popupMenu = new PopupMenu(context, v); + popupMenu.inflate(R.menu.menu_song); + popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_tag_editor: + Intent intent = new Intent(context, SongTagEditorActivity.class); + intent.putExtra(AppKeys.E_ID, song.id); + context.startActivity(intent); + return true; + case R.id.action_details: + String songFilePath = SongFileLoader.getSongFile(context, song.id); + File songFile = new File(songFilePath); + SongDetailDialogHelper.getDialog(context, songFile).show(); + return true; + case R.id.action_go_to_album: + if (goToAble != null) { + goToAble.goToAlbum(song.albumId); + } + return true; + case R.id.action_go_to_artist: + if (goToAble != null) { + goToAble.goToArtist(song.artistId); + } + return true; + } + return false; + } + }); + popupMenu.show(); + } + }); return convertView; } } diff --git a/app/src/main/java/com/kabouzeid/materialmusic/helper/PlayingQueueDialogHelper.java b/app/src/main/java/com/kabouzeid/materialmusic/helper/PlayingQueueDialogHelper.java index d6206d4c..66075554 100644 --- a/app/src/main/java/com/kabouzeid/materialmusic/helper/PlayingQueueDialogHelper.java +++ b/app/src/main/java/com/kabouzeid/materialmusic/helper/PlayingQueueDialogHelper.java @@ -1,19 +1,30 @@ package com.kabouzeid.materialmusic.helper; import android.content.Context; +import android.view.View; +import android.widget.AdapterView; import com.afollestad.materialdialogs.MaterialDialog; import com.kabouzeid.materialmusic.App; import com.kabouzeid.materialmusic.R; import com.kabouzeid.materialmusic.adapter.PlayingQueueAdapter; +import com.kabouzeid.materialmusic.adapter.songadapter.SongAdapter; +import com.kabouzeid.materialmusic.model.Song; import com.mobeta.android.dslv.DragSortListView; +import java.util.List; + /** * Created by karim on 24.01.15. */ public class PlayingQueueDialogHelper { - public static MaterialDialog getDialog(Context context) { + public static MaterialDialog getDialog(Context context, SongAdapter.GoToAble goToAble) { final App app = (App) context.getApplicationContext(); + List playingQueue = app.getMusicPlayerRemote().getPlayingQueue(); + if (playingQueue.isEmpty()) { + return null; + } + MaterialDialog dialog = new MaterialDialog.Builder(context) .title(context.getResources().getString(R.string.label_current_playing_queue)) .customView(R.layout.dialog_playlist, false) @@ -33,8 +44,15 @@ public class PlayingQueueDialogHelper { }) .build(); final DragSortListView dragSortListView = (DragSortListView) dialog.getCustomView().findViewById(R.id.dragSortListView); - final PlayingQueueAdapter playingQueueAdapter = new PlayingQueueAdapter(context, app.getMusicPlayerRemote().getPlayingQueue()); + final PlayingQueueAdapter playingQueueAdapter = new PlayingQueueAdapter(context, goToAble, playingQueue); dragSortListView.setAdapter(playingQueueAdapter); + dragSortListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + app.getMusicPlayerRemote().playSongAt(position); + playingQueueAdapter.notifyDataSetChanged(); + } + }); dragSortListView.setDropListener(new DragSortListView.DropListener() { @Override public void drop(int from, int to) { diff --git a/app/src/main/java/com/kabouzeid/materialmusic/model/MusicRemoteEvent.java b/app/src/main/java/com/kabouzeid/materialmusic/model/MusicRemoteEvent.java index a0f31636..74b57baa 100644 --- a/app/src/main/java/com/kabouzeid/materialmusic/model/MusicRemoteEvent.java +++ b/app/src/main/java/com/kabouzeid/materialmusic/model/MusicRemoteEvent.java @@ -10,18 +10,19 @@ public class MusicRemoteEvent { public static final int STOP = 3; public static final int NEXT = 4; public static final int PREV = 5; + public static final int TRACK_CHANGED = 6; - public static final int SONG_COMPLETED = 6; - public static final int QUEUE_COMPLETED = 7; + public static final int SONG_COMPLETED = 7; + public static final int QUEUE_COMPLETED = 8; - public static final int SERVICE_CONNECTED = 8; - public static final int SERVICE_DISCONNECTED = 9; + public static final int SERVICE_CONNECTED = 9; + public static final int SERVICE_DISCONNECTED = 10; - public static final int STATE_SAVED = 10; - public static final int STATE_RESTORED = 11; + public static final int STATE_SAVED = 11; + public static final int STATE_RESTORED = 12; - public static final int SHUFFLE_MODE_CHANGED = 12; - public static final int REPEAT_MODE_CHANGED = 13; + public static final int SHUFFLE_MODE_CHANGED = 13; + public static final int REPEAT_MODE_CHANGED = 14; private int action; diff --git a/app/src/main/java/com/kabouzeid/materialmusic/provider/AlbumJSONStore.java b/app/src/main/java/com/kabouzeid/materialmusic/provider/AlbumJSONStore.java index cd3d6605..fc0179ae 100644 --- a/app/src/main/java/com/kabouzeid/materialmusic/provider/AlbumJSONStore.java +++ b/app/src/main/java/com/kabouzeid/materialmusic/provider/AlbumJSONStore.java @@ -21,6 +21,10 @@ public class AlbumJSONStore extends SQLiteOpenHelper { sInstance = new AlbumJSONStore(context.getApplicationContext()); } return sInstance; + } + + public static void deleteDatabase(final Context context) { + context.deleteDatabase(DATABASE_NAME); } @Override public void onCreate(final SQLiteDatabase db) { db.execSQL("CREATE TABLE IF NOT EXISTS " + AlbumJSONColumns.NAME + @@ -29,14 +33,6 @@ public class AlbumJSONStore extends SQLiteOpenHelper { ); } - public static void deleteDatabase(final Context context) { - context.deleteDatabase(DATABASE_NAME); - } @Override - public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) { - db.execSQL("DROP TABLE IF EXISTS " + AlbumJSONColumns.NAME); - onCreate(db); - } - public void addAlbumJSON(final String albumAndArtistName, final String JSON) { if (albumAndArtistName == null || JSON == null) { return; @@ -80,6 +76,10 @@ public class AlbumJSONStore extends SQLiteOpenHelper { cursor.close(); } return null; + } @Override + public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) { + db.execSQL("DROP TABLE IF EXISTS " + AlbumJSONColumns.NAME); + onCreate(db); } public void removeItem(final String albumAndArtistName) { @@ -100,4 +100,5 @@ public class AlbumJSONStore extends SQLiteOpenHelper { + } diff --git a/app/src/main/java/com/kabouzeid/materialmusic/provider/ArtistJSONStore.java b/app/src/main/java/com/kabouzeid/materialmusic/provider/ArtistJSONStore.java index f9bce410..f5247846 100644 --- a/app/src/main/java/com/kabouzeid/materialmusic/provider/ArtistJSONStore.java +++ b/app/src/main/java/com/kabouzeid/materialmusic/provider/ArtistJSONStore.java @@ -21,6 +21,10 @@ public class ArtistJSONStore extends SQLiteOpenHelper { sInstance = new ArtistJSONStore(context.getApplicationContext()); } return sInstance; + } + + public static void deleteDatabase(final Context context) { + context.deleteDatabase(DATABASE_NAME); } @Override public void onCreate(final SQLiteDatabase db) { db.execSQL("CREATE TABLE IF NOT EXISTS " + ArtistJSONColumns.NAME + @@ -29,14 +33,6 @@ public class ArtistJSONStore extends SQLiteOpenHelper { ); } - public static void deleteDatabase(final Context context) { - context.deleteDatabase(DATABASE_NAME); - } @Override - public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) { - db.execSQL("DROP TABLE IF EXISTS " + ArtistJSONColumns.NAME); - onCreate(db); - } - public void addArtistJSON(final String artistName, final String JSON) { if (artistName == null || JSON == null) { return; @@ -80,6 +76,10 @@ public class ArtistJSONStore extends SQLiteOpenHelper { cursor.close(); } return null; + } @Override + public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) { + db.execSQL("DROP TABLE IF EXISTS " + ArtistJSONColumns.NAME); + onCreate(db); } public void removeItem(final String artistName) { @@ -100,4 +100,5 @@ public class ArtistJSONStore extends SQLiteOpenHelper { + } diff --git a/app/src/main/java/com/kabouzeid/materialmusic/service/MusicService.java b/app/src/main/java/com/kabouzeid/materialmusic/service/MusicService.java index ea210211..f0b1c851 100644 --- a/app/src/main/java/com/kabouzeid/materialmusic/service/MusicService.java +++ b/app/src/main/java/com/kabouzeid/materialmusic/service/MusicService.java @@ -299,6 +299,7 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe } else { Toast.makeText(this, getResources().getString(R.string.audio_focus_denied), Toast.LENGTH_SHORT).show(); } + notifyOnMusicRemoteEventListeners(MusicRemoteEvent.TRACK_CHANGED); } private boolean requestFocus() { diff --git a/app/src/main/java/com/kabouzeid/materialmusic/ui/activities/MainActivity.java b/app/src/main/java/com/kabouzeid/materialmusic/ui/activities/MainActivity.java index e352849a..78e9e682 100644 --- a/app/src/main/java/com/kabouzeid/materialmusic/ui/activities/MainActivity.java +++ b/app/src/main/java/com/kabouzeid/materialmusic/ui/activities/MainActivity.java @@ -18,8 +18,11 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; +import com.afollestad.materialdialogs.MaterialDialog; import com.kabouzeid.materialmusic.R; +import com.kabouzeid.materialmusic.helper.PlayingQueueDialogHelper; import com.kabouzeid.materialmusic.interfaces.KabSearchAbleFragment; import com.kabouzeid.materialmusic.interfaces.KabViewsDisableAble; import com.kabouzeid.materialmusic.interfaces.OnMusicRemoteEventListener; @@ -85,7 +88,6 @@ public class MainActivity extends AbsFabActivity } private void setUpToolBar() { - toolbarTitle = getTitle(); toolbar = (Toolbar) findViewById(R.id.toolbar); statusBar = findViewById(R.id.statusBar); setSupportActionBar(toolbar); @@ -253,7 +255,14 @@ public class MainActivity extends AbsFabActivity case R.id.action_current_playing: openCurrentPlayingIfPossible(null); return true; - + case R.id.action_playing_queue: + final MaterialDialog materialDialog = PlayingQueueDialogHelper.getDialog(this, this); + if (materialDialog != null) { + materialDialog.show(); + } else { + Toast.makeText(this, getResources().getString(R.string.nothing_playing), Toast.LENGTH_SHORT).show(); + } + return true; } return super.onOptionsItemSelected(item); } diff --git a/app/src/main/java/com/kabouzeid/materialmusic/ui/activities/MusicControllerActivity.java b/app/src/main/java/com/kabouzeid/materialmusic/ui/activities/MusicControllerActivity.java index a89f2069..65d562d3 100644 --- a/app/src/main/java/com/kabouzeid/materialmusic/ui/activities/MusicControllerActivity.java +++ b/app/src/main/java/com/kabouzeid/materialmusic/ui/activities/MusicControllerActivity.java @@ -16,6 +16,7 @@ import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.SeekBar; import android.widget.TextView; +import android.widget.Toast; import com.afollestad.materialdialogs.MaterialDialog; import com.kabouzeid.materialmusic.R; @@ -356,10 +357,7 @@ public class MusicControllerActivity extends AbsFabActivity implements OnMusicRe public void onMusicRemoteEvent(MusicRemoteEvent event) { super.onMusicRemoteEvent(event); switch (event.getAction()) { - case MusicRemoteEvent.NEXT: - updateCurrentSong(); - break; - case MusicRemoteEvent.PREV: + case MusicRemoteEvent.TRACK_CHANGED: updateCurrentSong(); break; case MusicRemoteEvent.REPEAT_MODE_CHANGED: @@ -399,8 +397,12 @@ public class MusicControllerActivity extends AbsFabActivity implements OnMusicRe super.onBackPressed(); return true; case R.id.action_playing_queue: - final MaterialDialog materialDialog = PlayingQueueDialogHelper.getDialog(this); - materialDialog.show(); + final MaterialDialog materialDialog = PlayingQueueDialogHelper.getDialog(this, this); + if (materialDialog != null) { + materialDialog.show(); + } else { + Toast.makeText(this, getResources().getString(R.string.nothing_playing), Toast.LENGTH_SHORT).show(); + } return true; case R.id.action_tag_editor: Intent intent = new Intent(this, SongTagEditorActivity.class); diff --git a/app/src/main/java/com/kabouzeid/materialmusic/ui/activities/tageditor/AlbumTagEditorActivity.java b/app/src/main/java/com/kabouzeid/materialmusic/ui/activities/tageditor/AlbumTagEditorActivity.java index 54420395..be7c8746 100644 --- a/app/src/main/java/com/kabouzeid/materialmusic/ui/activities/tageditor/AlbumTagEditorActivity.java +++ b/app/src/main/java/com/kabouzeid/materialmusic/ui/activities/tageditor/AlbumTagEditorActivity.java @@ -75,40 +75,6 @@ public class AlbumTagEditorActivity extends AbsTagEditorActivity implements Text year.setText(getSongYear()); } - @Override - protected void save() { - Artwork artwork = null; - Map fieldKeyValueMap = new EnumMap<>(FieldKey.class); - fieldKeyValueMap.put(FieldKey.ALBUM, albumTitle.getText().toString()); - //android seems not to recognize album_artist field so we additionally write the normal artist field - fieldKeyValueMap.put(FieldKey.ARTIST, albumArtistName.getText().toString()); - fieldKeyValueMap.put(FieldKey.ALBUM_ARTIST, albumArtistName.getText().toString()); - fieldKeyValueMap.put(FieldKey.GENRE, genreName.getText().toString()); - fieldKeyValueMap.put(FieldKey.YEAR, year.getText().toString()); - - try { - albumArtFile = MusicUtil.getAlbumArtFile(this, String.valueOf(getId())); - } catch (IOException e) { - Log.e(TAG, "error while creating albumArtFile", e); - } - - if (albumArtBitmap != null && albumArtFile != null) { - try { - albumArtBitmap.compress(Bitmap.CompressFormat.PNG, 0, new FileOutputStream(albumArtFile)); - artwork = ArtworkFactory.createArtworkFromFile(albumArtFile); - MusicUtil.insertAlbumArt(this, getId(), albumArtFile.getAbsolutePath()); - } catch (IOException e) { - Log.e(TAG, "error while trying to create the artwork from file", e); - } - } - writeValuesToFiles(fieldKeyValueMap, artwork, deleteAlbumArt); - } - - @Override - protected int getContentViewResId() { - return R.layout.activity_album_tag_editor; - } - @Override protected void loadCurrentImage() { setImageBitmap(getAlbumArt()); @@ -147,6 +113,57 @@ public class AlbumTagEditorActivity extends AbsTagEditorActivity implements Text searchWebFor(query); } + @Override + protected void deleteImage() { + setImageRes(R.drawable.default_album_art); + deleteAlbumArt = true; + dataChanged(); + } + + @Override + protected void save() { + Artwork artwork = null; + Map fieldKeyValueMap = new EnumMap<>(FieldKey.class); + fieldKeyValueMap.put(FieldKey.ALBUM, albumTitle.getText().toString()); + //android seems not to recognize album_artist field so we additionally write the normal artist field + fieldKeyValueMap.put(FieldKey.ARTIST, albumArtistName.getText().toString()); + fieldKeyValueMap.put(FieldKey.ALBUM_ARTIST, albumArtistName.getText().toString()); + fieldKeyValueMap.put(FieldKey.GENRE, genreName.getText().toString()); + fieldKeyValueMap.put(FieldKey.YEAR, year.getText().toString()); + + try { + albumArtFile = MusicUtil.getAlbumArtFile(this, String.valueOf(getId())); + } catch (IOException e) { + Log.e(TAG, "error while creating albumArtFile", e); + } + + if (albumArtBitmap != null && albumArtFile != null) { + try { + albumArtBitmap.compress(Bitmap.CompressFormat.PNG, 0, new FileOutputStream(albumArtFile)); + artwork = ArtworkFactory.createArtworkFromFile(albumArtFile); + MusicUtil.insertAlbumArt(this, getId(), albumArtFile.getAbsolutePath()); + } catch (IOException e) { + Log.e(TAG, "error while trying to create the artwork from file", e); + } + } + writeValuesToFiles(fieldKeyValueMap, artwork, deleteAlbumArt); + } + + @Override + protected int getContentViewResId() { + return R.layout.activity_album_tag_editor; + } + + @Override + protected List getSongPaths() { + List songs = AlbumSongLoader.getAlbumSongList(this, getId()); + List songIds = new ArrayList<>(); + for (Song song : songs) { + songIds.add(song.id); + } + return SongFileLoader.getSongFiles(this, songIds); + } + @Override protected void loadImageFromFile(final Uri selectedFileUri) { DisplayImageOptions options = new DisplayImageOptions.Builder() @@ -167,23 +184,6 @@ public class AlbumTagEditorActivity extends AbsTagEditorActivity implements Text } } - @Override - protected void deleteImage() { - setImageRes(R.drawable.default_album_art); - deleteAlbumArt = true; - dataChanged(); - } - - @Override - protected List getSongPaths() { - List songs = AlbumSongLoader.getAlbumSongList(this, getId()); - List songIds = new ArrayList<>(); - for (Song song : songs) { - songIds.add(song.id); - } - return SongFileLoader.getSongFiles(this, songIds); - } - @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { diff --git a/app/src/main/java/com/kabouzeid/materialmusic/ui/activities/tageditor/SongTagEditorActivity.java b/app/src/main/java/com/kabouzeid/materialmusic/ui/activities/tageditor/SongTagEditorActivity.java index 8f3688ea..b81cf929 100644 --- a/app/src/main/java/com/kabouzeid/materialmusic/ui/activities/tageditor/SongTagEditorActivity.java +++ b/app/src/main/java/com/kabouzeid/materialmusic/ui/activities/tageditor/SongTagEditorActivity.java @@ -64,6 +64,26 @@ public class SongTagEditorActivity extends AbsTagEditorActivity implements TextW trackNumber.setText(getTrackNumber()); } + @Override + protected void loadCurrentImage() { + + } + + @Override + protected void getImageFromLastFM() { + + } + + @Override + protected void searchImageOnWeb() { + + } + + @Override + protected void deleteImage() { + + } + @Override protected void save() { Map fieldKeyValueMap = new EnumMap<>(FieldKey.class); @@ -82,18 +102,10 @@ public class SongTagEditorActivity extends AbsTagEditorActivity implements TextW } @Override - protected void loadCurrentImage() { - - } - - @Override - protected void getImageFromLastFM() { - - } - - @Override - protected void searchImageOnWeb() { - + protected List getSongPaths() { + List tempIdList = new ArrayList<>(); + tempIdList.add(getId()); + return SongFileLoader.getSongFiles(this, tempIdList); } @Override @@ -101,18 +113,6 @@ public class SongTagEditorActivity extends AbsTagEditorActivity implements TextW } - @Override - protected void deleteImage() { - - } - - @Override - protected List getSongPaths() { - List tempIdList = new ArrayList<>(); - tempIdList.add(getId()); - return SongFileLoader.getSongFiles(this, tempIdList); - } - @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { diff --git a/app/src/main/res/layout/tab_indicator.xml b/app/src/main/res/layout/tab_indicator.xml index 79d7d004..a3f2d5b3 100644 --- a/app/src/main/res/layout/tab_indicator.xml +++ b/app/src/main/res/layout/tab_indicator.xml @@ -13,13 +13,14 @@ See the License for the specific language governing permissions and limitations under the License. --> - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/menu/drawer.xml b/app/src/main/res/menu/drawer.xml index 44a4dc39..bfe649f2 100644 --- a/app/src/main/res/menu/drawer.xml +++ b/app/src/main/res/menu/drawer.xml @@ -7,7 +7,7 @@ android:id="@+id/action_current_playing" android:icon="@drawable/music_box" android:title="@string/action_current_playing" - app:showAsAction="ifRoom"/> + app:showAsAction="always"/> + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/menu_song.xml b/app/src/main/res/menu/menu_song.xml index 595f321b..97a5d024 100644 --- a/app/src/main/res/menu/menu_song.xml +++ b/app/src/main/res/menu/menu_song.xml @@ -7,7 +7,7 @@ app:showAsAction="never"/> Playing queue Search Play next - Add to playing queue" - Add to playlist..." + Add to playing queue" + Remove from playing queue + Add to playlist…" Tag Editor" Delete from disk" Details - Go to... + Go to… Albums Artists Genres @@ -55,7 +56,7 @@ Length Bitrate Sampling rate - ok + OK Go to artist Go to album Playing queue