diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
new file mode 100644
index 0000000..59587ff
Binary files /dev/null and b/.idea/caches/build_file_checksums.ser differ
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 0c96608..c51a432 100755
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -3,7 +3,6 @@
-
diff --git a/README.md b/README.md
index 0832f52..ca7c973 100755
--- a/README.md
+++ b/README.md
@@ -32,14 +32,13 @@ Used to quickly search for songs, artists or albums in the library. 2 search mo
## Releases
-[Latest Release (v 1.2)](https://github.com/Valou3433/blade-player/releases/download/v1.2/blade-1.2.apk)
+[Latest Release (v 1.3)](https://github.com/Valou3433/blade-player/releases/download/v1.3/blade-1.3.apk)
-[Mirror](http://valou3433.fr/blade/blade-1.2.apk)
+[Mirror](http://valou3433.fr/blade/blade-1.3.apk)
-- added ability to edit local songs metadata
-- added themes (for now only blade, nightly and green)
-- added image generation for local playlists, ...
-- fixed bugs
+- added song linkmanager
+- added animation and red theme
+- fixed bugs on search, mediasession, tag editor
Link to all [Blade-Player Releases](https://github.com/Valou3433/blade-player/releases)
diff --git a/app/app.iml b/app/app.iml
index c3f46c7..541f529 100755
--- a/app/app.iml
+++ b/app/app.iml
@@ -84,20 +84,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -150,5 +166,6 @@
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 90a7a51..12f423b 100755
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -7,8 +7,8 @@ android {
applicationId "v.blade"
minSdkVersion 16
targetSdkVersion 27
- versionCode 11
- versionName "1.2"
+ versionCode 12
+ versionName "1.3"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
compileOptions {
diff --git a/app/release/blade-1.3.apk b/app/release/blade-1.3.apk
new file mode 100644
index 0000000..86ffc27
Binary files /dev/null and b/app/release/blade-1.3.apk differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index caaa6a7..51d4f27 100755
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -89,12 +89,21 @@
android:name="android.support.PARENT_ACTIVITY"
android:value="v.blade.ui.MainActivity"/>
-
-
+
+
+
+
+
diff --git a/app/src/main/java/v/blade/BladeApplication.java b/app/src/main/java/v/blade/BladeApplication.java
index c68f6c7..0671ecb 100644
--- a/app/src/main/java/v/blade/BladeApplication.java
+++ b/app/src/main/java/v/blade/BladeApplication.java
@@ -46,6 +46,8 @@ else if(theme.equalsIgnoreCase("blade"))
ThemesActivity.setThemeToBlade();
else if(theme.equalsIgnoreCase("green"))
ThemesActivity.setThemeToGreen();
+ else if(theme.equalsIgnoreCase("red"))
+ ThemesActivity.setThemeToRed();
}
}
}
diff --git a/app/src/main/java/v/blade/library/LibraryObject.java b/app/src/main/java/v/blade/library/LibraryObject.java
index 48a3836..f63e64a 100755
--- a/app/src/main/java/v/blade/library/LibraryObject.java
+++ b/app/src/main/java/v/blade/library/LibraryObject.java
@@ -19,6 +19,7 @@
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.net.Uri;
import java.io.Serializable;
@@ -52,6 +53,7 @@ public void setArt(String path, Bitmap miniatureArt)
public boolean getArtLoading() {return this.artLoad;}
public Bitmap getArtMiniature() {return miniatureArt;}
public Bitmap getArt() {return BitmapFactory.decodeFile(artPath);}
+ public Uri getArtUri() {return artPath == null ? null : Uri.parse(artPath);}
public boolean hasArt() {return hasArt;}
public String getType() {return this.getClass().getSimpleName();}
diff --git a/app/src/main/java/v/blade/library/LibraryService.java b/app/src/main/java/v/blade/library/LibraryService.java
index c422935..42c9088 100755
--- a/app/src/main/java/v/blade/library/LibraryService.java
+++ b/app/src/main/java/v/blade/library/LibraryService.java
@@ -29,6 +29,7 @@ public class LibraryService
public static boolean SAVE_PLAYLISTS_TO_LIBRARY;
public static boolean REGISTER_SONGS_BETTER_SOURCES;
public static Uri TREE_URI;
+ public static boolean ENABLE_SONG_CHANGE_ANIM;
/* library */
private static final List artists = Collections.synchronizedList(new ArrayList());
@@ -43,7 +44,7 @@ public class LibraryService
static HashMap> songsByName = new HashMap<>();
//song linkss
- private static final HashMap> songLinks = new HashMap<>();
+ public static final HashMap> songLinks = new HashMap<>();
/* list callbacks */
public interface UserLibraryCallback{void onLibraryChange();}
@@ -157,6 +158,8 @@ public static void configureLibrary(Context appContext)
String treeUri = generalPrefs.getString("sdcard_uri", null);
if(treeUri != null) TREE_URI = Uri.parse(treeUri);
+ ENABLE_SONG_CHANGE_ANIM = generalPrefs.getBoolean("anim_0", true);
+
SAVE_PLAYLISTS_TO_LIBRARY = generalPrefs.getBoolean("save_playlist_to_library", false);
REGISTER_SONGS_BETTER_SOURCES = generalPrefs.getBoolean("register_better_sources", true);
@@ -319,7 +322,7 @@ public static void linkSong(Song source, Song destination, boolean save)
{
if(src != null)
{
- destination.getSources().addSource(src);
+ destination.getSources().addSource(src); //addSource is checking for double-add
unregisterSong(source, src);
}
}
@@ -347,27 +350,32 @@ public static void linkSong(Song source, Song destination, boolean save)
list.add(source);
//save songlinks to cache (by rewriting hashmap)
- if(save)
+ if(save) writeLinks();
+ }
+
+ /*
+ * Rewrite song links on disk
+ */
+ public static void writeLinks()
+ {
+ try
{
- try
+ songLinksFile.createNewFile();
+ BufferedWriter writer = new BufferedWriter(new FileWriter(songLinksFile));
+ for(Song s : songLinks.keySet())
{
- songLinksFile.createNewFile();
- BufferedWriter writer = new BufferedWriter(new FileWriter(songLinksFile));
- for(Song s : songLinks.keySet())
- {
- List links = songLinks.get(s);
- writer.write(s.getArtist() + CACHE_SEPARATOR + s.getAlbum() + CACHE_SEPARATOR + s.getTitle() + CACHE_SEPARATOR +
- links.size() + CACHE_SEPARATOR);
- for(Song linked : links)
- writer.write(linked.getArtist() + CACHE_SEPARATOR + linked.getAlbum() + CACHE_SEPARATOR + linked.getTitle() + CACHE_SEPARATOR);
- writer.newLine();
- }
- writer.close();
- }
- catch (IOException e)
- {
- e.printStackTrace();
+ List links = songLinks.get(s);
+ writer.write(s.getArtist() + CACHE_SEPARATOR + s.getAlbum() + CACHE_SEPARATOR + s.getTitle() + CACHE_SEPARATOR +
+ links.size() + CACHE_SEPARATOR);
+ for(Song linked : links)
+ writer.write(linked.getArtist() + CACHE_SEPARATOR + linked.getAlbum() + CACHE_SEPARATOR + linked.getTitle() + CACHE_SEPARATOR);
+ writer.newLine();
}
+ writer.close();
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
}
}
@@ -437,27 +445,31 @@ private static void registerSongBetterSources()
//search all songs on best source
ArrayList bestSourceSongs = new ArrayList<>();
- for(Song s : songs)
+ synchronized (songs)
{
- if(s.getSources().getSourceByPriority(0).getSource() != bestSource && s.getSources().getSourceByPriority(0).getSource() != Source.SOURCE_LOCAL_LIB)
+ for(Song s : songs)
{
- //query bestSource for this song
- try
+ if(s.getSources().getSourceByPriority(0).getSource() != bestSource && s.getSources().getSourceByPriority(0).getSource() != Source.SOURCE_LOCAL_LIB)
{
- if(bestSource.searchForSong(s))
+ //query bestSource for this song
+ try
+ {
+ if(bestSource.searchForSong(s))
+ {
+ bestSourceSongs.add(s);
+ }
+ addedSongs++;
+ if(addedSongs >= BETTER_SOURCES_MAX) break;
+ }
+ catch (Exception error)
{
- bestSourceSongs.add(s);
+ //TODO : handle error
+ continue;
}
- addedSongs++;
- if(addedSongs >= BETTER_SOURCES_MAX) break;
- }
- catch (Exception error)
- {
- //TODO : handle error
- continue;
}
}
}
+
//also search for songs in playlist
if(!SAVE_PLAYLISTS_TO_LIBRARY)
{
@@ -512,7 +524,7 @@ private static void registerSongLinks()
while (reader.ready())
{
String[] line = reader.readLine().split(CACHE_SEPARATOR);
- System.out.println(Arrays.toString(line));
+ //System.out.println(Arrays.toString(line));
Song song = getSongHandle(line[2], line[1], line[0], 0, null, 0, 0);
if(song == null) continue;
int size = Integer.parseInt(line[3]);
@@ -527,6 +539,7 @@ private static void registerSongLinks()
}
catch (IOException e)
{
+ System.err.println("registerSongLinks() encoutered IOException");
e.printStackTrace();
}
}
@@ -720,9 +733,13 @@ static Song getSongHandle(String name, String album, String artist, long duratio
if(alb.getName().equalsIgnoreCase(album) && alb.getArtist().getName().equalsIgnoreCase(songArtist.getName()))
songAlbum = alb;
}
- if(songAlbum == null) for(Album alb : albumHandles)
- if(alb.getName().equalsIgnoreCase(album) && alb.getArtist().getName().equalsIgnoreCase(songArtist.getName()))
- songAlbum = alb;
+ if(songAlbum == null)
+ synchronized (albumHandles)
+ {
+ for (Album alb : albumHandles)
+ if (alb.getName().equalsIgnoreCase(album) && alb.getArtist().getName().equalsIgnoreCase(songArtist.getName()))
+ songAlbum = alb;
+ }
if(songAlbum == null) {songAlbum = new Album(album, songArtist); songAlbum.setHandled(true); albumHandles.add(songAlbum);}
songAlbum.getSources().addSource(source);
diff --git a/app/src/main/java/v/blade/library/Source.java b/app/src/main/java/v/blade/library/Source.java
index 9c03886..94dce4a 100755
--- a/app/src/main/java/v/blade/library/Source.java
+++ b/app/src/main/java/v/blade/library/Source.java
@@ -35,7 +35,6 @@
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
-import java.lang.Error;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
@@ -148,7 +147,7 @@ public void playSong(Song song, PlayerCallback callback)
if(local == null) {if(callback != null) callback.onFailure(player); return;}
if(mediaPlayer == null) {if(callback != null) callback.onFailure(player); return;}
- if(song.getFormat().equals("audio/x-ms-wma"))
+ if(song.getFormat() != null && song.getFormat().equals("audio/x-ms-wma"))
{
Toast.makeText(LibraryService.appContext, LibraryService.appContext.getString(R.string.format_unsupported), Toast.LENGTH_SHORT).show();
callback.onFailure(player);
@@ -676,7 +675,7 @@ public void seekTo(int msec)
@Override
public int getCurrentPosition()
{
- return spotifyPlayer == null ? 0 : (int) spotifyPlayer.getPlaybackState().positionMs;
+ return spotifyPlayer == null ? 0 : (spotifyPlayer.getPlaybackState() == null ? 0 : (int) spotifyPlayer.getPlaybackState().positionMs);
}
};
@@ -794,42 +793,45 @@ public void registerCachedSongs()
spr.close();
//spotify playlists
- for(File f : spotifyPlaylistsCache.listFiles())
+ if(spotifyPlaylistsCache.exists())
{
- ArrayList thisList = new ArrayList<>();
- BufferedReader sppr = new BufferedReader(new FileReader(f));
- String id = sppr.readLine();
- boolean isMine = Boolean.parseBoolean(sppr.readLine());
- String owner = null; String ownerID = null;
- if(!isMine) {owner = sppr.readLine(); ownerID = sppr.readLine();}
- boolean isCollab = Boolean.parseBoolean(sppr.readLine());
- while(sppr.ready())
+ for(File f : spotifyPlaylistsCache.listFiles())
{
- String[] tp = sppr.readLine().split(CACHE_SEPARATOR);
- Song song = LibraryService.SAVE_PLAYLISTS_TO_LIBRARY ?
- LibraryService.registerSong(tp[2], tp[1], Integer.parseInt(tp[4]), 0,
- Long.parseLong(tp[5]), tp[0], new SongSources.SongSource(tp[6], SOURCE_SPOTIFY))
- : LibraryService.getSongHandle(tp[0], tp[1], tp[2], Long.parseLong(tp[5]),
- new SongSources.SongSource(tp[6], SOURCE_SPOTIFY), Integer.parseInt(tp[4]), 0);
- song.setFormat(tp[3]);
- thisList.add(song);
-
- if(!song.getAlbum().hasArt() && !song.getAlbum().getArtLoading())
+ ArrayList thisList = new ArrayList<>();
+ BufferedReader sppr = new BufferedReader(new FileReader(f));
+ String id = sppr.readLine();
+ boolean isMine = Boolean.parseBoolean(sppr.readLine());
+ String owner = null; String ownerID = null;
+ if(!isMine) {owner = sppr.readLine(); ownerID = sppr.readLine();}
+ boolean isCollab = Boolean.parseBoolean(sppr.readLine());
+ while(sppr.ready())
{
- //the image is supposed to be cached locally, so no need to provide URL
- spotifyCachedToLoadArt.add(song.getAlbum());
- song.getAlbum().setArtLoading();
+ String[] tp = sppr.readLine().split(CACHE_SEPARATOR);
+ Song song = LibraryService.SAVE_PLAYLISTS_TO_LIBRARY ?
+ LibraryService.registerSong(tp[2], tp[1], Integer.parseInt(tp[4]), 0,
+ Long.parseLong(tp[5]), tp[0], new SongSources.SongSource(tp[6], SOURCE_SPOTIFY))
+ : LibraryService.getSongHandle(tp[0], tp[1], tp[2], Long.parseLong(tp[5]),
+ new SongSources.SongSource(tp[6], SOURCE_SPOTIFY), Integer.parseInt(tp[4]), 0);
+ song.setFormat(tp[3]);
+ thisList.add(song);
+
+ if(!song.getAlbum().hasArt() && !song.getAlbum().getArtLoading())
+ {
+ //the image is supposed to be cached locally, so no need to provide URL
+ spotifyCachedToLoadArt.add(song.getAlbum());
+ song.getAlbum().setArtLoading();
+ }
}
+ sppr.close();
+
+ Playlist p = new Playlist(f.getName(), thisList);
+ if(!isMine) p.setOwner(owner, ownerID);
+ if(isCollab) p.setCollaborative();
+ spotifyCachedToLoadArt.add(p);
+ p.setArtLoading();
+ p.getSources().addSource(new SongSources.SongSource(id, SOURCE_SPOTIFY));
+ LibraryService.getPlaylists().add(p);
}
- sppr.close();
-
- Playlist p = new Playlist(f.getName(), thisList);
- if(!isMine) p.setOwner(owner, ownerID);
- if(isCollab) p.setCollaborative();
- spotifyCachedToLoadArt.add(p);
- p.setArtLoading();
- p.getSources().addSource(new SongSources.SongSource(id, SOURCE_SPOTIFY));
- LibraryService.getPlaylists().add(p);
}
}
}
@@ -1082,19 +1084,21 @@ public List query(String query)
Song song = LibraryService.getSongHandle(t.name, t.album.name, t.artists.get(0).name, t.duration_ms, new SongSources.SongSource(t.id, SOURCE_SPOTIFY), t.track_number, 0);
tr.add(song);
+ //System.out.println("[SART] Song : " + song.getName() + " - " + song.getAlbum() + " - " + song.getArtist() + " , hasArt = " + song.getAlbum().hasArt() + " art = " + song.getAlbum().getArtUri());
if(!song.getAlbum().hasArt())
{
if(t.album.images.get(0) != null)
urls.put(song.getAlbum(), t.album.images.get(0).url);
+ //System.out.println("[SART] Album " + song.getAlbum() + " (artist = " + song.getArtist() + ") : img = " + t.album.images.get(0).url);
}
}
for(kaaes.spotify.webapi.android.models.AlbumSimple a : albums.albums.items)
{
Album album = null;
Pager