This commit is contained in:
Karim Abou Zeid 2015-04-11 19:56:09 +02:00
commit bce9de2782
22 changed files with 303 additions and 217 deletions

View file

@ -23,8 +23,8 @@ android {
applicationId "com.kabouzeid.gramophone" applicationId "com.kabouzeid.gramophone"
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 22 targetSdkVersion 22
versionCode 13 versionCode 16
versionName "0.9.6.3b" versionName "0.9.8b"
} }
compileOptions { compileOptions {

View file

@ -19,8 +19,66 @@
android:label="@string/app_name" > android:label="@string/app_name" >
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.MUSIC_PLAYER" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.APP_MUSIC" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="content" />
<data android:mimeType="audio/*" />
<data android:mimeType="application/ogg" />
<data android:mimeType="application/x-ogg" />
<data android:mimeType="application/itunes" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:mimeType="audio/*" />
<data android:mimeType="application/ogg" />
<data android:mimeType="application/x-ogg" />
<data android:mimeType="application/itunes" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:mimeType="audio/*" />
<data android:mimeType="application/ogg" />
<data android:mimeType="application/x-ogg" />
<data android:mimeType="application/itunes" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.dir/playlist" />
<data android:mimeType="vnd.android.cursor.dir/albums" />
<data android:mimeType="vnd.android.cursor.dir/artists" />
</intent-filter>
<intent-filter>
<action android:name="com.cyanogenmod.eleven.AUDIO_PLAYER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.OPENABLE" />
<data android:mimeType="vnd.android.cursor.dir/audio"/>
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".ui.activities.AlbumDetailActivity" > <activity android:name=".ui.activities.AlbumDetailActivity" >

View file

@ -15,6 +15,7 @@ import android.widget.Toast;
import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.helper.AddToPlaylistDialogHelper; import com.kabouzeid.gramophone.helper.AddToPlaylistDialogHelper;
import com.kabouzeid.gramophone.helper.DeleteSongsDialogHelper; import com.kabouzeid.gramophone.helper.DeleteSongsDialogHelper;
import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
import com.kabouzeid.gramophone.helper.MusicPlayerRemote; import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.helper.SongDetailDialogHelper; import com.kabouzeid.gramophone.helper.SongDetailDialogHelper;
import com.kabouzeid.gramophone.loader.SongFilePathLoader; import com.kabouzeid.gramophone.loader.SongFilePathLoader;
@ -64,39 +65,7 @@ public class PlayingQueueAdapter extends ArrayAdapter<Song> {
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override @Override
public boolean onMenuItemClick(MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) { return MenuItemClickHelper.handleSongMenuClick(activity, song, item);
case R.id.action_delete_from_disk:
DeleteSongsDialogHelper.getDialog(activity, song).show();
return true;
case R.id.action_add_to_playlist:
AddToPlaylistDialogHelper.getDialog(activity, song).show();
return true;
case R.id.action_remove_from_playing_queue:
MusicPlayerRemote.removeFromQueue(position);
notifyDataSetChanged();
return true;
case R.id.action_play_next:
MusicPlayerRemote.playNext(song);
notifyDataSetChanged();
return true;
case R.id.action_tag_editor:
Intent intent = new Intent(activity, SongTagEditorActivity.class);
intent.putExtra(AppKeys.E_ID, song.id);
activity.startActivity(intent);
return true;
case R.id.action_details:
String songFilePath = SongFilePathLoader.getSongFilePath(activity, song.id);
File songFile = new File(songFilePath);
SongDetailDialogHelper.getDialog(activity, songFile).show();
return true;
case R.id.action_go_to_album:
NavigationUtil.goToAlbum(activity, song.albumId, null);
return true;
case R.id.action_go_to_artist:
NavigationUtil.goToArtist(activity, song.artistId, null);
return true;
}
return false;
} }
}); });
popupMenu.show(); popupMenu.show();

View file

@ -1,10 +1,8 @@
package com.kabouzeid.gramophone.adapter; package com.kabouzeid.gramophone.adapter;
import android.app.Activity; import android.app.Activity;
import android.graphics.Color;
import android.support.v4.util.Pair; import android.support.v4.util.Pair;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
@ -15,16 +13,13 @@ import android.widget.TextView;
import com.kabouzeid.gramophone.App; import com.kabouzeid.gramophone.App;
import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.helper.DeletePlaylistDialogHelper; import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
import com.kabouzeid.gramophone.helper.RenamePlaylistDialogHelper;
import com.kabouzeid.gramophone.loader.PlaylistLoader; import com.kabouzeid.gramophone.loader.PlaylistLoader;
import com.kabouzeid.gramophone.model.DataBaseChangedEvent; import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
import com.kabouzeid.gramophone.model.Playlist; import com.kabouzeid.gramophone.model.Playlist;
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity; import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
import com.kabouzeid.gramophone.util.NavigationUtil; import com.kabouzeid.gramophone.util.NavigationUtil;
import com.kabouzeid.gramophone.util.Util;
import com.squareup.otto.Subscribe; import com.squareup.otto.Subscribe;
import com.squareup.picasso.Picasso;
import java.util.List; import java.util.List;
@ -78,15 +73,7 @@ public class PlaylistAdapter extends RecyclerView.Adapter<PlaylistAdapter.ViewHo
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override @Override
public boolean onMenuItemClick(MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) { return MenuItemClickHelper.handlePlaylistMenuClick(activity, dataSet.get(getAdapterPosition()), item);
case R.id.action_rename_playlist:
RenamePlaylistDialogHelper.getDialog(activity, dataSet.get(getAdapterPosition()).id).show();
return true;
case R.id.action_delete_playlist:
DeletePlaylistDialogHelper.getDialog(activity, dataSet.get(getAdapterPosition()).id).show();
return true;
}
return false;
} }
}); });
popupMenu.show(); popupMenu.show();

View file

@ -1,16 +1,19 @@
package com.kabouzeid.gramophone.adapter; package com.kabouzeid.gramophone.adapter;
import android.content.Context; import android.app.Activity;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.PopupMenu;
import android.widget.TextView; import android.widget.TextView;
import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
import com.kabouzeid.gramophone.model.SearchEntry; import com.kabouzeid.gramophone.model.SearchEntry;
import com.kabouzeid.gramophone.model.Song; import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.ui.activities.SearchActivity; import com.kabouzeid.gramophone.ui.activities.SearchActivity;
@ -21,10 +24,12 @@ import java.util.List;
/** /**
* Created by karim on 27.02.15. * Created by karim on 27.02.15.
*/ */
public class SearchAdapter extends ArrayAdapter<SearchEntry> { public class SearchAdapter extends ArrayAdapter<SearchEntry>{
private Activity activity;
public SearchAdapter(Context context, List<SearchEntry> objects) { public SearchAdapter(Activity activity, List<SearchEntry> objects) {
super(context, R.layout.item_list_search, objects); super(activity, R.layout.item_list_search, objects);
this.activity = activity;
} }
@Override @Override
@ -33,26 +38,44 @@ public class SearchAdapter extends ArrayAdapter<SearchEntry> {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_list_search, parent, false); convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_list_search, parent, false);
} }
SearchEntry item = getItem(position); final SearchEntry item = getItem(position);
final TextView title = (TextView) convertView.findViewById(R.id.title); final TextView title = (TextView) convertView.findViewById(R.id.title);
final TextView subTitle = (TextView) convertView.findViewById(R.id.sub_title); final TextView subTitle = (TextView) convertView.findViewById(R.id.sub_title);
final ImageView imageView = (ImageView) convertView.findViewById(R.id.image); final ImageView imageView = (ImageView) convertView.findViewById(R.id.image);
final ImageView overflowButton = (ImageView) convertView.findViewById(R.id.menu);
if (item instanceof SearchActivity.LabelEntry) { if (item instanceof SearchActivity.LabelEntry) {
title.setTypeface(null, Typeface.BOLD); title.setTypeface(null, Typeface.BOLD);
subTitle.setVisibility(View.GONE); subTitle.setVisibility(View.GONE);
imageView.setVisibility(View.GONE); imageView.setVisibility(View.GONE);
overflowButton.setVisibility(View.GONE);
convertView.setBackgroundColor(Util.resolveColor(getContext(), R.attr.default_bar_color)); convertView.setBackgroundColor(Util.resolveColor(getContext(), R.attr.default_bar_color));
} else if (item instanceof Song) { } else if (item instanceof Song) {
title.setTypeface(null, Typeface.NORMAL); title.setTypeface(null, Typeface.NORMAL);
subTitle.setVisibility(View.VISIBLE); subTitle.setVisibility(View.VISIBLE);
imageView.setVisibility(View.GONE); imageView.setVisibility(View.GONE);
convertView.setBackgroundColor(Color.TRANSPARENT); convertView.setBackgroundColor(Color.TRANSPARENT);
overflowButton.setVisibility(View.VISIBLE);
overflowButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
PopupMenu popupMenu = new PopupMenu(activity, view);
popupMenu.inflate(R.menu.menu_item_song);
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
return MenuItemClickHelper.handleSongMenuClick(activity, (Song) item, menuItem);
}
});
popupMenu.show();
}
});
} else { } else {
title.setTypeface(null, Typeface.NORMAL); title.setTypeface(null, Typeface.NORMAL);
subTitle.setVisibility(View.VISIBLE); subTitle.setVisibility(View.VISIBLE);
imageView.setVisibility(View.VISIBLE); imageView.setVisibility(View.VISIBLE);
overflowButton.setVisibility(View.GONE);
convertView.setBackgroundColor(Color.TRANSPARENT); convertView.setBackgroundColor(Color.TRANSPARENT);
} }

View file

@ -15,6 +15,7 @@ import android.widget.TextView;
import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.helper.AddToPlaylistDialogHelper; import com.kabouzeid.gramophone.helper.AddToPlaylistDialogHelper;
import com.kabouzeid.gramophone.helper.DeleteSongsDialogHelper; import com.kabouzeid.gramophone.helper.DeleteSongsDialogHelper;
import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
import com.kabouzeid.gramophone.helper.MusicPlayerRemote; import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.helper.SongDetailDialogHelper; import com.kabouzeid.gramophone.helper.SongDetailDialogHelper;
import com.kabouzeid.gramophone.loader.SongFilePathLoader; import com.kabouzeid.gramophone.loader.SongFilePathLoader;
@ -92,43 +93,7 @@ public class AlbumSongAdapter extends RecyclerView.Adapter<AlbumSongAdapter.View
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override @Override
public boolean onMenuItemClick(MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) { return MenuItemClickHelper.handleSongMenuClick(activity, dataSet.get(getAdapterPosition()), item);
case R.id.action_delete_from_disk:
DeleteSongsDialogHelper.getDialog(activity, dataSet.get(getAdapterPosition())).show();
return true;
case R.id.action_add_to_playlist:
AddToPlaylistDialogHelper.getDialog(activity, dataSet.get(getAdapterPosition())).show();
return true;
case R.id.action_play_next:
MusicPlayerRemote.playNext(dataSet.get(getAdapterPosition()));
return true;
case R.id.action_add_to_current_playing:
MusicPlayerRemote.enqueue(dataSet.get(getAdapterPosition()));
return true;
case R.id.action_tag_editor:
Intent intent = new Intent(activity, SongTagEditorActivity.class);
intent.putExtra(AppKeys.E_ID, dataSet.get(getAdapterPosition()).id);
activity.startActivity(intent);
return true;
case R.id.action_details:
String songFilePath = SongFilePathLoader.getSongFilePath(activity, dataSet.get(getAdapterPosition()).id);
File songFile = new File(songFilePath);
SongDetailDialogHelper.getDialog(activity, songFile).show();
return true;
case R.id.action_go_to_album:
Pair[] albumPairs = null;
if (activity instanceof AbsFabActivity)
albumPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(albumPairs);
NavigationUtil.goToAlbum(activity, dataSet.get(getAdapterPosition()).albumId, albumPairs);
return true;
case R.id.action_go_to_artist:
Pair[] artistPairs = null;
if (activity instanceof AbsFabActivity)
artistPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(artistPairs);
NavigationUtil.goToArtist(activity, dataSet.get(getAdapterPosition()).artistId, artistPairs);
return true;
}
return false;
} }
}); });
popupMenu.show(); popupMenu.show();

View file

@ -16,6 +16,7 @@ import android.widget.Toast;
import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.helper.AddToPlaylistDialogHelper; import com.kabouzeid.gramophone.helper.AddToPlaylistDialogHelper;
import com.kabouzeid.gramophone.helper.DeleteSongsDialogHelper; import com.kabouzeid.gramophone.helper.DeleteSongsDialogHelper;
import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
import com.kabouzeid.gramophone.helper.MusicPlayerRemote; import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.helper.SongDetailDialogHelper; import com.kabouzeid.gramophone.helper.SongDetailDialogHelper;
import com.kabouzeid.gramophone.loader.SongFilePathLoader; import com.kabouzeid.gramophone.loader.SongFilePathLoader;
@ -70,28 +71,6 @@ public class ArtistSongAdapter extends ArrayAdapter<Song> {
@Override @Override
public boolean onMenuItemClick(MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.action_delete_from_disk:
DeleteSongsDialogHelper.getDialog(activity, song).show();
return true;
case R.id.action_add_to_playlist:
AddToPlaylistDialogHelper.getDialog(activity, song).show();
return true;
case R.id.action_play_next:
MusicPlayerRemote.playNext(song);
return true;
case R.id.action_add_to_current_playing:
MusicPlayerRemote.enqueue(song);
return true;
case R.id.action_tag_editor:
Intent intent = new Intent(activity, SongTagEditorActivity.class);
intent.putExtra(AppKeys.E_ID, song.id);
activity.startActivity(intent);
return true;
case R.id.action_details:
String songFilePath = SongFilePathLoader.getSongFilePath(activity, song.id);
File songFile = new File(songFilePath);
SongDetailDialogHelper.getDialog(activity, songFile).show();
return true;
case R.id.action_go_to_album: case R.id.action_go_to_album:
Pair[] albumPairs = new Pair[]{ Pair[] albumPairs = new Pair[]{
Pair.create(albumArt, activity.getResources().getString(R.string.transition_album_cover)) Pair.create(albumArt, activity.getResources().getString(R.string.transition_album_cover))
@ -100,14 +79,8 @@ public class ArtistSongAdapter extends ArrayAdapter<Song> {
albumPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(albumPairs); albumPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(albumPairs);
NavigationUtil.goToAlbum(activity, song.albumId, albumPairs); NavigationUtil.goToAlbum(activity, song.albumId, albumPairs);
return true; return true;
case R.id.action_go_to_artist:
Pair[] artistPairs = null;
if (activity instanceof AbsFabActivity)
artistPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(artistPairs);
NavigationUtil.goToArtist(activity, song.artistId, artistPairs);
return true;
} }
return false; return MenuItemClickHelper.handleSongMenuClick(activity, song, item);
} }
}); });
popupMenu.show(); popupMenu.show();

