Remove menu alpha, ellipsize song titles, CenterCrop image in landscape, do not auto populate server on fresh install, change welcome text, add names to all threads, stop active ImageLoader threads when changing concurrency, show extension and bitrate for videos

This commit is contained in:
Joshua Bahnsen 2014-01-25 02:41:45 -07:00
parent c1740b5291
commit 4389698d7f
15 changed files with 157 additions and 100 deletions

View File

@ -22,7 +22,7 @@
a:id="@+id/download_album_art_image"
a:layout_width="wrap_content"
a:layout_height="wrap_content"
a:scaleType="center"
a:scaleType="centerCrop"
a:contentDescription="@string/albumArt"/>
<LinearLayout

View File

@ -1,20 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/menu_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
android:id="@+id/menu_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
android:orientation="vertical"
android:alpha="1">
<TextView
android:id="@+id/menu_navigation"
style="@style/MenuDrawer.Widget.Category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/menu.navigation" />
android:text="@string/menu.navigation"/>
<TextView
android:id="@+id/menu_home"
@ -22,7 +23,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="?attr/home"
android:text="@string/button_bar.home" />
android:text="@string/button_bar.home"/>
<TextView
android:id="@+id/menu_browse"
@ -30,7 +31,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="?attr/browse"
android:text="@string/button_bar.browse" />
android:text="@string/button_bar.browse"/>
<TextView
android:id="@+id/menu_search"
@ -38,7 +39,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="?attr/search"
android:text="@string/button_bar.search" />
android:text="@string/button_bar.search"/>
<TextView
android:id="@+id/menu_playlists"
@ -46,7 +47,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="?attr/playlists"
android:text="@string/button_bar.playlists" />
android:text="@string/button_bar.playlists"/>
<TextView
android:id="@+id/menu_shares"
@ -54,7 +55,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="?attr/share"
android:text="@string/button_bar.shares" />
android:text="@string/button_bar.shares"/>
<TextView
android:id="@+id/menu_bookmarks"
@ -62,15 +63,15 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="?attr/bookmark"
android:text="@string/button_bar.bookmarks" />
android:text="@string/button_bar.bookmarks"/>
<TextView
android:id="@+id/menu_chat"
style="@style/MenuDrawer.Widget.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="?attr/chat"
android:text="@string/button_bar.chat" />
android:text="@string/button_bar.chat"/>
<TextView
android:id="@+id/menu_now_playing"
@ -78,14 +79,14 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableLeft="?attr/media_play"
android:text="@string/button_bar.now_playing" />
android:text="@string/button_bar.now_playing"/>
<TextView
android:id="@+id/menu_common"
style="@style/MenuDrawer.Widget.Category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/menu.common" />
android:text="@string/menu.common"/>
<TextView
android:id="@+id/menu_settings"
@ -93,7 +94,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="?attr/settings"
android:text="@string/menu.settings" />
android:text="@string/menu.settings"/>
<TextView
android:id="@+id/menu_about"
@ -101,7 +102,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="?attr/about"
android:text="@string/menu.about" />
android:text="@string/menu.about"/>
<TextView
android:id="@+id/menu_exit"
@ -109,7 +110,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="?attr/exit"
android:text="@string/menu.exit" />
android:text="@string/menu.exit"/>
</LinearLayout>
</ScrollView>

View File

@ -26,9 +26,9 @@
a:layout_gravity="left|center_vertical"
a:layout_weight="1"
a:drawablePadding="6dip"
a:ellipsize="marquee"
a:ellipsize="end"
a:paddingLeft="4dip"
a:paddingRight="6dip"
a:paddingRight="2dip"
a:singleLine="true"
a:textAppearance="?android:attr/textAppearanceMedium"/>

View File

