allow changing the song artist and title

This commit is contained in:
tibbi 2016-03-24 21:58:54 +01:00
parent 4e57796451
commit 126dbbf921
9 changed files with 180 additions and 7 deletions

View file

@ -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 <fields>;
public <fields>;
}

View file

@ -44,6 +44,7 @@
<action android:name="com.simplemobiletools.musicplayer.action.PLAYPAUSE"/>
<action android:name="com.simplemobiletools.musicplayer.action.NEXT"/>
<action android:name="com.simplemobiletools.musicplayer.action.STOP"/>
<action android:name="com.simplemobiletools.musicplayer.action.EDIT"/>
<action android:name="com.simplemobiletools.musicplayer.action.PLAYPOS"/>
<action android:name="com.simplemobiletools.musicplayer.action.REFRESH_LIST"/>
<action android:name="com.simplemobiletools.musicplayer.action.INCOMING_CALL_START"/>

View file

@ -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";

View file

@ -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<Song> 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();

View file

@ -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;

View file

@ -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();

View file

@ -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());
}
}

View file

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="@dimen/activity_margin">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title"/>
<EditText
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/activity_margin"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/artist"/>
<EditText
android:id="@+id/artist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/activity_margin"/>
</LinearLayout>

View file

@ -5,6 +5,11 @@
<string name="remove">Remove</string>
<string name="edit">Edit</string>
<string name="undo">Undo</string>
<string name="title">Title</string>
<string name="artist">Artist</string>
<string name="rename_song">Rename song</string>
<string name="rename_song_error">An error occurred during the renaming</string>
<string name="rename_song_empty">Please fill in both an artist and a title</string>
<plurals name="songs_deleted">
<item quantity="one">1 song deleted</item>