View file

@ -1,7 +1,6 @@
package com.kabouzeid.gramophone.adapter.songadapter; package com.kabouzeid.gramophone.adapter.songadapter;
import android.app.Activity; import android.app.Activity;
import android.content.Intent;
import android.support.v4.util.Pair; import android.support.v4.util.Pair;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -11,25 +10,17 @@ import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.PopupMenu; import android.widget.PopupMenu;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.helper.AddToPlaylistDialogHelper; import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
import com.kabouzeid.gramophone.helper.DeleteSongsDialogHelper;
import com.kabouzeid.gramophone.helper.MusicPlayerRemote; import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.helper.SongDetailDialogHelper;
import com.kabouzeid.gramophone.loader.SongFilePathLoader;
import com.kabouzeid.gramophone.misc.AppKeys;
import com.kabouzeid.gramophone.model.PlaylistSong; import com.kabouzeid.gramophone.model.PlaylistSong;
import com.kabouzeid.gramophone.model.Song; import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity; import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
import com.kabouzeid.gramophone.ui.activities.tageditor.SongTagEditorActivity;
import com.kabouzeid.gramophone.util.MusicUtil; import com.kabouzeid.gramophone.util.MusicUtil;
import com.kabouzeid.gramophone.util.NavigationUtil; import com.kabouzeid.gramophone.util.NavigationUtil;
import com.kabouzeid.gramophone.util.PlaylistsUtil;
import com.squareup.picasso.Picasso; import com.squareup.picasso.Picasso;
import java.io.File;
import java.util.List; import java.util.List;
/** /**
@ -98,33 +89,6 @@ public class PlaylistSongAdapter extends RecyclerView.Adapter<PlaylistSongAdapte
@Override @Override
public boolean onMenuItemClick(MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.action_delete_from_disk:
DeleteSongsDialogHelper.getDialog(activity, dataSet.get(getAdapterPosition())).show();
return true;
case R.id.action_add_to_playlist:
AddToPlaylistDialogHelper.getDialog(activity, dataSet.get(getAdapterPosition())).show();
return true;
case R.id.action_delete_from_playlist:
int position = getAdapterPosition();
PlaylistsUtil.removeFromPlaylist(activity, dataSet.remove(position));
notifyItemRemoved(position);
return true;
case R.id.action_play_next:
MusicPlayerRemote.playNext(dataSet.get(getAdapterPosition()));
return true;
case R.id.action_add_to_current_playing:
MusicPlayerRemote.enqueue(dataSet.get(getAdapterPosition()));
return true;
case R.id.action_tag_editor:
Intent intent = new Intent(activity, SongTagEditorActivity.class);
intent.putExtra(AppKeys.E_ID, dataSet.get(getAdapterPosition()).id);
activity.startActivity(intent);
return true;
case R.id.action_details:
String songFilePath = SongFilePathLoader.getSongFilePath(activity, dataSet.get(getAdapterPosition()).id);
File songFile = new File(songFilePath);
SongDetailDialogHelper.getDialog(activity, songFile).show();
return true;
case R.id.action_go_to_album: case R.id.action_go_to_album:
Pair[] albumPairs = new Pair[]{ Pair[] albumPairs = new Pair[]{
Pair.create(albumArt, activity.getResources().getString(R.string.transition_album_cover)) Pair.create(albumArt, activity.getResources().getString(R.string.transition_album_cover))
@ -133,14 +97,8 @@ public class PlaylistSongAdapter extends RecyclerView.Adapter<PlaylistSongAdapte
albumPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(albumPairs); albumPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(albumPairs);
NavigationUtil.goToAlbum(activity, dataSet.get(getAdapterPosition()).albumId, albumPairs); NavigationUtil.goToAlbum(activity, dataSet.get(getAdapterPosition()).albumId, albumPairs);
return true; return true;
case R.id.action_go_to_artist:
Pair[] artistPairs = null;
if (activity instanceof AbsFabActivity)
artistPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(artistPairs);
NavigationUtil.goToArtist(activity, dataSet.get(getAdapterPosition()).artistId, artistPairs);
return true;
} }
return false; return MenuItemClickHelper.handleSongMenuClick(activity, dataSet.get(getAdapterPosition()), item);
} }
}); });
popupMenu.show(); popupMenu.show();

View file

@ -17,6 +17,7 @@ import com.kabouzeid.gramophone.App;
import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.helper.AddToPlaylistDialogHelper; import com.kabouzeid.gramophone.helper.AddToPlaylistDialogHelper;
import com.kabouzeid.gramophone.helper.DeleteSongsDialogHelper; import com.kabouzeid.gramophone.helper.DeleteSongsDialogHelper;
import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
import com.kabouzeid.gramophone.helper.MusicPlayerRemote; import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.helper.SongDetailDialogHelper; import com.kabouzeid.gramophone.helper.SongDetailDialogHelper;
import com.kabouzeid.gramophone.loader.SongFilePathLoader; import com.kabouzeid.gramophone.loader.SongFilePathLoader;
@ -138,28 +139,6 @@ public class SongAdapter extends RecyclerView.Adapter<SongAdapter.ViewHolder> {
public boolean onMenuItemClick(MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
final int position = getAdapterPosition() - 1; final int position = getAdapterPosition() - 1;
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.action_delete_from_disk:
DeleteSongsDialogHelper.getDialog(activity, dataSet.get(position)).show();
return true;
case R.id.action_add_to_playlist:
AddToPlaylistDialogHelper.getDialog(activity, dataSet.get(position)).show();
return true;
case R.id.action_play_next:
MusicPlayerRemote.playNext(dataSet.get(position));
return true;
case R.id.action_add_to_current_playing:
MusicPlayerRemote.enqueue(dataSet.get(position));
return true;
case R.id.action_tag_editor:
Intent intent = new Intent(activity, SongTagEditorActivity.class);
intent.putExtra(AppKeys.E_ID, dataSet.get(position).id);
activity.startActivity(intent);
return true;
case R.id.action_details:
String songFilePath = SongFilePathLoader.getSongFilePath(activity, dataSet.get(position).id);
File songFile = new File(songFilePath);
SongDetailDialogHelper.getDialog(activity, songFile).show();
return true;
case R.id.action_go_to_album: case R.id.action_go_to_album:
Pair[] albumPairs = new Pair[]{ Pair[] albumPairs = new Pair[]{
Pair.create(albumArt, activity.getResources().getString(R.string.transition_album_cover)) Pair.create(albumArt, activity.getResources().getString(R.string.transition_album_cover))
@ -168,14 +147,8 @@ public class SongAdapter extends RecyclerView.Adapter<SongAdapter.ViewHolder> {
albumPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(albumPairs); albumPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(albumPairs);
NavigationUtil.goToAlbum(activity, dataSet.get(position).albumId, albumPairs); NavigationUtil.goToAlbum(activity, dataSet.get(position).albumId, albumPairs);
return true; return true;
case R.id.action_go_to_artist:
Pair[] artistPairs = null;
if (activity instanceof AbsFabActivity)
artistPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(artistPairs);
NavigationUtil.goToArtist(activity, dataSet.get(position).artistId, artistPairs);
return true;
} }
return false; return MenuItemClickHelper.handleSongMenuClick(activity, dataSet.get(position), item);
} }
}); });
popupMenu.show(); popupMenu.show();

View file

@ -0,0 +1,74 @@
package com.kabouzeid.gramophone.helper;
import android.app.Activity;
import android.content.Intent;
import android.support.v4.util.Pair;
import android.view.MenuItem;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.loader.SongFilePathLoader;
import com.kabouzeid.gramophone.misc.AppKeys;
import com.kabouzeid.gramophone.model.Playlist;
import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
import com.kabouzeid.gramophone.ui.activities.tageditor.SongTagEditorActivity;
import com.kabouzeid.gramophone.util.NavigationUtil;
import java.io.File;
/**
* Created by karim on 11.04.15.
*/
public class MenuItemClickHelper {
public static boolean handleSongMenuClick(Activity activity, Song song, MenuItem item){
switch (item.getItemId()) {
case R.id.action_delete_from_disk:
DeleteSongsDialogHelper.getDialog(activity, song).show();
return true;
case R.id.action_add_to_playlist:
AddToPlaylistDialogHelper.getDialog(activity, song).show();
return true;
case R.id.action_play_next:
MusicPlayerRemote.playNext(song);
return true;
case R.id.action_add_to_current_playing:
MusicPlayerRemote.enqueue(song);
return true;
case R.id.action_tag_editor:
Intent intent = new Intent(activity, SongTagEditorActivity.class);
intent.putExtra(AppKeys.E_ID, song.id);
activity.startActivity(intent);
return true;
case R.id.action_details:
String songFilePath = SongFilePathLoader.getSongFilePath(activity, song.id);
File songFile = new File(songFilePath);
SongDetailDialogHelper.getDialog(activity, songFile).show();
return true;
case R.id.action_go_to_album:
Pair[] albumPairs = null;
if (activity instanceof AbsFabActivity)
albumPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(albumPairs);
NavigationUtil.goToAlbum(activity, song.albumId, albumPairs);
return true;
case R.id.action_go_to_artist:
Pair[] artistPairs = null;
if (activity instanceof AbsFabActivity)
artistPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(artistPairs);
NavigationUtil.goToArtist(activity, song.artistId, artistPairs);
return true;
}
return false;
}
public static boolean handlePlaylistMenuClick(Activity activity, Playlist playlist, MenuItem item){
switch (item.getItemId()) {
case R.id.action_rename_playlist:
RenamePlaylistDialogHelper.getDialog(activity, playlist.id).show();
return true;
case R.id.action_delete_playlist:
DeletePlaylistDialogHelper.getDialog(activity, playlist.id).show();
return true;
}
return false;
}
}

View file

@ -4,6 +4,7 @@ import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.net.Uri;
import android.os.IBinder; import android.os.IBinder;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
@ -11,6 +12,9 @@ import android.widget.Toast;
import com.kabouzeid.gramophone.App; import com.kabouzeid.gramophone.App;
import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.loader.AlbumSongLoader;
import com.kabouzeid.gramophone.loader.ArtistSongLoader;
import com.kabouzeid.gramophone.loader.PlaylistSongLoader;
import com.kabouzeid.gramophone.loader.SongLoader; import com.kabouzeid.gramophone.loader.SongLoader;
import com.kabouzeid.gramophone.misc.AppKeys; import com.kabouzeid.gramophone.misc.AppKeys;
import com.kabouzeid.gramophone.model.MusicRemoteEvent; import com.kabouzeid.gramophone.model.MusicRemoteEvent;
@ -85,19 +89,19 @@ public class MusicPlayerRemote {
public static void playNextSong() { public static void playNextSong() {
if (musicService != null) { if (musicService != null) {
musicService.playNextSong(); musicService.playNextSong(true);
} }
} }
public static void playPreviousSong() { public static void playPreviousSong() {
if (musicService != null) { if (musicService != null) {
musicService.back(); musicService.back(true);
} }
} }
public static void back() { public static void back() {
if (musicService != null) { if (musicService != null) {
musicService.back(); musicService.back(true);
} }
} }
@ -304,4 +308,18 @@ public class MusicPlayerRemote {
position = -1; position = -1;
} }
} }
public static void playFile(Uri uri) {
if (musicService != null && uri != null) {
String filename;
String scheme = uri.getScheme();
if ("file".equals(scheme)) {
filename = uri.getPath();
} else {
filename = uri.toString();
}
//musicService.playFile(filename); //TODO
Toast.makeText(context, "This feature is not working yet", Toast.LENGTH_SHORT).show();
}
}
} }

