diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 25ea3346..3f680a82 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -15,3 +15,11 @@ #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} +-keepclassmembers class * implements java.io.Serializable { + static final long serialVersionUID; + java.lang.Object writeReplace(); + java.lang.Object readResolve(); + private static final java.io.ObjectStreamField[] serialPersistentFields; + private ; + public ; +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6d71b77d..066dc52e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -44,6 +44,7 @@ + diff --git a/app/src/main/java/com/simplemobiletools/musicplayer/Constants.java b/app/src/main/java/com/simplemobiletools/musicplayer/Constants.java index 2f53449a..05851939 100644 --- a/app/src/main/java/com/simplemobiletools/musicplayer/Constants.java +++ b/app/src/main/java/com/simplemobiletools/musicplayer/Constants.java @@ -6,6 +6,7 @@ public class Constants { public static final String WIDGET_TEXT_COLOR = "widget_text_color"; public static final String SONG_POS = "song_position"; public static final String DELETED_SONGS = "deleted_songs"; + public static final String EDITED_SONG = "edited_song"; private static final String PATH = "com.simplemobiletools.musicplayer.action."; @@ -16,6 +17,7 @@ public class Constants { public static final String PLAYPAUSE = PATH + "PLAYPAUSE"; public static final String NEXT = PATH + "NEXT"; public static final String STOP = PATH + "STOP"; + public static final String EDIT = PATH + "EDIT"; public static final String PLAYPOS = PATH + "PLAYPOS"; public static final String REFRESH_LIST = PATH + "REFRESH_LIST"; public static final String CALL_START = PATH + "CALL_START"; diff --git a/app/src/main/java/com/simplemobiletools/musicplayer/MainActivity.java b/app/src/main/java/com/simplemobiletools/musicplayer/MainActivity.java index df93b784..a1351e1d 100644 --- a/app/src/main/java/com/simplemobiletools/musicplayer/MainActivity.java +++ b/app/src/main/java/com/simplemobiletools/musicplayer/MainActivity.java @@ -1,16 +1,20 @@ package com.simplemobiletools.musicplayer; import android.Manifest; +import android.content.ContentValues; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Color; import android.media.MediaScannerConnection; +import android.net.Uri; import android.os.Bundle; +import android.provider.MediaStore; import android.support.design.widget.CoordinatorLayout; import android.support.design.widget.Snackbar; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; +import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.util.SparseBooleanArray; import android.view.ActionMode; @@ -20,6 +24,7 @@ import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.widget.AdapterView; +import android.widget.EditText; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; @@ -41,6 +46,7 @@ public class MainActivity extends AppCompatActivity private final int STORAGE_PERMISSION = 1; private Bus bus; private int selectedItemsCnt; + private Song currentSong; private List songs; private Snackbar snackbar; private boolean isSnackbarShown; @@ -141,7 +147,8 @@ public class MainActivity extends AppCompatActivity @Subscribe public void songChangedEvent(Events.SongChanged event) { - updateSongInfo(event.getSong()); + currentSong = event.getSong(); + updateSongInfo(currentSong); } @Subscribe @@ -191,6 +198,8 @@ public class MainActivity extends AppCompatActivity public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.cab_edit: + displayEditDialog(); + mode.finish(); return true; case R.id.cab_remove: prepareForDeleting(); @@ -201,6 +210,99 @@ public class MainActivity extends AppCompatActivity } } + private void displayEditDialog() { + final int songIndex = getSelectedSongIndex(); + if (songIndex == -1) + return; + + final Song selectedSong = songs.get(songIndex); + if (selectedSong == null) + return; + + final String title = selectedSong.getTitle(); + final String artist = selectedSong.getArtist(); + + final View renameSongView = getLayoutInflater().inflate(R.layout.rename_song, null); + final EditText titleET = (EditText) renameSongView.findViewById(R.id.title); + titleET.setText(title); + + final EditText artistET = (EditText) renameSongView.findViewById(R.id.artist); + artistET.setText(artist); + + final AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(getResources().getString(R.string.rename_song)); + builder.setView(renameSongView); + + builder.setPositiveButton("OK", null); + builder.setNegativeButton("Cancel", null); + + final AlertDialog alertDialog = builder.create(); + alertDialog.show(); + alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final String newSongTitle = titleET.getText().toString().trim(); + final String newSongArtist = artistET.getText().toString().trim(); + + if (!newSongTitle.isEmpty() && !newSongArtist.isEmpty()) { + final Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + if (updateContentResolver(uri, selectedSong.getId(), newSongTitle, newSongArtist)) { + getContentResolver().notifyChange(uri, null); + boolean currSongChanged = false; + if (currentSong != null && currentSong.equals(selectedSong)) { + currSongChanged = true; + } + + final Song songInList = songs.get(songIndex); + songInList.setTitle(newSongTitle); + songInList.setArtist(newSongArtist); + + if (currSongChanged) { + notifyCurrentSongChanged(songInList); + } + + alertDialog.dismiss(); + } else { + Utils.showToast(getApplicationContext(), R.string.rename_song_error); + } + } else { + Utils.showToast(getApplicationContext(), R.string.rename_song_empty); + } + } + }); + } + + private boolean updateContentResolver(Uri uri, long songID, String newSongTitle, String newSongArtist) { + final String where = MediaStore.Images.Media._ID + " = ? "; + final String[] args = {String.valueOf(songID)}; + + final ContentValues values = new ContentValues(); + values.put(MediaStore.Audio.Media.TITLE, newSongTitle); + values.put(MediaStore.Audio.Media.ARTIST, newSongArtist); + + return getContentResolver().update(uri, values, where, args) == 1; + } + + private int getSelectedSongIndex() { + final SparseBooleanArray items = songsList.getCheckedItemPositions(); + int cnt = items.size(); + for (int i = 0; i < cnt; i++) { + if (items.valueAt(i)) { + return items.keyAt(i); + } + } + return -1; + } + + private void notifyCurrentSongChanged(Song newSong) { + final Intent intent = new Intent(this, MusicService.class); + intent.putExtra(Constants.EDITED_SONG, newSong); + intent.setAction(Constants.EDIT); + startService(intent); + currentSong = newSong; + ((SongAdapter) songsList.getAdapter()).notifyDataSetChanged(); + } + private void prepareForDeleting() { toBeDeleted.clear(); final SparseBooleanArray items = songsList.getCheckedItemPositions(); diff --git a/app/src/main/java/com/simplemobiletools/musicplayer/MusicService.java b/app/src/main/java/com/simplemobiletools/musicplayer/MusicService.java index f396d457..4f9689f6 100644 --- a/app/src/main/java/com/simplemobiletools/musicplayer/MusicService.java +++ b/app/src/main/java/com/simplemobiletools/musicplayer/MusicService.java @@ -104,10 +104,11 @@ public class MusicService extends Service pauseSong(); break; case Constants.PLAYPAUSE: - if (isPlaying()) + if (isPlaying()) { pauseSong(); - else + } else { resumeSong(); + } break; case Constants.NEXT: playNextSong(); @@ -124,6 +125,11 @@ public class MusicService extends Service case Constants.CALL_STOP: incomingCallStop(); break; + case Constants.EDIT: + currSong = (Song) intent.getSerializableExtra(Constants.EDITED_SONG); + bus.post(new Events.SongChanged(currSong)); + setupNotification(); + break; case Constants.FINISH: destroyPlayer(); break; diff --git a/app/src/main/java/com/simplemobiletools/musicplayer/MyWidgetProvider.java b/app/src/main/java/com/simplemobiletools/musicplayer/MyWidgetProvider.java index 71bec9a2..683b7a01 100644 --- a/app/src/main/java/com/simplemobiletools/musicplayer/MyWidgetProvider.java +++ b/app/src/main/java/com/simplemobiletools/musicplayer/MyWidgetProvider.java @@ -70,9 +70,6 @@ public class MyWidgetProvider extends AppWidgetProvider { @Subscribe public void songChangedEvent(Events.SongChanged event) { - if (currSong == event.getSong()) - return; - currSong = event.getSong(); updateSongInfo(); updateWidgets(); diff --git a/app/src/main/java/com/simplemobiletools/musicplayer/Song.java b/app/src/main/java/com/simplemobiletools/musicplayer/Song.java index d7f34ed7..348f5e54 100644 --- a/app/src/main/java/com/simplemobiletools/musicplayer/Song.java +++ b/app/src/main/java/com/simplemobiletools/musicplayer/Song.java @@ -1,6 +1,9 @@ package com.simplemobiletools.musicplayer; -public class Song { +import java.io.Serializable; + +public class Song implements Serializable { + private static final long serialVersionUID = 6717978783256842145L; private long id; private String title; private String artist; @@ -21,10 +24,18 @@ public class Song { return artist; } + public void setArtist(String newArtist) { + artist = newArtist; + } + public String getTitle() { return title; } + public void setTitle(String newTitle) { + title = newTitle; + } + public String getPath() { return path; } @@ -38,4 +49,15 @@ public class Song { + ", path=" + getPath() + "}"; } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + + if (o == null) + return false; + + return this.toString().equals(o.toString()); + } } diff --git a/app/src/main/res/layout/rename_song.xml b/app/src/main/res/layout/rename_song.xml new file mode 100644 index 00000000..eb4dee4a --- /dev/null +++ b/app/src/main/res/layout/rename_song.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8dae9fd3..ef5e4a55 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -5,6 +5,11 @@ Remove Edit Undo + Title + Artist + Rename song + An error occurred during the renaming + Please fill in both an artist and a title 1 song deleted