@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
a:layout_width="0dip"
a:layout_height="wrap_content"
a:layout_gravity="center_vertical"
a:layout_weight="1"
a:orientation="vertical" >
a:layout_width="0dip"
a:layout_height="wrap_content"
a:layout_gravity="center_vertical"
a:layout_weight="1"
a:orientation="vertical">
<LinearLayout
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:layout_gravity="center_vertical"
a:orientation="horizontal" >
a:orientation="horizontal">
<TextView
a:id="@+id/song_title"
@ -18,23 +18,21 @@
a:layout_height="wrap_content"
a:layout_gravity="left|center_vertical"
a:layout_weight="1"
a:drawablePadding="6dip"
a:ellipsize="marquee"
a:ellipsize="end"
a:paddingLeft="4dip"
a:paddingRight="6dip"
a:paddingRight="2dip"
a:singleLine="true"
a:text="Video Title"
a:textAppearance="?android:attr/textAppearanceMedium" />
a:textAppearance="?android:attr/textAppearanceMedium"/>
<TextView
a:id="@+id/song_duration"
a:layout_width="wrap_content"
a:layout_height="wrap_content"
a:layout_gravity="right|center_vertical"
a:paddingLeft="3dip"
a:paddingRight="9dip"
a:paddingLeft="2dip"
a:paddingRight="6dip"
a:singleLine="true"
a:textAppearance="?android:attr/textAppearanceSmall" />
a:textAppearance="?android:attr/textAppearanceSmall"/>
</LinearLayout>
</LinearLayout>

View File

@ -95,7 +95,7 @@
<string name="main.songs_starred">Starred</string>
<string name="main.songs_title">Songs</string>
<string name="main.videos">Videos</string>
<string name="main.welcome_text">Welcome to UltraSonic! The app is currently not configured. After you\'ve set up your personal server (available from <b>subsonic.org</b>), please go to <b>Settings</b> and change the configuration to connect to it.</string>
<string name="main.welcome_text">Welcome to UltraSonic! The app is currently not configured. After you\'ve set up your personal server (available from <b>subsonic.org</b>), please click <i>Add Server</i> in <b>Settings</b> to connect to it.</string>
<string name="main.welcome_title">Welcome!</string>
<string name="menu.about">About</string>
<string name="menu.common">Common</string>

View File