View file

@ -52,6 +52,7 @@ public class Album implements SearchEntry {
imageView.setImageResource(R.drawable.default_album_art); imageView.setImageResource(R.drawable.default_album_art);
Picasso.with(context) Picasso.with(context)
.load(MusicUtil.getAlbumArtUri(id)) .load(MusicUtil.getAlbumArtUri(id))
.placeholder(R.drawable.default_album_art)
.into(imageView); .into(imageView);
} }
} }

View file

@ -20,6 +20,7 @@ import android.os.Binder;
import android.os.IBinder; import android.os.IBinder;
import android.os.PowerManager; import android.os.PowerManager;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.widget.Toast; import android.widget.Toast;
@ -153,10 +154,10 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
resumePlaying(); resumePlaying();
break; break;
case ACTION_REWIND: case ACTION_REWIND:
back(); back(true);
break; break;
case ACTION_SKIP: case ACTION_SKIP:
playNextSong(); playNextSong(true);
break; break;
case ACTION_STOP: case ACTION_STOP:
stopPlaying(); stopPlaying();
@ -167,7 +168,7 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
} }
} }
} }
return START_NOT_STICKY; return START_STICKY;
} }
@Override @Override
@ -268,14 +269,14 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
remoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_STOPPED); remoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_STOPPED);
notifyOnMusicRemoteEventListeners(MusicRemoteEvent.STOP); notifyOnMusicRemoteEventListeners(MusicRemoteEvent.STOP);
} else { } else {
playNextSong(); playNextSong(false);
} }
} }
public void playNextSong() { public void playNextSong(boolean force) {
if (position != -1) { if (position != -1) {
if (isPlayerPrepared) { if (isPlayerPrepared) {
setPosition(getNextPosition()); setPosition(getNextPosition(force));
playSong(); playSong();
notifyOnMusicRemoteEventListeners(MusicRemoteEvent.NEXT); notifyOnMusicRemoteEventListeners(MusicRemoteEvent.NEXT);
} }
@ -380,7 +381,7 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
return ContentUris.withAppendedId(android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, playingQueue.get(position).id); return ContentUris.withAppendedId(android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, playingQueue.get(position).id);
} }
public int getNextPosition() { public int getNextPosition(boolean force) {
int position = 0; int position = 0;
switch (repeatMode) { switch (repeatMode) {
case REPEAT_MODE_NONE: case REPEAT_MODE_NONE:
@ -396,7 +397,14 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
} }
break; break;
case REPEAT_MODE_THIS: case REPEAT_MODE_THIS:
position = getPosition(); if(force){
position = getPosition() + 1;
if (isLastTrack()) {
position = 0;
}
} else {
position = getPosition();
}
break; break;
} }
return position; return position;
@ -628,25 +636,25 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
} }
} }
public void playPreviousSong() { public void playPreviousSong(boolean force) {
if (position != -1) { if (position != -1) {
setPosition(getPreviousPosition()); setPosition(getPreviousPosition(force));
playSong(); playSong();
notifyOnMusicRemoteEventListeners(MusicRemoteEvent.PREV); notifyOnMusicRemoteEventListeners(MusicRemoteEvent.PREV);
} }
} }
public void back() { public void back(boolean force) {
if (position != -1) { if (position != -1) {
if (getSongProgressMillis() > 2000) { if (getSongProgressMillis() > 2000) {
seekTo(0); seekTo(0);
} else { } else {
playPreviousSong(); playPreviousSong(force);
} }
} }
} }
public int getPreviousPosition() { public int getPreviousPosition(boolean force) {
int position = 0; int position = 0;
switch (repeatMode) { switch (repeatMode) {
case REPEAT_MODE_NONE: case REPEAT_MODE_NONE:
@ -662,7 +670,14 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
} }
break; break;
case REPEAT_MODE_THIS: case REPEAT_MODE_THIS:
position = getPosition(); if(force){
position = getPosition() - 1;
if (position < 0) {
position = getPlayingQueue().size() - 1;
}
} else {
position = getPosition();
}
break; break;
} }
return position; return position;

View file

@ -2,13 +2,16 @@ package com.kabouzeid.gramophone.ui.activities;
import android.content.Intent; import android.content.Intent;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.util.Pair; import android.support.v4.util.Pair;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout; import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
@ -20,6 +23,9 @@ import com.kabouzeid.gramophone.helper.AboutDeveloperDialogHelper;
import com.kabouzeid.gramophone.helper.CreatePlaylistDialogHelper; import com.kabouzeid.gramophone.helper.CreatePlaylistDialogHelper;
import com.kabouzeid.gramophone.helper.MusicPlayerRemote; import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.interfaces.KabViewsDisableAble; import com.kabouzeid.gramophone.interfaces.KabViewsDisableAble;
import com.kabouzeid.gramophone.loader.AlbumSongLoader;
import com.kabouzeid.gramophone.loader.ArtistSongLoader;
import com.kabouzeid.gramophone.loader.PlaylistSongLoader;
import com.kabouzeid.gramophone.model.MusicRemoteEvent; import com.kabouzeid.gramophone.model.MusicRemoteEvent;
import com.kabouzeid.gramophone.model.Song; import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.model.UIPreferenceChangedEvent; import com.kabouzeid.gramophone.model.UIPreferenceChangedEvent;
@ -33,6 +39,8 @@ import com.kabouzeid.gramophone.util.Util;
import com.kabouzeid.gramophone.util.ViewUtil; import com.kabouzeid.gramophone.util.ViewUtil;
import com.squareup.picasso.Picasso; import com.squareup.picasso.Picasso;
import java.util.List;
public class MainActivity extends AbsFabActivity public class MainActivity extends AbsFabActivity
implements NavigationDrawerFragment.NavigationDrawerCallbacks, KabViewsDisableAble { implements NavigationDrawerFragment.NavigationDrawerCallbacks, KabViewsDisableAble {
@ -61,6 +69,8 @@ public class MainActivity extends AbsFabActivity
); );
setUpToolBar(); setUpToolBar();
setUpViewPager(); setUpViewPager();
handlePlaybackIntent(getIntent());
} }
private void setUpViewPager() { private void setUpViewPager() {
@ -120,7 +130,7 @@ public class MainActivity extends AbsFabActivity
setUpDrawerToggle(); setUpDrawerToggle();
} }
private void setToolBarTransparent(boolean transparent){ private void setToolBarTransparent(boolean transparent) {
float alpha = transparent ? 0.97f : 1f; float alpha = transparent ? 0.97f : 1f;
final int colorPrimary = Util.resolveColor(this, R.attr.colorPrimary); final int colorPrimary = Util.resolveColor(this, R.attr.colorPrimary);
ViewUtil.setBackgroundAlpha(toolbar, alpha, colorPrimary); ViewUtil.setBackgroundAlpha(toolbar, alpha, colorPrimary);
@ -297,4 +307,60 @@ public class MainActivity extends AbsFabActivity
super.onPause(); super.onPause();
PreferenceUtils.getInstance(MainActivity.this).setLastStartPage(currentPage); PreferenceUtils.getInstance(MainActivity.this).setLastStartPage(currentPage);
} }
private boolean handlePlaybackIntent(Intent intent) {
if (intent == null) {
return false;
}
Uri uri = intent.getData();
String mimeType = intent.getType();
boolean handled = false;
if (uri != null && uri.toString().length() > 0) {
MusicPlayerRemote.playFile(uri);
handled = true;
} else if (MediaStore.Audio.Playlists.CONTENT_TYPE.equals(mimeType)) {
final int id = (int) parseIdFromIntent(intent, "playlistId", "playlist");
if (id >= 0) {
int position = intent.getIntExtra("position", 0);
MusicPlayerRemote.openQueue((List<Song>) (List<? extends Song>) PlaylistSongLoader.getPlaylistSongList(this, id), position, true);
handled = true;
}
} else if (MediaStore.Audio.Albums.CONTENT_TYPE.equals(mimeType)) {
final int id = (int) parseIdFromIntent(intent, "albumId", "album");
if (id >= 0) {
int position = intent.getIntExtra("position", 0);
MusicPlayerRemote.openQueue(AlbumSongLoader.getAlbumSongList(this, id), position, true);
handled = true;
}
} else if (MediaStore.Audio.Artists.CONTENT_TYPE.equals(mimeType)) {
final int id = (int) parseIdFromIntent(intent, "artistId", "artist");
if (id >= 0) {
int position = intent.getIntExtra("position", 0);
MusicPlayerRemote.openQueue(ArtistSongLoader.getArtistSongList(this, id), position, true);
handled = true;
}
}
if (handled) {
setIntent(new Intent());
}
return handled;
}
private long parseIdFromIntent(Intent intent, String longKey,
String stringKey) {
long id = intent.getLongExtra(longKey, -1);
if (id < 0) {
String idString = intent.getStringExtra(stringKey);
if (idString != null) {
try {
id = Long.parseLong(idString);
} catch (NumberFormatException e) {
Log.e(TAG, e.getMessage());
}
}
}
return id;
}
} }

