implement deleting songs

This commit is contained in:
tibbi 2016-03-23 23:09:03 +01:00
parent 7b874c9b30
commit dd54c29e55
8 changed files with 166 additions and 18 deletions

View file

@ -22,6 +22,7 @@ android {
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
compile 'com.jakewharton:butterknife:7.0.1'
compile 'com.squareup:otto:1.3.8'
compile 'com.github.yukuku:ambilwarna:2.0.1'

View file

@ -4,7 +4,7 @@
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<application
@ -45,6 +45,7 @@
<action android:name="com.simplemobiletools.musicplayer.action.NEXT"/>
<action android:name="com.simplemobiletools.musicplayer.action.STOP"/>
<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"/>
<action android:name="com.simplemobiletools.musicplayer.action.INCOMING_CALL_STOP"/>
</intent-filter>

View file

@ -5,6 +5,7 @@ public class Constants {
public static final String WIDGET_BG_COLOR = "widget_bg_color";
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";
private static final String PATH = "com.simplemobiletools.musicplayer.action.";
@ -16,6 +17,7 @@ public class Constants {
public static final String NEXT = PATH + "NEXT";
public static final String STOP = PATH + "STOP";
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";
public static final String CALL_STOP = PATH + "CALL_STOP";
}

View file

@ -3,14 +3,21 @@ package com.simplemobiletools.musicplayer;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Color;
import android.media.MediaScannerConnection;
import android.os.Bundle;
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.AppCompatActivity;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
@ -21,16 +28,23 @@ import android.widget.Toast;
import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends AppCompatActivity implements ListView.MultiChoiceModeListener {
public class MainActivity extends AppCompatActivity
implements ListView.MultiChoiceModeListener, AdapterView.OnItemClickListener, ListView.OnTouchListener {
private final int STORAGE_PERMISSION = 1;
private Bus bus;
private int selectedItemsCnt;
private List<Song> songs;
private Snackbar snackbar;
private boolean isSnackbarShown;
private List<String> toBeDeleted;
@Bind(R.id.playPauseBtn) ImageView playPauseBtn;
@Bind(R.id.songs) ListView songsList;
@ -66,7 +80,10 @@ public class MainActivity extends AppCompatActivity implements ListView.MultiCho
}
private void initializePlayer() {
toBeDeleted = new ArrayList<>();
songsList.setMultiChoiceModeListener(this);
songsList.setOnTouchListener(this);
songsList.setOnItemClickListener(this);
Utils.sendIntent(this, Constants.INIT);
}
@ -85,14 +102,15 @@ public class MainActivity extends AppCompatActivity implements ListView.MultiCho
}
private void fillSongsListView(ArrayList<Song> songs) {
this.songs = songs;
final SongAdapter adapter = new SongAdapter(this, songs);
songsList.setAdapter(adapter);
songsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
songPicked(position);
}
});
}
@Override
protected void onPause() {
super.onPause();
deleteSongs();
}
@Override
@ -175,6 +193,7 @@ public class MainActivity extends AppCompatActivity implements ListView.MultiCho
case R.id.cab_edit:
return true;
case R.id.cab_remove:
prepareForDeleting();
mode.finish();
return true;
default:
@ -182,8 +201,96 @@ public class MainActivity extends AppCompatActivity implements ListView.MultiCho
}
}
private void prepareForDeleting() {
toBeDeleted.clear();
Utils.showToast(this, R.string.deleting);
final SparseBooleanArray items = songsList.getCheckedItemPositions();
int cnt = items.size();
int deletedCnt = 0;
for (int i = 0; i < cnt; i++) {
if (items.valueAt(i)) {
final int id = items.keyAt(i);
final String path = songs.get(id).getPath();
toBeDeleted.add(path);
deletedCnt++;
}
}
notifyDeletion(deletedCnt);
}
private void notifyDeletion(int cnt) {
final CoordinatorLayout coordinator = (CoordinatorLayout) findViewById(R.id.coordinator_layout);
final Resources res = getResources();
final String msg = res.getQuantityString(R.plurals.songs_deleted, cnt, cnt);
snackbar = Snackbar.make(coordinator, msg, Snackbar.LENGTH_INDEFINITE);
snackbar.setAction(res.getString(R.string.undo), undoDeletion);
snackbar.setActionTextColor(Color.WHITE);
snackbar.show();
isSnackbarShown = true;
updateSongsList();
}
private void updateSongsList() {
final Intent intent = new Intent(this, MusicService.class);
final String[] deletedSongs = new String[toBeDeleted.size()];
toBeDeleted.toArray(deletedSongs);
intent.putExtra(Constants.DELETED_SONGS, deletedSongs);
intent.setAction(Constants.REFRESH_LIST);
startService(intent);
}
private void deleteSongs() {
if (toBeDeleted.isEmpty())
return;
if (snackbar != null) {
snackbar.dismiss();
}
isSnackbarShown = false;
final List<String> updatedFiles = new ArrayList<>();
for (String delPath : toBeDeleted) {
final File file = new File(delPath);
if (file.exists()) {
if (file.delete()) {
updatedFiles.add(delPath);
}
}
}
final String[] deletedPaths = updatedFiles.toArray(new String[updatedFiles.size()]);
MediaScannerConnection.scanFile(this, deletedPaths, null, null);
toBeDeleted.clear();
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
songPicked(position);
}
private View.OnClickListener undoDeletion = new View.OnClickListener() {
@Override
public void onClick(View v) {
toBeDeleted.clear();
snackbar.dismiss();
isSnackbarShown = false;
updateSongsList();
}
};
@Override
public void onDestroyActionMode(ActionMode mode) {
selectedItemsCnt = 0;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (isSnackbarShown) {
deleteSongs();
}
return false;
}
}