@ -1,29 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="listselect" parent="android:style/Widget.ListView">
<item name="android:listSelector">@drawable/list_selector_holo_dark</item>
</style>
<style name="listselectlight" parent="android:style/Widget.ListView.White">
<item name="android:listSelector">@drawable/list_selector_holo_light</item>
</style>
<style name="customprogress" parent="android:style/Widget.ProgressBar.Horizontal">
<item name="android:progressDrawable">@drawable/progress_horizontal_holo_dark</item>
</style>
<style name="Widget.MenuDrawer">
<item name="mdMenuBackground">@color/md__transparent</item>
<item name="mdMenuBackground">?android:attr/windowBackground</item>
<item name="mdContentBackground">?android:attr/windowBackground</item>
<item name="mdActiveIndicator">@drawable/menu_arrow</item>
<item name="mdMenuSize">250dp</item>
<item name="mdAllowIndicatorAnimation">true</item>
<item name="mdDropShadowSize">5dip</item>
<item name="mdDropShadowColor">@color/translucent</item>
<item name="mdAllowIndicatorAnimation">true</item>
</style>
<style name="MenuDrawer" />
<style name="MenuDrawer.Widget" />
<style name="MenuDrawer"/>
<style name="MenuDrawer.Widget"/>
<style name="MenuDrawer.Widget.Category">
<item name="android:textStyle">bold</item>
<item name="android:textColor">@color/cyan</item>
@ -34,7 +36,7 @@
<item name="android:singleLine">true</item>
<item name="android:ellipsize">end</item>
</style>
<style name="MenuDrawer.Widget.Title">
<item name="android:textAppearance">?android:attr/textAppearance</item>
<item name="android:textSize">18sp</item>
@ -45,8 +47,8 @@
<item name="android:drawablePadding">16dp</item>
<item name="android:gravity">center_vertical</item>
</style>
<attr name="star_hollow" format="reference"/>
<attr name="star_hollow" format="reference"/>
<attr name="star_full" format="reference"/>
<attr name="about" format="reference"/>
<attr name="select_all" format="reference"/>
@ -64,31 +66,31 @@
<attr name="remove_all" format="reference"/>
<attr name="save" format="reference"/>
<attr name="screen_on_off" format="reference"/>
<attr name="search" format="reference"/>
<attr name="select_folder" format="reference"/>
<attr name="settings" format="reference"/>
<attr name="share" format="reference"/>
<attr name="downloaded" format="reference"/>
<attr name="downloading" format="reference"/>
<attr name="media_previous" format="reference"/>
<attr name="media_next" format="reference"/>
<attr name="media_pause" format="reference"/>
<attr name="media_repeat_all" format="reference"/>
<attr name="media_repeat_off" format="reference"/>
<attr name="media_repeat_single" format="reference"/>
<attr name="media_shuffle" format="reference"/>
<attr name="media_play" format="reference"/>
<attr name="media_play_next" format="reference"/>
<attr name="media_play_small" format="reference"/>
<attr name="media_stop" format="reference"/>
<attr name="media_toggle" format="reference"/>
<attr name="chat" format="reference"/>
<attr name="chat_send" format="reference" />
<attr name="bookmark" format="reference" />
<attr name="check_mark_off" format="reference" />
<attr name="check_mark_on" format="reference" />
<attr name="button_check_custom" format="reference" />
<attr name="color_background" format="reference" />
<attr name="search" format="reference"/>
<attr name="select_folder" format="reference"/>
<attr name="settings" format="reference"/>
<attr name="share" format="reference"/>
<attr name="downloaded" format="reference"/>
<attr name="downloading" format="reference"/>
<attr name="media_previous" format="reference"/>
<attr name="media_next" format="reference"/>
<attr name="media_pause" format="reference"/>
<attr name="media_repeat_all" format="reference"/>
<attr name="media_repeat_off" format="reference"/>
<attr name="media_repeat_single" format="reference"/>
<attr name="media_shuffle" format="reference"/>
<attr name="media_play" format="reference"/>
<attr name="media_play_next" format="reference"/>
<attr name="media_play_small" format="reference"/>
<attr name="media_stop" format="reference"/>
<attr name="media_toggle" format="reference"/>
<attr name="chat" format="reference"/>
<attr name="chat_send" format="reference"/>
<attr name="bookmark" format="reference"/>
<attr name="check_mark_off" format="reference"/>
<attr name="check_mark_on" format="reference"/>
<attr name="button_check_custom" format="reference"/>
<attr name="color_background" format="reference"/>
</resources>

View File