View file

@ -135,7 +135,7 @@ public class NavigationDrawerFragment extends Fragment {
private void setUpListView() { private void setUpListView() {
final ArrayList<NavigationDrawerItem> navigationDrawerItems = new ArrayList<>(); final ArrayList<NavigationDrawerItem> navigationDrawerItems = new ArrayList<>();
navigationDrawerItems.add(new NavigationDrawerItem(getString(R.string.songs), R.drawable.ic_my_library_music_white_24dp)); navigationDrawerItems.add(new NavigationDrawerItem(getString(R.string.songs), R.drawable.ic_audiotrack_white_24dp));
navigationDrawerItems.add(new NavigationDrawerItem(getString(R.string.albums), R.drawable.ic_album_white_24dp)); navigationDrawerItems.add(new NavigationDrawerItem(getString(R.string.albums), R.drawable.ic_album_white_24dp));
navigationDrawerItems.add(new NavigationDrawerItem(getString(R.string.artists), R.drawable.ic_person_white_24dp)); navigationDrawerItems.add(new NavigationDrawerItem(getString(R.string.artists), R.drawable.ic_person_white_24dp));
navigationDrawerItems.add(new NavigationDrawerItem(getString(R.string.playlists), R.drawable.ic_queue_music_white_24dp)); navigationDrawerItems.add(new NavigationDrawerItem(getString(R.string.playlists), R.drawable.ic_queue_music_white_24dp));

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 B

View file

@ -45,4 +45,10 @@
android:textAppearance="@style/TextAppearance.AppCompat.Body1" android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textColor="?caption_text_color"/> android:textColor="?caption_text_color"/>
</LinearLayout> </LinearLayout>
<ImageView
android:id="@+id/menu"
style="@style/OverFlowButton"
android:layout_gravity="center_vertical"
android:layout_marginRight="2dp"/>
</LinearLayout> </LinearLayout>

View file

@ -30,22 +30,22 @@
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView
android:textColor="?title_text_color"
android:id="@+id/song_title" android:id="@+id/song_title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fontFamily="sans-serif" android:fontFamily="sans-serif"
android:singleLine="true" android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"/> android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
android:textColor="?title_text_color"/>
<TextView <TextView
android:textColor="?caption_text_color"
android:id="@+id/song_info" android:id="@+id/song_info"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fontFamily="sans-serif" android:fontFamily="sans-serif"
android:singleLine="true" android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"/> android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textColor="?caption_text_color"/>
</LinearLayout> </LinearLayout>
<ImageView <ImageView