aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
m---------ServerProxy0
-rw-r--r--app/build.gradle4
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/SelectInternetRadioStationFragment.java45
-rw-r--r--app/src/main/java/github/daneren2005/dsub/service/DownloadService.java6
-rw-r--r--app/src/main/java/github/daneren2005/dsub/util/BackgroundTask.java19
-rw-r--r--app/src/main/java/github/daneren2005/dsub/util/Notifications.java20
-rw-r--r--app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientBase.java2
-rw-r--r--app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientICS.java2
-rw-r--r--app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientJB.java13
-rw-r--r--app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientLP.java14
-rw-r--r--app/src/main/res/values-pt-rPT/strings.xml63
-rw-r--r--app/src/main/res/xml/changelog.xml4
12 files changed, 143 insertions, 49 deletions
diff --git a/ServerProxy b/ServerProxy
-Subproject 158e7e67eca5d7cf69915a59503464d47f16711
+Subproject a74d706b529ebba4ab73b64169e769affb6ae2a
diff --git a/app/build.gradle b/app/build.gradle
index ced2d978..075e403c 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -9,8 +9,8 @@ android {
applicationId "github.daneren2005.dsub"
minSdkVersion 14
targetSdkVersion 23
- versionCode 186
- versionName '5.3'
+ versionCode 187
+ versionName '5.3.1'
setProperty("archivesBaseName", "DSub $versionName")
resConfigs "de", "es", "fr", "hu", "nl", "pt-rPT", "ru", "sv"
}
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SelectInternetRadioStationFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SelectInternetRadioStationFragment.java
index 16082cbd..c39e9f61 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/SelectInternetRadioStationFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/SelectInternetRadioStationFragment.java
@@ -18,10 +18,18 @@
*/
package github.daneren2005.dsub.fragments;
+import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.ArrayList;
import java.util.List;
@@ -37,6 +45,8 @@ import github.daneren2005.dsub.util.Util;
import github.daneren2005.dsub.view.UpdateView;
public class SelectInternetRadioStationFragment extends SelectRecyclerFragment<InternetRadioStation> {
+ private static final String TAG = SelectInternetRadioStationFragment.class.getSimpleName();
+
@Override
public int getOptionsMenu() {
return R.menu.abstract_top_menu;
@@ -67,6 +77,7 @@ public class SelectInternetRadioStationFragment extends SelectRecyclerFragment<I
return null;
}
+ getStreamFromPlaylist(item);
downloadService.download(item);
return null;
}
@@ -94,6 +105,40 @@ public class SelectInternetRadioStationFragment extends SelectRecyclerFragment<I
return false;
}
+ private void getStreamFromPlaylist(InternetRadioStation internetRadioStation) {
+ if(internetRadioStation.getStreamUrl() != null && (internetRadioStation.getStreamUrl().indexOf(".m3u") != -1 || internetRadioStation.getStreamUrl().indexOf(".pls") != -1)) {
+ try {
+ URL url = new URL(internetRadioStation.getStreamUrl());
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+
+ try {
+ BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+ String line;
+ while((line = in.readLine()) != null) {
+ // Not blank line or comment
+ if(line.length() > 0 && line.indexOf('#') != 0) {
+ if(internetRadioStation.getStreamUrl().indexOf(".m3u") != -1) {
+ internetRadioStation.setStreamUrl(line);
+ break;
+ } else {
+ if(line.indexOf("File1=") == 0) {
+ internetRadioStation.setStreamUrl(line.replace("File1=", ""));
+ } else if(line.indexOf("Title1=") == 0) {
+ internetRadioStation.setTitle(line.replace("Title1=", ""));
+ }
+ }
+ }
+ }
+ } finally {
+ connection.disconnect();
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to get stream data from playlist");
+ }
+
+ }
+ }
+
private void displayInternetRadioStationInfo(final InternetRadioStation station) {
List<Integer> headers = new ArrayList<>();
List<String> details = new ArrayList<>();
diff --git a/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java b/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java
index a6bbc327..1cf482ca 100644
--- a/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java
+++ b/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java
@@ -1469,7 +1469,7 @@ public class DownloadService extends Service {
Notifications.hidePlayingNotification(this, this, handler);
}
if(mRemoteControl != null) {
- mRemoteControl.setPlaybackState(playerState.getRemoteControlClientPlayState());
+ mRemoteControl.setPlaybackState(playerState.getRemoteControlClientPlayState(), getCurrentPlayingIndex(), size());
}
if (playerState == STARTED) {
@@ -2842,6 +2842,8 @@ public class DownloadService extends Service {
final Integer duration = getPlayerDuration();
final boolean isSeekable = isSeekable();
final int position = getPlayerPosition();
+ final int index = getCurrentPlayingIndex();
+ final int queueSize = size();
synchronized(onSongChangedListeners) {
for (final OnSongChangedListener listener : onSongChangedListeners) {
@@ -2861,7 +2863,7 @@ public class DownloadService extends Service {
@Override
public void run() {
if(mRemoteControl != null) {
- mRemoteControl.setPlaybackState(playerState.getRemoteControlClientPlayState());
+ mRemoteControl.setPlaybackState(playerState.getRemoteControlClientPlayState(), index, queueSize);
}
}
});
diff --git a/app/src/main/java/github/daneren2005/dsub/util/BackgroundTask.java b/app/src/main/java/github/daneren2005/dsub/util/BackgroundTask.java
index 31e83200..2b0c6279 100644
--- a/app/src/main/java/github/daneren2005/dsub/util/BackgroundTask.java
+++ b/app/src/main/java/github/daneren2005/dsub/util/BackgroundTask.java
@@ -27,6 +27,7 @@ import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
import org.xmlpull.v1.XmlPullParserException;
@@ -54,6 +55,7 @@ public abstract class BackgroundTask<T> implements ProgressListener {
private static final Collection<Thread> threads = Collections.synchronizedCollection(new ArrayList<Thread>());
protected static final BlockingQueue<BackgroundTask.Task> queue = new LinkedBlockingQueue<BackgroundTask.Task>(10);
private static Handler handler = null;
+ private static AtomicInteger currentlyRunning = new AtomicInteger(0);
static {
try {
handler = new Handler(Looper.getMainLooper());
@@ -71,6 +73,11 @@ public abstract class BackgroundTask<T> implements ProgressListener {
threads.add(thread);
thread.start();
}
+ } else if(currentlyRunning.get() >= threads.size()) {
+ Log.w(TAG, "Emergency add new thread: " + (threads.size() + 1));
+ Thread thread = new Thread(new TaskRunnable(), String.format("BackgroundTask_%d", threads.size()));
+ threads.add(thread);
+ thread.start();
}
if(handler == null) {
try {
@@ -304,22 +311,30 @@ public abstract class BackgroundTask<T> implements ProgressListener {
@Override
public void run() {
Looper.prepare();
+ final Thread currentThread = Thread.currentThread();
while(running) {
try {
Task task = queue.take();
+ currentlyRunning.incrementAndGet();
task.execute();
} catch(InterruptedException stop) {
Log.e(TAG, "Thread died");
running = false;
- threads.remove(Thread.currentThread());
} catch(Throwable t) {
Log.e(TAG, "Unexpected crash in BackgroundTask thread", t);
+ running = false;
}
+
+ currentlyRunning.decrementAndGet();
+ }
+
+ if(threads.contains(currentThread)) {
+ threads.remove(currentThread);
}
}
}
- public static interface OnCancelListener {
+ public interface OnCancelListener {
void onCancel();
}
}
diff --git a/app/src/main/java/github/daneren2005/dsub/util/Notifications.java b/app/src/main/java/github/daneren2005/dsub/util/Notifications.java
index 0d4a0f9c..d6a92b07 100644
--- a/app/src/main/java/github/daneren2005/dsub/util/Notifications.java
+++ b/app/src/main/java/github/daneren2005/dsub/util/Notifications.java
@@ -99,7 +99,12 @@ public final class Notifications {
public void run() {
downloadService.stopForeground(true);
showDownloadingNotification(context, downloadService, handler, downloadService.getCurrentDownloading(), downloadService.getBackgroundDownloads().size());
- downloadService.startForeground(NOTIFICATION_ID_PLAYING, notification);
+
+ try {
+ downloadService.startForeground(NOTIFICATION_ID_PLAYING, notification);
+ } catch(Exception e) {
+ Log.e(TAG, "Failed to start notifications after stopping foreground download");
+ }
}
});
} else {
@@ -107,13 +112,22 @@ public final class Notifications {
@Override
public void run() {
if (playing) {
- downloadService.startForeground(NOTIFICATION_ID_PLAYING, notification);
+ try {
+ downloadService.startForeground(NOTIFICATION_ID_PLAYING, notification);
+ } catch(Exception e) {
+ Log.e(TAG, "Failed to start notifications while playing");
+ }
} else {
playShowing = false;
persistentPlayingShowing = true;
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
downloadService.stopForeground(false);
- notificationManager.notify(NOTIFICATION_ID_PLAYING, notification);
+
+ try {
+ notificationManager.notify(NOTIFICATION_ID_PLAYING, notification);
+ } catch(Exception e) {
+ Log.e(TAG, "Failed to start notifications while paused");
+ }
}
}
});
diff --git a/app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientBase.java b/app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientBase.java
index 1f7035dc..4f9a27f0 100644
--- a/app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientBase.java
+++ b/app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientBase.java
@@ -29,7 +29,7 @@ public abstract class RemoteControlClientBase {
public abstract void register(final Context context, final ComponentName mediaButtonReceiverComponent);
public abstract void unregister(final Context context);
- public abstract void setPlaybackState(int state);
+ public abstract void setPlaybackState(int state, int index, int queueSize);
public abstract void updateMetadata(Context context, MusicDirectory.Entry currentSong);
public abstract void metadataChanged(MusicDirectory.Entry currentSong);
public abstract void updateAlbumArt(MusicDirectory.Entry currentSong, Bitmap bitmap);
diff --git a/app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientICS.java b/app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientICS.java
index 2a06e798..74076afb 100644
--- a/app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientICS.java
+++ b/app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientICS.java
@@ -54,7 +54,7 @@ public class RemoteControlClientICS extends RemoteControlClientBase {
audioManager.unregisterRemoteControlClient(mRemoteControl);
}
- public void setPlaybackState(final int state) {
+ public void setPlaybackState(final int state, int index, int queueSize) {
if(mRemoteControl == null) {
return;
}
diff --git a/app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientJB.java b/app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientJB.java
index e61e9a47..d10c8594 100644
--- a/app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientJB.java
+++ b/app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientJB.java
@@ -1,17 +1,10 @@
package github.daneren2005.dsub.util.compat;
-import github.daneren2005.dsub.domain.MusicDirectory;
-import github.daneren2005.dsub.util.ImageLoader;
import android.annotation.TargetApi;
-import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.media.AudioManager;
-import android.media.MediaMetadataRetriever;
import android.media.RemoteControlClient;
-import github.daneren2005.dsub.activity.SubsonicActivity;
-import github.daneren2005.dsub.service.DownloadService;
+
import github.daneren2005.dsub.util.SilentBackgroundTask;
@TargetApi(18)
@@ -36,13 +29,13 @@ public class RemoteControlClientJB extends RemoteControlClientICS {
return null;
}
}.execute();
- setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYING);
+ setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYING, 0, 0);
}
});
}
@Override
- public void setPlaybackState(final int state) {
+ public void setPlaybackState(final int state, int index, int queueSize) {
if(mRemoteControl == null) {
return;
}
diff --git a/app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientLP.java b/app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientLP.java
index df468155..d666afb2 100644
--- a/app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientLP.java
+++ b/app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientLP.java
@@ -39,7 +39,6 @@ import android.support.v7.media.MediaRouter;
import android.util.Log;
import android.view.KeyEvent;
-import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@@ -50,7 +49,6 @@ import github.daneren2005.dsub.domain.Bookmark;
import github.daneren2005.dsub.domain.MusicDirectory;
import github.daneren2005.dsub.domain.MusicDirectory.Entry;
import github.daneren2005.dsub.domain.Playlist;
-import github.daneren2005.dsub.domain.PodcastEpisode;
import github.daneren2005.dsub.domain.SearchCritera;
import github.daneren2005.dsub.domain.SearchResult;
import github.daneren2005.dsub.service.DownloadFile;
@@ -123,8 +121,12 @@ public class RemoteControlClientLP extends RemoteControlClientBase {
mediaSession.release();
}
+ private void setPlaybackState(int state) {
+ setPlaybackState(state, downloadService.getCurrentPlayingIndex(), downloadService.size());
+ }
+
@Override
- public void setPlaybackState(int state) {
+ public void setPlaybackState(int state, int index, int queueSize) {
PlaybackState.Builder builder = new PlaybackState.Builder();
int newState = PlaybackState.STATE_NONE;
@@ -156,7 +158,7 @@ public class RemoteControlClientLP extends RemoteControlClientBase {
isSong = entry.isSong();
}
- builder.setActions(getPlaybackActions(isSong));
+ builder.setActions(getPlaybackActions(isSong, index, queueSize));
if(entry != null) {
addCustomActions(entry, builder);
@@ -240,14 +242,12 @@ public class RemoteControlClientLP extends RemoteControlClientBase {
return mediaSession;
}
- protected long getPlaybackActions(boolean isSong) {
+ protected long getPlaybackActions(boolean isSong, int currentIndex, int size) {
long actions = PlaybackState.ACTION_PLAY |
PlaybackState.ACTION_PAUSE |
PlaybackState.ACTION_SEEK_TO |
PlaybackState.ACTION_SKIP_TO_QUEUE_ITEM;
- int currentIndex = downloadService.getCurrentPlayingIndex();
- int size = downloadService.size();
if(isSong) {
if (currentIndex > 0) {
actions |= PlaybackState.ACTION_SKIP_TO_PREVIOUS;
diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml
index 9042839f..885035a4 100644
--- a/app/src/main/res/values-pt-rPT/strings.xml
+++ b/app/src/main/res/values-pt-rPT/strings.xml
@@ -36,6 +36,7 @@
<string name="button_bar.now_playing">A reproduzir agora</string>
<string name="button_bar.podcasts">Podcasts</string>
<string name="button_bar.bookmarks">Marcadores</string>
+ <string name="button_bar.internet_radio">Rádios online</string>
<string name="button_bar.shares">Partilhas</string>
<string name="button_bar.chat">Chat</string>
<string name="button_bar.admin">Administração</string>
@@ -43,17 +44,17 @@
<string name="button_bar.offline">Offline</string>
<string name="main.welcome_title">Bem-vindo!</string>
- <string name="main.welcome_text">Bem-vindo ao DSub! Atualmente a aplicação está configurada para usar o servidor de demonstração do Subsonic. Depois de configurar o seu servidor pessoal (disponível em <b>subsonic.org</b>), vá às <b>Definições</b> e altere as configurações para que possa conectar-se.</string>
+ <string name="main.welcome_text">Bem-vindo ao DSub! Atualmente a aplicação está configurada para usar o servidor de demonstração do Subsonic. Depois de configurar o seu servidor pessoal (disponível em <b>subsonic.org</b>), consulte as <b>Definições</b> e altere as configurações para que possa conectar-se.</string>
<string name="main.about_title">Sobre o DSub</string>
<string name="main.faq_title">FAQ</string>
<string name="main.faq_text">
<![CDATA[
<font color="red">Cache vs Cache permanente</font>:
- <br/>Quando o DSub transfere as músicas, elas poderão vir a ser eliminadas mais tarde para dar espaço para novas transferências. Por outro lado, as músicas que ficam permanentemente na cache nunca serão eliminadas.
- <p/><font color="red">Falhas com o ChromeCast</font>:
- <br/>Experimente a opção Definições -> Reprodução -> Usar dispositivo como proxy. É uma solução alternativa devido ao Chromecast não aceitar certificados auto-assinados.
+ <br/>Quando o DSub transfere as músicas, as mesmas poderão ser eliminadas mais tarde para dar espaço para novas transferências. Por outro lado, as músicas que ficam permanentemente na cache nunca serão eliminadas.
+ <p/><font color="red">Falhas com o Chromecast</font>:
+ <br/>Experimente a opção Definições -> Transmissão -> Usar dispositivo como proxy. É uma solução alternativa devido ao Chromecast não aceitar certificados auto-assinados.
<p/><font color="red">Primeiro nível na biblioteca são grupos de artistas</font>:
- <br/>No menu de opções, desmarque a opção "Artistas no primeiro nível". Isto irá fazer com que o primeiro nível de diretorias apresentado seja tratado como grupos de artistas em vez de artistas propriamente ditos.
+ <br/>No menu de opções, desmarque a opção "Artistas no primeiro nível". Isto fará com que o primeiro nível de diretorias apresentado seja tratado como grupos de artistas em vez de artistas propriamente ditos.
]]>
</string>
<string name="main.shuffle">Aleatório</string>
@@ -192,7 +193,7 @@
<string name="download.menu_shuffle_notification">A lista de reprodução foi aleatorizada</string>
<string name="download.menu_remove_played_songs">Remover músicas reproduzidas</string>
<string name="download.playlist_title">Guardar lista de reprodução</string>
- <string name="download.playlist_name">Introduza o nome da lista de reprodução:</string>
+ <string name="download.playlist_name">Introduza um nome para a lista de reprodução:</string>
<string name="download.playlist_saving">A guardar a lista de reprodução \"%s\"...</string>
<string name="download.playlist_done">A lista de reprodução foi guardada com sucesso.</string>
<string name="download.playlist_error">Falha ao guardar a lista de reprodução, tente novamente mais tarde.</string>
@@ -219,6 +220,12 @@
<string name="download.thumbs_up">Gosto</string>
<string name="download.thumbs_down">Não gosto</string>
<string name="download.batch_mode">Modo em série</string>
+ <string name="download.playback_speed_half">0.5x</string>
+ <string name="download.playback_speed_normal">1x</string>
+ <string name="download.playback_speed_one_half">1.5x</string>
+ <string name="download.playback_speed_double">2x</string>
+ <string name="download.playback_speed_tripple">3x</string>
+ <string name="download.playback_speed_custom">Personalizado</string>
<string name="sync.new_podcasts">Novos podcasts disponíveis</string>
<string name="sync.new_playlists">Novas músicas nas listas de reprodução</string>
@@ -277,8 +284,8 @@
<string name="settings.server_sync_summary">Ativar ou não a sincronização para este servidor</string>
<string name="settings.server_sync">Sincronização ativa</string>
<string name="settings.cache_title">Cache de música</string>
- <string name="settings.preload_wifi">Músicas para pre-carregar (Wi-Fi)</string>
- <string name="settings.preload_mobile">Músicas para pre-carregar (dados móveis)</string>
+ <string name="settings.preload_wifi">Músicas para pré-carregar (Wi-Fi)</string>
+ <string name="settings.preload_mobile">Músicas para pré-carregar (dados móveis)</string>
<string name="settings.cache_size">Tamanho da cache</string>
<string name="settings.cache_location">Localização da cache</string>
<string name="settings.cache_location_error">Localização da cache inválida. A utilizar predefinição.</string>
@@ -299,6 +306,8 @@
<string name="settings.theme_dark">Escuro</string>
<string name="settings.theme_black">Preto</string>
<string name="settings.theme_holo">Holo</string>
+ <string name="settings.theme_day_night">Dia/Noite</string>
+ <string name="settings.theme_day_black_night">Dia/Noite (Preto)</string>
<string name="settings.theme_fullscreen">Ecrã inteiro</string>
<string name="settings.theme_fullscreen_summary">Ocultar o maior número de elementos da interface que o Android permita</string>
<string name="settings.track_title">Mostrar número da faixa</string>
@@ -332,7 +341,7 @@
<string name="settings.max_video_bitrate_2000">2000 Kbps</string>
<string name="settings.max_video_bitrate_3000">3000 Kbps</string>
<string name="settings.max_video_bitrate_5000">5000 Kbps</string>
- <string name="settings.max_bitrate_unlimited">Ilimitado</string>
+ <string name="settings.max_bitrate_unlimited">Ilimitada</string>
<string name="settings.wifi_required_title">Transmissão apenas em Wi-Fi</string>
<string name="settings.wifi_required_summary">Apenas transmitir multimédia se ligado por Wi-Fi</string>
<string name="settings.network_timeout_title">Intervalo de ligação</string>
@@ -352,7 +361,7 @@
<string name="settings.search_history_cleared">O histório de pesquisa foi apagado</string>
<string name="settings.other_title">Outras definições</string>
<string name="settings.scrobble_title">Scrobble para Last.FM</string>
- <string name="settings.scrobble_summary">Lembrar de configurar o nome de utilizador e palavra-passe do Last.FM no servidor Subsonic</string>
+ <string name="settings.scrobble_summary">Não se esqueça de configurar o seu nome de utilizador e palavra-passe do Last.FM no servidor Subsonic</string>
<string name="settings.hide_media_title">Ocultar do resto</string>
<string name="settings.hide_media_summary">Ocultar ficheiros de música das outras aplicações</string>
<string name="settings.hide_media_toast">As mudanças terão efeito na próxima vez que o Android procure músicas no seu dispositivo.</string>
@@ -367,12 +376,12 @@
<string name="settings.sleep_timer_off">Desligado</string>
<string name="settings.sleep_timer_on">Ligado</string>
<string name="settings.sleep_timer_always_on">Sempre ligado</string>
- <string name="settings.temp_loss_title">Perda de foco temporário</string>
+ <string name="settings.temp_loss_title">Perda temporária de foco</string>
<string name="settings.temp_loss_pause">Pausar sempre</string>
<string name="settings.temp_loss_pause_lower">Pausar, baixar volume quando pedido</string>
<string name="settings.temp_loss_lower">Baixar sempre o volume</string>
<string name="settings.temp_loss_nothing">Não fazer nada</string>
- <string name="settings.keep_played_count_title">Manter músicas reproduzidas</string>
+ <string name="settings.keep_played_count_title">Manter as músicas reproduzidas</string>
<string name="settings.keep_played_count_none">Remover todas as músicas reproduzidas</string>
<string name="settings.keep_played_count_one">Manter as últimas músicas reproduzidas</string>
<string name="settings.keep_played_count_two">Manter as 2 últimas músicas reproduzidas</string>
@@ -384,14 +393,14 @@
<string name="settings.persistent_summary">Mostrar a notificação mesmo depois de pausar. Pressione o botão de parar para a remover</string>
<string name="settings.gapless_playback">Reprodução sem pausas</string>
<string name="settings.gapless_playback_summary">Se notar falhas estranhas durante a reprodução, desmarcar esta opção pode ajudar</string>
- <string name="settings.chat_refresh">Taxa de atualização do Chat (s)</string>
+ <string name="settings.chat_refresh">Taxa de atualização do chat (s)</string>
<string name="settings.chat_enabled">Ativar chat</string>
<string name="settings.chat_enabled_summary">Mostrar ou não a opção \"Chat\" no menu lateral</string>
<string name="settings.video_title">Vídeo</string>
<string name="settings.video_player">Reprodutor de vídeo</string>
<string name="settings.video_raw">Raw (Requer Subsonic 4.8+)</string>
<string name="settings.video_hls">HTTP Live Stream (HLS) (Requer Subsonic 4.8+)</string>
- <string name="settings.video_transcode">Transcodificação direta (Requísitos de vídeo -> mp4 ou configuração similar no servidor</string>
+ <string name="settings.video_transcode">Transcodificação direta (Requer vídeo -> mp4 ou configuração similar no servidor</string>
<string name="settings.video_flash">Flash (Requer plugin)</string>
<string name="settings.cache_screen_title">Cache/Ligação</string>
<string name="settings.playback_title">Reprodução</string>
@@ -401,6 +410,8 @@
<string name="settings.podcasts_enabled_summary">Mostrar ou não a opção \"Podcasts\" no menu lateral</string>
<string name="settings.bookmarks_enabled">Ativar marcadores</string>
<string name="settings.bookmarks_enabled_summary">Mostrar ou não a opção \"Marcadores\" no menu lateral</string>
+ <string name="settings.internet_radio_enabled">Ativar rádios online</string>
+ <string name="settings.internet_radio_enabled_summary">Mostrar ou não a opção \"Rádios online\" no menu lateral</string>
<string name="settings.shares_enabled">Ativar partilhas</string>
<string name="settings.shares_enabled_summary">Mostrar ou não a opção \"Partilhas\" no menu lateral</string>
<string name="settings.sync_title">Sincronização</string>
@@ -437,21 +448,26 @@
<string name="settings.browse_by_tags">Procurar por tags</string>
<string name="settings.browse_by_tags_summary">Procurar por tags em vez da estrutura das pastas. Requer Subsonic 4.7+</string>
<string name="settings.disable_exit_prompt">Desativar diálogo de saída</string>
- <string name="settings.disable_exit_prompt_summary">Fechar a aplicação imediatamente após pressionar o botão voltar no ecrã inicial</string>
+ <string name="settings.disable_exit_prompt_summary">Fechar a aplicação imediatamente após pressionar o botão de voltar no ecrã inicial</string>
<string name="settings.override_system_language">Sobrepor linguagem do sistema</string>
<string name="settings.override_system_language_summary">Mostrar a aplicação em inglês mesmo se o DSub tiver uma tradução disponível para a linguagem do sistema. Poderá ser necessário limpar a aplicação da memória para as alterações terem efeito</string>
<string name="settings.drawer_items_title">Separadores laterais</string>
+ <string name="settings.song_press_action">Ação ao pressionar uma música</string>
+ <string name="settings.song_press_play_single">Reproduzir apenas essa música</string>
+ <string name="settings.song_press_play_all">Adicionar tudo no álbum à fila de reprodução</string>
+ <string name="settings.song_press_play_next">Adicionar como próxima música</string>
+ <string name="settings.song_press_play_last">Adicionar música ao fim da fila de reprodução</string>
<string name="settings.large_album_art">Grandes capas de álbum</string>
<string name="settings.large_album_art_summary">Mostrar os álbuns com uma grande capa em vez de em lista</string>
<string name="settings.admin_enabled">Ativar administração</string>
<string name="settings.admin_enabled_summary">Mostrar ou não a opção \"Administração\" no menu lateral</string>
<string name="settings.replay_gain">Replay Gain</string>
- <string name="settings.replay_gain_summary">Escalar ou não o volume da reprodução por tags de replay gain nos álbuns e faixas</string>
+ <string name="settings.replay_gain_summary">Escalar ou não o volume da reprodução por tags \"replay gain\" nos álbuns e faixas</string>
<string name="settings.replay_gain_type">Ler pelas tags</string>
<string name="settings.replay_gain_type.smart">Deteção inteligente</string>
<string name="settings.replay_gain_type.album">Tags nos álbuns</string>
<string name="settings.replay_gain_type.track">Tags nas faixas</string>
- <string name="settings.replay_gain_bump">Pré-amp do Replay Gain</string>
+ <string name="settings.replay_gain_bump">Pré-amplificação do Replay Gain</string>
<string name="settings.replay_gain_untagged">Músicas sem Replay Gain</string>
<string name="settings.casting">Transmissão</string>
<string name="settings.casting_proxy">Usar dispositivo como proxy</string>
@@ -461,14 +477,14 @@
<string name="settings.start_on_headphones">Iniciar com os auscultadores</string>
<string name="settings.start_on_headphones_summary">Iniciar quando os auscultadores são ligados. Isto requer o uso de um serviço que inicia com o arranque, para verificar o evento de ligação dos auscultadores mesmo quando o DSub não está a ser executado</string>
<string name="settings.color_action_bar">Colorir barra de ações</string>
- <string name="settings.color_action_bar.summary">Colorir ou não a barra de ações e barra de estado</string>
+ <string name="settings.color_action_bar.summary">Colorir ou não a barra de ações e a barra de estado</string>
<string name="settings.shuffle_by_album">Aleatorizar por álbum</string>
<string name="settings.shuffle_by_album.true">Aleatorizar a ordem dos álbuns</string>
<string name="settings.shuffle_by_album.false">Aleatorizar todas as músicas juntas</string>
<string name="settings.casting_stream_original">Transmitir original</string>
<string name="settings.casting_stream_original_summary">Transmitir os ficheiros originais se suportado pelo dispositivo de transmissão</string>
<string name="settings.heads_up_notification">Notificações Heads Up (5.0+)</string>
- <string name="settings.heads_up_notification_summary">Mostrar notificações de reprodução como notificações Heads Up (Android Lollipop+ apenas)</string>
+ <string name="settings.heads_up_notification_summary">Mostrar notificações de reprodução como notificações \"Heads Up\" (Android Lollipop+ apenas)</string>
<string name="settings.casting_cache">Cache durante a transmissão</string>
<string name="settings.casting_cache_summary">Adicionar à cache as músicas a reproduzir no momento da transmissão</string>
@@ -596,6 +612,7 @@
<string name="details.title.podcast">Detalhes do podcast</string>
<string name="details.title.playlist">Detalhes da lista de reprodução</string>
<string name="details.title.artist">Detalhes do artista</string>
+ <string name="details.title.internet_radio_station">Detalhes da rádio online</string>
<string name="details.podcast">Podcast</string>
<string name="details.status">Estado</string>
<string name="details.artist">Artista</string>
@@ -635,6 +652,10 @@
<string name="details.last_played">Última reprodução</string>
<string name="details.expiration">Expiração</string>
<string name="details.played_count">Nº de reproduções</string>
+ <string name="details.stream_url">URL da transmissão</string>
+ <string name="details.home_page">Página web</string>
+
+ <string name="permission.external_storage.failed">O DSub não funciona se não puder escrever no armazenamento</string>
<plurals name="select_album_n_songs">
<item quantity="zero">Sem músicas</item>
@@ -646,8 +667,8 @@
<item quantity="other">%d músicas agendadas para transferência.</item>
</plurals>
<plurals name="select_album_n_songs_added">
- <item quantity="one">Uma música adicionada à lista de reprodução.</item>
- <item quantity="other">%d músicas adicionadas à lista de reprodução.</item>
+ <item quantity="one">Uma música adicionada à fila de reprodução.</item>
+ <item quantity="other">%d músicas adicionadas à fila de reprodução.</item>
</plurals>
<plurals name="select_album_donate_dialog_n_trial_days_left">
<item quantity="one">Um dia de período de testes restante</item>
diff --git a/app/src/main/res/xml/changelog.xml b/app/src/main/res/xml/changelog.xml
index 89f076f7..169edaa0 100644
--- a/app/src/main/res/xml/changelog.xml
+++ b/app/src/main/res/xml/changelog.xml
@@ -1,5 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<changelog>
+ <release version="5.3.1" versioncode="187" releasedate="10/4/2016">
+ <change>Fix Internet Radio streams which point to playlists</change>
+ <change>Don't show playback speed button below Android 6.0</change>
+ </release>
<release version="5.3" versioncode="186" releasedate="9/23/2016">
<change>Listen to Radio Internet Stations</change>
<change>Automatic Day/Night theme</change>