diff --git a/res/layout/select_album_header.xml b/res/layout/select_album_header.xml
index d631e19b..91be0aa1 100644
--- a/res/layout/select_album_header.xml
+++ b/res/layout/select_album_header.xml
@@ -1,7 +1,7 @@
+ a:layout_width="fill_parent"
+ a:layout_height="wrap_content">
+ a:src="@drawable/unknown_album_large"/>
+ a:textAppearance="?android:attr/textAppearanceMedium"/>
+ a:textAppearance="?android:attr/textAppearanceSmall"/>
+ a:textAppearance="?android:attr/textAppearanceSmall"/>
+
+
+ a:textAppearance="?android:attr/textAppearanceSmall"/>
+ a:textAppearance="?android:attr/textAppearanceSmall"/>
\ No newline at end of file
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 4f6d90ba..ae667164 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -388,6 +388,7 @@
11
12
albumArt
+ Multiple Years
- Aucun titre
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index bc3d5c3d..e81083b0 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -388,6 +388,7 @@
11
12
albumArt
+ Multiple Years
- Nincsenek dalok
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2a68266f..9a142f56 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -388,6 +388,7 @@
11
12
albumArt
+ Multiple Years
- No songs
diff --git a/src/com/thejoshwa/ultrasonic/androidapp/activity/DownloadActivity.java b/src/com/thejoshwa/ultrasonic/androidapp/activity/DownloadActivity.java
index ab1bae84..b27565e4 100644
--- a/src/com/thejoshwa/ultrasonic/androidapp/activity/DownloadActivity.java
+++ b/src/com/thejoshwa/ultrasonic/androidapp/activity/DownloadActivity.java
@@ -1325,7 +1325,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
artistTextView.setText(null);
downloadTrackTextView.setText(null);
downloadTotalDurationTextView.setText(null);
- getImageLoader().loadImage(albumArtImageView, null, true, 0, false, false);
+ getImageLoader().loadImage(albumArtImageView, null, true, 0, false, true);
}
}
diff --git a/src/com/thejoshwa/ultrasonic/androidapp/activity/SelectAlbumActivity.java b/src/com/thejoshwa/ultrasonic/androidapp/activity/SelectAlbumActivity.java
index 56b8217c..8591de5d 100644
--- a/src/com/thejoshwa/ultrasonic/androidapp/activity/SelectAlbumActivity.java
+++ b/src/com/thejoshwa/ultrasonic/androidapp/activity/SelectAlbumActivity.java
@@ -1196,11 +1196,12 @@ public class SelectAlbumActivity extends SubsonicTabActivity
int artworkSelection = random.nextInt(entries.size());
getImageLoader().loadImage(coverArtView, entries.get(artworkSelection), false, Util.getAlbumImageSize(SelectAlbumActivity.this), false, true);
- TextView titleView = (TextView) header.findViewById(R.id.select_album_title);
- titleView.setText(name != null ? name : getActionBarSubtitle());
-
AlbumHeader albumHeader = AlbumHeader.processEntries(SelectAlbumActivity.this, entries);
+ TextView titleView = (TextView) header.findViewById(R.id.select_album_title);
+ name = albumHeader.getAlbumNames().size() == 1 ? albumHeader.getAlbumNames().iterator().next() : name;
+ titleView.setText(name != null ? name : getActionBarSubtitle());
+
// Don't show a header if all entries are videos
if (albumHeader.getIsAllVideo())
{
@@ -1221,6 +1222,13 @@ public class SelectAlbumActivity extends SubsonicTabActivity
genreView.setText(genre);
+ TextView yearView = (TextView) header.findViewById(R.id.select_album_year);
+ String year;
+
+ year = albumHeader.getYears().size() == 1 ? albumHeader.getYears().iterator().next().toString() : getResources().getString(R.string.common_multiple_years);
+
+ yearView.setText(year);
+
TextView songCountView = (TextView) header.findViewById(R.id.select_album_song_count);
String songs = getResources().getQuantityString(R.plurals.select_album_n_songs, songCount, songCount);
songCountView.setText(songs);
diff --git a/src/com/thejoshwa/ultrasonic/androidapp/util/AlbumHeader.java b/src/com/thejoshwa/ultrasonic/androidapp/util/AlbumHeader.java
index 6b6c68fc..d1570c33 100644
--- a/src/com/thejoshwa/ultrasonic/androidapp/util/AlbumHeader.java
+++ b/src/com/thejoshwa/ultrasonic/androidapp/util/AlbumHeader.java
@@ -14,6 +14,8 @@ public class AlbumHeader
private Set artists;
private Set grandParents;
private Set genres;
+ private Set albumNames;
+ private Set years;
public boolean getIsAllVideo()
{
@@ -40,11 +42,24 @@ public class AlbumHeader
return this.genres;
}
+ public Set getAlbumNames()
+ {
+ return this.albumNames;
+ }
+
+ public Set getYears()
+ {
+ return this.years;
+ }
+
public AlbumHeader()
{
this.artists = new HashSet();
this.grandParents = new HashSet();
this.genres = new HashSet();
+ this.albumNames = new HashSet();
+ this.years = new HashSet();
+
this.isAllVideo = true;
this.totalDuration = 0;
}
@@ -83,6 +98,16 @@ public class AlbumHeader
{
albumHeader.genres.add(entry.getGenre());
}
+
+ if (entry.getAlbum() != null)
+ {
+ albumHeader.albumNames.add(entry.getAlbum());
+ }
+
+ if (entry.getYear() != null)
+ {
+ albumHeader.years.add(entry.getYear());
+ }
}
}
diff --git a/src/com/thejoshwa/ultrasonic/androidapp/util/CacheCleaner.java b/src/com/thejoshwa/ultrasonic/androidapp/util/CacheCleaner.java
index 48961d59..2cb38216 100644
--- a/src/com/thejoshwa/ultrasonic/androidapp/util/CacheCleaner.java
+++ b/src/com/thejoshwa/ultrasonic/androidapp/util/CacheCleaner.java
@@ -77,11 +77,11 @@ public class CacheCleaner
}
}
- private static void deleteEmptyDirs(Iterable dirs, Collection undeletable)
+ private static void deleteEmptyDirs(Iterable dirs, Collection doNotDelete)
{
for (File dir : dirs)
{
- if (undeletable.contains(dir))
+ if (doNotDelete.contains(dir))
{
continue;
}
@@ -114,8 +114,8 @@ public class CacheCleaner
}
long cacheSizeBytes = Util.getCacheSizeMB(context) * 1024L * 1024L;
-
long bytesUsedBySubsonic = 0L;
+
for (File file : files)
{
bytesUsedBySubsonic += file.length();
@@ -140,7 +140,7 @@ public class CacheCleaner
return bytesToDelete;
}
- private static void deleteFiles(Collection files, Collection undeletable, long bytesToDelete, boolean deletePartials)
+ private static void deleteFiles(Collection files, Collection doNotDelete, long bytesToDelete, boolean deletePartials)
{
if (files.isEmpty())
{
@@ -154,9 +154,10 @@ public class CacheCleaner
if (bytesToDelete > bytesDeleted || (deletePartials && (file.getName().endsWith(".partial") || file.getName().contains(".partial."))))
{
- if (!undeletable.contains(file) && !file.getName().equals(Constants.ALBUM_ART_FILE))
+ if (!doNotDelete.contains(file) && !file.getName().equals(Constants.ALBUM_ART_FILE))
{
long size = file.length();
+
if (Util.delete(file))
{
bytesDeleted += size;
@@ -174,6 +175,7 @@ public class CacheCleaner
{
String name = file.getName();
boolean isCacheFile = name.endsWith(".partial") || name.contains(".partial.") || name.endsWith(".complete") || name.contains(".complete.");
+
if (isCacheFile)
{
files.add(file);
@@ -186,6 +188,7 @@ public class CacheCleaner
{
findCandidatesForDeletion(child, files, dirs);
}
+
dirs.add(file);
}
}
@@ -212,18 +215,18 @@ public class CacheCleaner
});
}
- private Set findUndeletableFiles()
+ private Set findFilesToNotDelete()
{
- Set undeletable = new HashSet(5);
+ Set filesToNotDelete = new HashSet(5);
for (DownloadFile downloadFile : downloadService.getDownloads())
{
- undeletable.add(downloadFile.getPartialFile());
- undeletable.add(downloadFile.getCompleteFile());
+ filesToNotDelete.add(downloadFile.getPartialFile());
+ filesToNotDelete.add(downloadFile.getCompleteFile());
}
- undeletable.add(FileUtil.getMusicDirectory(context));
- return undeletable;
+ filesToNotDelete.add(FileUtil.getMusicDirectory(context));
+ return filesToNotDelete;
}
private class BackgroundCleanup extends AsyncTask
@@ -246,10 +249,10 @@ public class CacheCleaner
findCandidatesForDeletion(FileUtil.getMusicDirectory(context), files, dirs);
sortByAscendingModificationTime(files);
- Set undeletable = findUndeletableFiles();
+ Set filesToNotDelete = findFilesToNotDelete();
- deleteFiles(files, undeletable, getMinimumDelete(files), true);
- deleteEmptyDirs(dirs, undeletable);
+ deleteFiles(files, filesToNotDelete, getMinimumDelete(files), true);
+ deleteEmptyDirs(dirs, filesToNotDelete);
}
catch (RuntimeException x)
{
@@ -282,8 +285,8 @@ public class CacheCleaner
if (bytesToDelete > 0L)
{
sortByAscendingModificationTime(files);
- Set undeletable = findUndeletableFiles();
- deleteFiles(files, undeletable, bytesToDelete, false);
+ Set filesToNotDelete = findFilesToNotDelete();
+ deleteFiles(files, filesToNotDelete, bytesToDelete, false);
}
}
catch (RuntimeException x)
diff --git a/src/com/thejoshwa/ultrasonic/androidapp/util/ImageLoader.java b/src/com/thejoshwa/ultrasonic/androidapp/util/ImageLoader.java
index d433b5f5..43b0e819 100644
--- a/src/com/thejoshwa/ultrasonic/androidapp/util/ImageLoader.java
+++ b/src/com/thejoshwa/ultrasonic/androidapp/util/ImageLoader.java
@@ -38,6 +38,7 @@ import com.thejoshwa.ultrasonic.androidapp.service.MusicServiceFactory;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -98,7 +99,7 @@ public class ImageLoader implements Runnable
{
running.set(true);
- threads = new ArrayList(this.concurrency);
+ threads = Collections.synchronizedCollection(new ArrayList(this.concurrency));
for (int i = 0; i < this.concurrency; i++)
{
@@ -209,9 +210,10 @@ public class ImageLoader implements Runnable
MusicDirectory.Entry tagEntry = (MusicDirectory.Entry) view.getTag();
+ // Only apply image to the view if the view is intended for this entry
if (entry != null && tagEntry != null && !entry.equals(tagEntry))
{
- Log.i(TAG, "Skipping entry");
+ Log.i(TAG, "View is no longer valid, not setting ImageBitmap");
return;
}