View file

@ -32,8 +32,10 @@ import com.squareup.otto.Bus;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
public class MusicService extends Service
@ -47,6 +49,7 @@ public class MusicService extends Service
private ArrayList<Integer> playedSongIDs;
private Song currSong;
private Bus bus;
private List<String> ignoredPaths;
private boolean wasPlayingAtCall;
private Bitmap prevBitmap;
private Bitmap playBitmap;
@ -60,6 +63,7 @@ public class MusicService extends Service
super.onCreate();
songs = new ArrayList<>();
playedSongIDs = new ArrayList<>();
ignoredPaths = new ArrayList<>();
if (bus == null) {
bus = BusProvider.getInstance();
@ -123,6 +127,15 @@ public class MusicService extends Service
case Constants.FINISH:
destroyPlayer();
break;
case Constants.REFRESH_LIST:
ignoredPaths = Arrays.asList(intent.getStringArrayExtra(Constants.DELETED_SONGS));
fillPlaylist();
bus.post(new Events.PlaylistUpdated(songs));
if (currSong != null && ignoredPaths.contains(currSong.getPath())) {
playNextSong();
}
break;
default:
break;
}
@ -168,7 +181,10 @@ public class MusicService extends Service
final String title = cursor.getString(titleIndex);
final String artist = cursor.getString(artistIndex);
final String path = cursor.getString(pathIndex);
songs.add(new Song(id, title, artist, path));
if (!ignoredPaths.contains(path)) {
songs.add(new Song(id, title, artist, path));
}
}
} while (cursor.moveToNext());
cursor.close();

View file

@ -9,10 +9,11 @@ import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.LightingColorFilter;
import android.graphics.Paint;
import android.widget.Toast;
public class Utils {
public static void sendIntent(Context context, String action) {
Intent intent = new Intent(context, MusicService.class);
final Intent intent = new Intent(context, MusicService.class);
intent.setAction(action);
context.startService(intent);
}
@ -28,4 +29,8 @@ public class Utils {
canvas.drawBitmap(bmp, 0, 0, paint);
return bmp;
}
public static void showToast(Context context, int resId) {
Toast.makeText(context, context.getResources().getString(resId), Toast.LENGTH_SHORT).show();
}
}

View file

@ -2,7 +2,6 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_margin"
android:paddingTop="@dimen/activity_margin">
<LinearLayout
@ -10,7 +9,8 @@
android:layout_width="match_parent"
android:layout_height="@dimen/widget_row_height"
android:layout_marginRight="@dimen/activity_margin"
android:orientation="horizontal">
android:orientation="horizontal"
android:paddingLeft="@dimen/activity_margin">
<ImageView
android:id="@+id/previousBtn"
@ -64,6 +64,7 @@
android:layout_marginRight="@dimen/activity_margin"
android:layout_marginTop="@dimen/activity_margin"
android:gravity="center_horizontal"
android:paddingLeft="@dimen/activity_margin"
android:textSize="18sp"/>
<TextView
@ -73,14 +74,22 @@
android:layout_below="@+id/songTitle"
android:layout_marginRight="@dimen/activity_margin"
android:gravity="center_horizontal"
android:paddingLeft="@dimen/activity_margin"
android:textSize="16sp"/>
<ListView
android:id="@+id/songs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/songArtist"
android:layout_marginTop="@dimen/activity_margin"
android:choiceMode="multipleChoiceModal"/>
android:layout_marginTop="@dimen/activity_margin">
<ListView
android:id="@+id/songs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:choiceMode="multipleChoiceModal"
android:paddingLeft="@dimen/activity_margin"/>
</android.support.design.widget.CoordinatorLayout>
</RelativeLayout>

View file

@ -4,4 +4,11 @@
<string name="no_permissions">Permission for accessing the songs has not been granted</string>
<string name="remove">Remove</string>
<string name="edit">Edit</string>
<string name="deleting">Deleting</string>
<string name="undo">Undo</string>
<plurals name="songs_deleted">
<item quantity="one">1 song deleted</item>
<item quantity="other">%1$d songs deleted</item>
</plurals>
</resources>