@ -48,6 +48,7 @@ import com.thejoshwa.ultrasonic.androidapp.service.MusicServiceFactory;
import com.thejoshwa.ultrasonic.androidapp.util.Constants;
import com.thejoshwa.ultrasonic.androidapp.util.ErrorDialog;
import com.thejoshwa.ultrasonic.androidapp.util.FileUtil;
import com.thejoshwa.ultrasonic.androidapp.util.ImageLoader;
import com.thejoshwa.ultrasonic.androidapp.util.ModalBackgroundTask;
import com.thejoshwa.ultrasonic.androidapp.util.TimeSpanPreference;
import com.thejoshwa.ultrasonic.androidapp.util.Util;
@ -102,7 +103,7 @@ public class SettingsActivity extends PreferenceResultActivity implements Shared
public MenuDrawer menuDrawer;
private int activePosition = 1;
private int menuActiveViewId;
private int activeServers = 3;
private int activeServers;
View chatMenuItem;
View bookmarksMenuItem;
View sharesMenuItem;
@ -224,7 +225,7 @@ public class SettingsActivity extends PreferenceResultActivity implements Shared
}
settings = PreferenceManager.getDefaultSharedPreferences(this);
activeServers = settings.getInt(Constants.PREFERENCES_KEY_ACTIVE_SERVERS, 3);
activeServers = settings.getInt(Constants.PREFERENCES_KEY_ACTIVE_SERVERS, 0);
serversCategory = (PreferenceCategory) findPreference(Constants.PREFERENCES_KEY_SERVERS_KEY);
@ -516,6 +517,10 @@ public class SettingsActivity extends PreferenceResultActivity implements Shared
{
setBluetoothPreferences(sharedPreferences.getBoolean(key, true));
}
else if (Constants.PREFERENCES_KEY_IMAGE_LOADER_CONCURRENCY.equals(key))
{
setImageLoaderConcurrency(Integer.parseInt(sharedPreferences.getString(key, "5")));
}
}
private void update()
@ -567,6 +572,22 @@ public class SettingsActivity extends PreferenceResultActivity implements Shared
}
}
private static void setImageLoaderConcurrency(int concurrency)
{
SubsonicTabActivity instance = SubsonicTabActivity.getInstance();
if (instance != null)
{
ImageLoader imageLoader = instance.getImageLoader();
if (imageLoader != null)
{
imageLoader.stopImageLoader();
imageLoader.setConcurrency(concurrency);
}
}
}
private void setHideMedia(boolean hide)
{
File nomediaDir = new File(FileUtil.getUltraSonicDirectory(), ".nomedia");

View File

@ -349,16 +349,11 @@ public class SubsonicTabActivity extends ResultActivity implements OnClickListen
new AsyncTask<Void, Void, String[]>()
{
@Override
protected void onPostExecute(String[] result)
{
super.onPostExecute(result);
}
@SuppressLint("NewApi")
@Override
protected String[] doInBackground(Void... params)
{
Thread.currentThread().setName("showNotification");
RemoteViews notificationView = notification.contentView;
RemoteViews bigNotificationView = null;
@ -455,7 +450,6 @@ public class SubsonicTabActivity extends ResultActivity implements OnClickListen
public void hidePlayingNotification(final Handler handler, final DownloadServiceImpl downloadService)
{
currentSong = null;
// Remove notification and remove the service from the foreground

View File

@ -179,6 +179,8 @@ public class DownloadServiceImpl extends Service implements DownloadService
@Override
public void run()
{
Thread.currentThread().setName("DownloadServiceImpl");
Looper.prepare();
if (mediaPlayer != null)
@ -2172,6 +2174,8 @@ public class DownloadServiceImpl extends Service implements DownloadService
@Override
public void run()
{
Thread.currentThread().setName("PositionCache");
// Stop checking position before the song reaches completion
while (isRunning)
{
@ -2181,7 +2185,8 @@ public class DownloadServiceImpl extends Service implements DownloadService
{
cachedPosition = mediaPlayer.getCurrentPosition();
}
Thread.sleep(200L);
Thread.sleep(50L);
}
catch (Exception e)
{
@ -2211,6 +2216,8 @@ public class DownloadServiceImpl extends Service implements DownloadService
@Override
public void execute()
{
Thread.currentThread().setName("CheckCompletionTask");
if (downloadFile == null)
{
return;

View File

@ -367,6 +367,7 @@ public class DownloadServiceLifecycleSupport
{
try
{
Thread.currentThread().setName("SerializeTask");
serializeDownloadQueueNow();
}
finally
@ -385,6 +386,7 @@ public class DownloadServiceLifecycleSupport
{
try
{
Thread.currentThread().setName("DeserializeTask");
lock.lock();
deserializeDownloadQueueNow();
setup.set(true);
@ -393,6 +395,7 @@ public class DownloadServiceLifecycleSupport
{
lock.unlock();
}
return null;
}
}

View File

@ -41,6 +41,7 @@ import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
/**
@ -64,7 +65,7 @@ public class JukeboxService
private JukeboxStatus jukeboxStatus;
private float gain = 0.5f;
private VolumeToast volumeToast;
private boolean running = false;
private AtomicBoolean running = new AtomicBoolean();
private Thread serviceThread;
// TODO: Report warning if queue fills up.
@ -80,18 +81,24 @@ public class JukeboxService
public void startJukeboxService()
{
if (running) return;
if (running.get())
{
return;
}
running = true;
running.set(true);
startProcessTasks();
}
public void stopJukeboxService()
{
running = false;
running.set(false);
Util.sleepQuietly(1000);
if (serviceThread != null) serviceThread.interrupt();
if (serviceThread != null)
{
serviceThread.interrupt();
}
}
private void startProcessTasks()
@ -136,7 +143,7 @@ public class JukeboxService
private void processTasks()
{
while (running)
while (running.get())
{
JukeboxTask task = null;

View File

@ -239,6 +239,7 @@ public class CacheCleaner
try
{
Thread.currentThread().setName("BackgroundCleanup");
List<File> files = new ArrayList<File>();
List<File> dirs = new ArrayList<File>();
@ -272,6 +273,7 @@ public class CacheCleaner
try
{
Thread.currentThread().setName("BackgroundSpaceCleanup");
List<File> files = new ArrayList<File>();
List<File> dirs = new ArrayList<File>();
findCandidatesForDeletion(FileUtil.getMusicDirectory(context), files, dirs);
@ -300,6 +302,7 @@ public class CacheCleaner
{
try
{
Thread.currentThread().setName("BackgroundPlaylistsCleanup");
String server = Util.getServerName(context);
SortedSet<File> playlistFiles = FileUtil.listFiles(FileUtil.getPlaylistDirectory(server));
List<Playlist> playlists = params[0];

View File

@ -40,6 +40,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Asynchronous loading of images, with caching.
@ -50,7 +51,6 @@ import java.util.concurrent.LinkedBlockingQueue;
*/
public class ImageLoader implements Runnable
{
private static final String TAG = ImageLoader.class.getSimpleName();
private final LRUCache<String, Bitmap> cache = new LRUCache<String, Bitmap>(150);
@ -59,8 +59,8 @@ public class ImageLoader implements Runnable
private final int imageSizeLarge;
private Bitmap largeUnknownImage;
private Context context;
private Collection<Thread> threads = new ArrayList<Thread>();
private boolean running = false;
private Collection<Thread> threads;
private AtomicBoolean running = new AtomicBoolean();
private int concurrency;
public ImageLoader(Context context, int concurrency)
@ -86,16 +86,23 @@ public class ImageLoader implements Runnable
public synchronized boolean isRunning()
{
return running && !threads.isEmpty();
return running.get() && !threads.isEmpty();
}
public void setConcurrency(int concurrency)
{
this.concurrency = concurrency;
}
public void startImageLoader()
{
running = true;
running.set(true);
threads = new ArrayList<Thread>(this.concurrency);
for (int i = 0; i < this.concurrency; i++)
{
Thread thread = new Thread(this, "ImageLoader");
Thread thread = new Thread(this, String.format("ImageLoader [%d]", i));
threads.add(thread);
thread.start();
}
@ -110,7 +117,8 @@ public class ImageLoader implements Runnable
thread.interrupt();
}
running = false;
running.set(false);
threads.clear();
}
private void createLargeUnknownImage(Context context)
@ -263,7 +271,7 @@ public class ImageLoader implements Runnable
@Override
public void run()
{
while (running)
while (running.get())
{
try
{
@ -272,7 +280,8 @@ public class ImageLoader implements Runnable
}
catch (InterruptedException ignored)
{
running.set(false);
break;
}
catch (Throwable x)
{

View File

@ -197,7 +197,15 @@ public class SongView extends UpdateView implements Checkable
}
}
viewHolder.title.setText(song.getTitle());
StringBuilder title = new StringBuilder(60);
title.append(song.getTitle());
if (song.isVideo() && Util.shouldDisplayBitrateWithArtist(this.context))
{
title.append(" (").append(String.format(this.context.getString(R.string.song_details_all), bitRate == null ? "" : String.format("%s ", bitRate), fileFormat)).append(')');
}
viewHolder.title.setText(title);
if (viewHolder.artist != null)
{

View File

@ -62,6 +62,7 @@ public class UpdateView extends LinearLayout
@Override
public void run()
{
Thread.currentThread().setName("startUpdater");
Looper.prepare();
backgroundHandler = new Handler(Looper.myLooper());
uiHandler.post(updateRunnable);
@ -110,6 +111,7 @@ public class UpdateView extends LinearLayout
{
Log.w(TAG, "Error when updating song views.", x);
}
uiHandler.postDelayed(updateRunnable, Util.getViewRefreshInterval(context));
}
};
@ -121,6 +123,8 @@ public class UpdateView extends LinearLayout
{
try
{
Thread.currentThread().setName("updateAllLive-Background");
for (UpdateView view : views)
{
view.updateBackground();