implement deleting songs
This commit is contained in:
parent
7b874c9b30
commit
dd54c29e55
8 changed files with 166 additions and 18 deletions
|
@ -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'
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue