diff options
author | Koen <koen@koenvh.nl> | 2018-08-01 18:21:12 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-01 18:21:12 +0200 |
commit | 32a1cfa82165a5af8ec8b8013b4b41c13b6b47d9 (patch) | |
tree | f5c417b2cfbbdb619d1d004fd0f676db99794025 | |
parent | 9dc25397072fd00ea73bdbeed9b46afdce366349 (diff) | |
parent | 50583cec5ab2148209ea8b050712aa5f1878ed64 (diff) | |
download | dsub-32a1cfa82165a5af8ec8b8013b4b41c13b6b47d9.tar.gz dsub-32a1cfa82165a5af8ec8b8013b4b41c13b6b47d9.tar.bz2 dsub-32a1cfa82165a5af8ec8b8013b4b41c13b6b47d9.zip |
Merge pull request #1 from daneren2005/edge
Merge DSub 5.4
-rw-r--r-- | app/build.gradle | 18 | ||||
-rw-r--r-- | app/src/google/AndroidManifest.xml | 30 | ||||
-rw-r--r-- | app/src/main/java/github/daneren2005/dsub/provider/DLNARouteProvider.java | 24 | ||||
-rw-r--r-- | app/src/main/java/github/daneren2005/dsub/service/DownloadService.java | 133 | ||||
-rw-r--r-- | app/src/main/java/github/daneren2005/dsub/util/Notifications.java | 68 | ||||
-rw-r--r-- | app/src/main/res/values-hu/strings.xml | 5 | ||||
-rw-r--r-- | app/src/main/res/values-pt-rPT/strings.xml | 42 | ||||
-rw-r--r-- | app/src/main/res/xml/changelog.xml | 16 | ||||
-rw-r--r-- | build.gradle | 5 |
9 files changed, 220 insertions, 121 deletions
diff --git a/app/build.gradle b/app/build.gradle index 47604723..3c8e5f45 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,15 +1,15 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 24 + compileSdkVersion 27 buildToolsVersion '25.0.0' defaultConfig { applicationId "github.daneren2005.dsub" minSdkVersion 14 - targetSdkVersion 23 - versionCode 195 - versionName '5.3.5' + targetSdkVersion 26 + versionCode 198 + versionName '5.4.1' setProperty("archivesBaseName", "DSub $versionName") resConfigs "de", "es", "fr", "hu", "nl", "pt-rPT", "ru", "sv" } @@ -56,11 +56,11 @@ android { dependencies { compile project(':Server Proxy') compile fileTree(include: ['*.jar'], dir: 'libs') - compile 'com.android.support:support-v4:24.2.+' - compile 'com.android.support:appcompat-v7:24.2.+' - compile 'com.android.support:mediarouter-v7:24.2.+' - compile 'com.android.support:recyclerview-v7:24.2.+' - compile 'com.android.support:design:24.2.+' + compile 'com.android.support:support-v4:27.1.+' + compile 'com.android.support:appcompat-v7:27.1.+' + compile 'com.android.support:mediarouter-v7:27.1.+' + compile 'com.android.support:recyclerview-v7:27.1.+' + compile 'com.android.support:design:27.1.+' googleCompile 'com.google.android.gms:play-services-cast:8.1.0' compile 'com.sothree.slidinguppanel:library:3.0.0' compile 'de.hdodenhof:circleimageview:1.2.1' diff --git a/app/src/google/AndroidManifest.xml b/app/src/google/AndroidManifest.xml index 14827d43..0708a47e 100644 --- a/app/src/google/AndroidManifest.xml +++ b/app/src/google/AndroidManifest.xml @@ -2,17 +2,23 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="github.daneren2005.dsub"> - <meta-data - android:name="com.google.android.backup.api_key" - android:value="AEdPqrEAAAAIUhOMtwa_eG-f0oYUHnetl_Cz7cO9zae8ZXOK5w" /> - <meta-data - android:name="com.google.android.gms.version" - android:value="@integer/google_play_services_version" /> - <meta-data - android:name="com.google.android.gms.car.application" - android:resource="@xml/auto_app_description" /> - <meta-data - android:name="com.google.android.gms.car.notification.SmallIcon" - android:resource="@drawable/stat_notify_playing" /> + <application android:label="@string/common.appname" + android:backupAgent="github.daneren2005.dsub.util.SettingsBackupAgent" + android:icon="@drawable/launch" + android:theme="@style/Theme.DSub.Light"> + + <meta-data + android:name="com.google.android.backup.api_key" + android:value="AEdPqrEAAAAIUhOMtwa_eG-f0oYUHnetl_Cz7cO9zae8ZXOK5w" /> + <meta-data + android:name="com.google.android.gms.version" + android:value="@integer/google_play_services_version" /> + <meta-data + android:name="com.google.android.gms.car.application" + android:resource="@xml/auto_app_description" /> + <meta-data + android:name="com.google.android.gms.car.notification.SmallIcon" + android:resource="@drawable/stat_notify_playing" /> + </application> </manifest> diff --git a/app/src/main/java/github/daneren2005/dsub/provider/DLNARouteProvider.java b/app/src/main/java/github/daneren2005/dsub/provider/DLNARouteProvider.java index 0ee16723..f4238c99 100644 --- a/app/src/main/java/github/daneren2005/dsub/provider/DLNARouteProvider.java +++ b/app/src/main/java/github/daneren2005/dsub/provider/DLNARouteProvider.java @@ -228,7 +228,9 @@ public class DLNARouteProvider extends MediaRouteProvider { removing.remove(id); return; } - adding.add(id); + synchronized (adding) { + adding.add(id); + } if(device.getType().getType().equals("MediaRenderer") && device instanceof RemoteDevice) { try { @@ -255,21 +257,35 @@ public class DLNARouteProvider extends MediaRouteProvider { broadcastDescriptors(); } }); - adding.remove(id); + + synchronized (adding) { + if (adding.contains(id)) { + adding.remove(id); + } + } } @Override public void failure(ActionInvocation actionInvocation, UpnpResponse upnpResponse, String s) { Log.w(TAG, "Failed to get default volume for DLNA route"); Log.w(TAG, "Reason: " + s); - adding.remove(id); + + synchronized (adding) { + if (adding.contains(id)) { + adding.remove(id); + } + } } }); } catch(Exception e) { Log.e(TAG, "Failed to add device", e); } } else { - adding.remove(id); + synchronized (adding) { + if(adding.contains(id)) { + adding.remove(id); + } + } } } private void deviceRemoved(Device device) { 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 c5caad26..a4ca705c 100644 --- a/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java +++ b/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java @@ -68,6 +68,7 @@ import java.util.Iterator; import java.util.List; import java.util.Timer; import java.util.TimerTask; +import java.util.concurrent.CopyOnWriteArrayList; import android.annotation.TargetApi; import android.app.Service; @@ -154,7 +155,7 @@ public class DownloadService extends Service { private boolean removePlayed; private boolean shufflePlay; private boolean artistRadio; - private final List<OnSongChangedListener> onSongChangedListeners = new ArrayList<>(); + private final CopyOnWriteArrayList<OnSongChangedListener> onSongChangedListeners = new CopyOnWriteArrayList<>(); private long revision; private static DownloadService instance; private String suggestedPlaylistName; @@ -2800,12 +2801,7 @@ public class DownloadService extends Service { addOnSongChangedListener(listener, false); } public void addOnSongChangedListener(OnSongChangedListener listener, boolean run) { - synchronized(onSongChangedListeners) { - int index = onSongChangedListeners.indexOf(listener); - if (index == -1) { - onSongChangedListeners.add(listener); - } - } + onSongChangedListeners.addIfAbsent(listener); if(run) { if(mediaPlayerHandler != null) { @@ -2824,56 +2820,47 @@ public class DownloadService extends Service { } } public void removeOnSongChangeListener(OnSongChangedListener listener) { - synchronized(onSongChangedListeners) { - int index = onSongChangedListeners.indexOf(listener); - if (index != -1) { - onSongChangedListeners.remove(index); - } - } + onSongChangedListeners.remove(listener); } private void onSongChanged() { final long atRevision = revision; - synchronized(onSongChangedListeners) { - final boolean shouldFastForward = shouldFastForward(); - for (final OnSongChangedListener listener : onSongChangedListeners) { - handler.post(new Runnable() { - @Override - public void run() { - if (revision == atRevision && instance != null) { - listener.onSongChanged(currentPlaying, currentPlayingIndex, shouldFastForward); + final boolean shouldFastForward = shouldFastForward(); + for (final OnSongChangedListener listener : onSongChangedListeners) { + handler.post(new Runnable() { + @Override + public void run() { + if (revision == atRevision && instance != null) { + listener.onSongChanged(currentPlaying, currentPlayingIndex, shouldFastForward); - MusicDirectory.Entry entry = currentPlaying != null ? currentPlaying.getSong() : null; - listener.onMetadataUpdate(entry, METADATA_UPDATED_ALL); - } + MusicDirectory.Entry entry = currentPlaying != null ? currentPlaying.getSong() : null; + listener.onMetadataUpdate(entry, METADATA_UPDATED_ALL); } - }); - } + } + }); + } - if (mediaPlayerHandler != null && !onSongChangedListeners.isEmpty()) { - mediaPlayerHandler.post(new Runnable() { - @Override - public void run() { - onSongProgress(); - } - }); - } + if (mediaPlayerHandler != null && !onSongChangedListeners.isEmpty()) { + mediaPlayerHandler.post(new Runnable() { + @Override + public void run() { + onSongProgress(); + } + }); } } private void onSongsChanged() { final long atRevision = revision; - synchronized(onSongChangedListeners) { - final boolean shouldFastForward = shouldFastForward(); - for (final OnSongChangedListener listener : onSongChangedListeners) { - handler.post(new Runnable() { - @Override - public void run() { - if (revision == atRevision && instance != null) { - listener.onSongsChanged(downloadList, currentPlaying, currentPlayingIndex, shouldFastForward); - } + final boolean shouldFastForward = shouldFastForward(); + for (final OnSongChangedListener listener : onSongChangedListeners) { + handler.post(new Runnable() { + @Override + public void run() { + if (revision == atRevision && instance != null) { + listener.onSongsChanged(downloadList, currentPlaying, currentPlayingIndex, shouldFastForward); } - }); - } + } + }); } } @@ -2888,17 +2875,15 @@ public class DownloadService extends Service { final int index = getCurrentPlayingIndex(); final int queueSize = size(); - synchronized(onSongChangedListeners) { - for (final OnSongChangedListener listener : onSongChangedListeners) { - handler.post(new Runnable() { - @Override - public void run() { - if (revision == atRevision && instance != null) { - listener.onSongProgress(currentPlaying, position, duration, isSeekable); - } + for (final OnSongChangedListener listener : onSongChangedListeners) { + handler.post(new Runnable() { + @Override + public void run() { + if (revision == atRevision && instance != null) { + listener.onSongProgress(currentPlaying, position, duration, isSeekable); } - }); - } + } + }); } if(manual) { @@ -2921,35 +2906,31 @@ public class DownloadService extends Service { } private void onStateUpdate() { final long atRevision = revision; - synchronized(onSongChangedListeners) { - for (final OnSongChangedListener listener : onSongChangedListeners) { - handler.post(new Runnable() { - @Override - public void run() { - if (revision == atRevision && instance != null) { - listener.onStateUpdate(currentPlaying, playerState); - } + for (final OnSongChangedListener listener : onSongChangedListeners) { + handler.post(new Runnable() { + @Override + public void run() { + if (revision == atRevision && instance != null) { + listener.onStateUpdate(currentPlaying, playerState); } - }); - } + } + }); } } public void onMetadataUpdate() { onMetadataUpdate(METADATA_UPDATED_ALL); } public void onMetadataUpdate(final int updateType) { - synchronized(onSongChangedListeners) { - for (final OnSongChangedListener listener : onSongChangedListeners) { - handler.post(new Runnable() { - @Override - public void run() { - if (instance != null) { - MusicDirectory.Entry entry = currentPlaying != null ? currentPlaying.getSong() : null; - listener.onMetadataUpdate(entry, updateType); - } + for (final OnSongChangedListener listener : onSongChangedListeners) { + handler.post(new Runnable() { + @Override + public void run() { + if (instance != null) { + MusicDirectory.Entry entry = currentPlaying != null ? currentPlaying.getSong() : null; + listener.onMetadataUpdate(entry, updateType); } - }); - } + } + }); } handler.post(new Runnable() { 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 750ab40c..428c33e0 100644 --- a/app/src/main/java/github/daneren2005/dsub/util/Notifications.java +++ b/app/src/main/java/github/daneren2005/dsub/util/Notifications.java @@ -15,7 +15,9 @@ package github.daneren2005.dsub.util; +import android.annotation.TargetApi; import android.app.Notification; +import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.ComponentName; @@ -56,11 +58,24 @@ public final class Notifications { private static boolean downloadForeground = false; private static boolean persistentPlayingShowing = false; + private static NotificationChannel playingChannel; + private static NotificationChannel downloadingChannel; + private static NotificationChannel syncChannel; + private final static Pair<Integer, Integer> NOTIFICATION_TEXT_COLORS = new Pair<Integer, Integer>(); public static void showPlayingNotification(final Context context, final DownloadService downloadService, final Handler handler, MusicDirectory.Entry song) { + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + getPlayingNotificationChannel(context); + } + // Set the icon, scrolling text and timestamp - final Notification notification = new Notification(R.drawable.stat_notify_playing, song.getTitle(), System.currentTimeMillis()); + final Notification notification = new NotificationCompat.Builder(context) + .setSmallIcon(R.drawable.stat_notify_playing) + .setTicker(song.getTitle()) + .setWhen(System.currentTimeMillis()) + .setChannelId("now-playing-channel") + .build(); final boolean playing = downloadService.getPlayerState() == PlayerState.STARTED; if(playing) { @@ -331,7 +346,24 @@ public final class Notifications { DSubWidgetProvider.notifyInstances(context, downloadService, false); } + @TargetApi(Build.VERSION_CODES.O) + private static NotificationChannel getPlayingNotificationChannel(Context context) { + if(playingChannel == null) { + playingChannel = new NotificationChannel("now-playing-channel", "Now Playing", NotificationManager.IMPORTANCE_LOW); + playingChannel.setDescription("Now playing notification"); + + NotificationManager notificationManager = context.getSystemService(NotificationManager.class); + notificationManager.createNotificationChannel(playingChannel); + } + + return playingChannel; + } + public static void showDownloadingNotification(final Context context, final DownloadService downloadService, Handler handler, DownloadFile file, int size) { + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + getDownloadingNotificationChannel(context); + } + Intent cancelIntent = new Intent(context, DownloadService.class); cancelIntent.setAction(DownloadService.CANCEL_DOWNLOADS); PendingIntent cancelPI = PendingIntent.getService(context, 0, cancelIntent, 0); @@ -356,7 +388,8 @@ public final class Notifications { .setOngoing(true) .addAction(R.drawable.notification_close, context.getResources().getString(R.string.common_cancel), - cancelPI); + cancelPI) + .setChannelId("downloading-channel"); Intent notificationIntent = new Intent(context, SubsonicFragmentActivity.class); notificationIntent.putExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD_VIEW, true); @@ -395,6 +428,19 @@ public final class Notifications { } } + @TargetApi(Build.VERSION_CODES.O) + private static NotificationChannel getDownloadingNotificationChannel(Context context) { + if(downloadingChannel == null) { + downloadingChannel = new NotificationChannel("downloading-channel", "Downloading Notification", NotificationManager.IMPORTANCE_LOW); + downloadingChannel.setDescription("Ongoing downloading notification to keep the service alive"); + + NotificationManager notificationManager = context.getSystemService(NotificationManager.class); + notificationManager.createNotificationChannel(downloadingChannel); + } + + return downloadingChannel; + } + public static void showSyncNotification(final Context context, int stringId, String extra) { showSyncNotification(context, stringId, extra, null); } @@ -404,6 +450,10 @@ public final class Notifications { extra = ""; } + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + getSyncNotificationChannel(context); + } + NotificationCompat.Builder builder; builder = new NotificationCompat.Builder(context) .setSmallIcon(R.drawable.stat_notify_sync) @@ -413,6 +463,7 @@ public final class Notifications { .setOngoing(false) .setGroup(NOTIFICATION_SYNC_GROUP) .setPriority(NotificationCompat.PRIORITY_LOW) + .setChannelId("sync-channel") .setAutoCancel(true); Intent notificationIntent = new Intent(context, SubsonicFragmentActivity.class); @@ -449,4 +500,17 @@ public final class Notifications { notificationManager.notify(stringId, builder.build()); } } + + @TargetApi(Build.VERSION_CODES.O) + private static NotificationChannel getSyncNotificationChannel(Context context) { + if(syncChannel == null) { + syncChannel = new NotificationChannel("sync-channel", "Sync Notifications", NotificationManager.IMPORTANCE_MIN); + syncChannel.setDescription("Sync notifications"); + + NotificationManager notificationManager = context.getSystemService(NotificationManager.class); + notificationManager.createNotificationChannel(syncChannel); + } + + return syncChannel; + } } diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 3416a471..6a2799ea 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -346,6 +346,8 @@ <string name="settings.max_bitrate_unlimited">Korlátlan</string> <string name="settings.wifi_required_title">Streamelés csak Wi-Fivel</string> <string name="settings.wifi_required_summary">Streamelés csak Wi-Fi hálózaton keresztül.</string> + <string name="settings.local_network_required_title">Ne streameljen roaming közben</string> + <string name="settings.local_network_required_summary">Ne streameljen médiát roaming közben</string> <string name="settings.network_timeout_title">Hálózati időtúllépés</string> <string name="settings.network_timeout_10000">10 másodperc</string> <string name="settings.network_timeout_15000">15 másodperc</string> @@ -491,6 +493,8 @@ <string name="settings.casting_cache_summary">Az éppen lejátszott dal gyorsítótárazása a tartalomátküldés (Casting) alatt.</string> <string name="settings.casting.dlna_casting_enabled">DLNA engedélyezve</string> <string name="settings.casting.dlna_casting_enabled.summary">Ha akkumulátor-merülési probléma lépne fel Android 7.0 alatt, kapcsolja ki a funkciót!</string> + <string name="settings.rewind_interval">Visszatekerés időintervalluma</string> + <string name="settings.fastforward_interval">Gyors előretekerés időintervalluma</string> <string name="shuffle.title">Dalsorrend keverése</string> <string name="shuffle.startYear">Kezdő év:</string> @@ -498,6 +502,7 @@ <string name="shuffle.genre">Műfaj:</string> <string name="shuffle.pick_genre">Műfaj kiválasztása</string> + <string name="share.create_error">%s megosztás létrehozása sikertelen!</string> <string name="share.expires">Lejárati idő: %s</string> <string name="share.expires_never">Nincs lejárati idő</string> <string name="share.deleted">\"%s\" megosztás törölve</string> diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 885035a4..c8f59195 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -50,11 +50,11 @@ <string name="main.faq_text"> <![CDATA[ <font color="red">Cache vs Cache permanente</font>: - <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. + <br/>Quando o DSub transfere as músicas, as mesmas poderão vir a ser eliminadas para dar espaço a novas transferências. Por outro lado, as músicas que ficam permanentemente na cache nunca serão eliminadas automaticamente. <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 fará 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 diretórios apresentado seja tratado como grupos de artistas em vez de artistas propriamente ditos. ]]> </string> <string name="main.shuffle">Aleatório</string> @@ -102,7 +102,7 @@ <string name="menu.add_podcast">Adicionar canal</string> <string name="menu.keep_synced">Manter sincronizado</string> <string name="menu.stop_sync">Parar sincronização</string> - <string name="menu.show_all">Mostrar todo o conteúdo</string> + <string name="menu.show_all">Mostrar todas as músicas</string> <string name="menu.show_artist">Mostrar artista</string> <string name="menu.share">Partilhar</string> <string name="menu.delete_cache">Eliminar cache</string> @@ -161,8 +161,8 @@ <string name="select_genre.songs">%d músicas</string> <string name="select_genre.albums">%d álbuns</string> - <string name="select_podcasts.error">Houve um erro ao transferir este podcast no servidor. O servidor deve transferi-lo primeiro.</string> - <string name="select_podcasts.skipped">Este podcast não foi transferido no servidor. O servidor deve transferi-lo primeiro.</string> + <string name="select_podcasts.error">Ocorreu um erro ao transferir este podcast no servidor. O servidor deve de o transferir primeiro.</string> + <string name="select_podcasts.skipped">Este podcast não foi transferido no servidor. O servidor deve de o transferir primeiro.</string> <string name="select_podcasts.initializing">Este podcast está a ser inicializado no servidor. Por favor atualize dentro de momentos.</string> <string name="select_podcasts.server_download">Transferir no servidor</string> <string name="select_podcasts.server_delete">Eliminar do servidor</string> @@ -282,13 +282,13 @@ <string name="settings.server_password">Palavra-passe</string> <string name="settings.server_open_browser">Abrir no navegador</string> <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.server_sync">Ativar sincronização</string> <string name="settings.cache_title">Cache de música</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> + <string name="settings.cache_location_error">Localização da cache inválida. A usar predefinição.</string> <string name="settings.cache_location_reset">Não foi possível escrever na localização da cache que definiu. Se atualizou recentemente o SO do seu dispositivo para o KitKat 4.4, então o modo como as aplicações escrevem no cartão SD mudou e só podem escrever numa localização específica. A localização que o DSub usa já foi alterada para a localização correta. Para eliminar os antigos dados da aplicação, terá que montar o cartão SD no computador e eliminar a pasta manualmente</string> <string name="settings.cache_location_internal">Interna</string> <string name="settings.cache_location_external">Externa</string> @@ -320,6 +320,7 @@ <string name="settings.max_bitrate_wifi">Taxa de bits máxima do áudio - Wi-Fi</string> <string name="settings.max_bitrate_mobile">Taxa de bits máxima do áudio - Dados móveis</string> <string name="settings.max_bitrate_32">32 Kbps</string> + <string name="settings.max_bitrate_48">48 Kbps</string> <string name="settings.max_bitrate_64">64 Kbps</string> <string name="settings.max_bitrate_80">80 Kbps</string> <string name="settings.max_bitrate_96">96 Kbps</string> @@ -383,7 +384,7 @@ <string name="settings.temp_loss_nothing">Não fazer nada</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_one">Manter a última música reproduzida</string> <string name="settings.keep_played_count_two">Manter as 2 últimas músicas reproduzidas</string> <string name="settings.keep_played_count_three">Manter as 3 últimas músicas reproduzidas</string> <string name="settings.disconnect_pause_title">Pausar ao desconectar</string> @@ -400,7 +401,7 @@ <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 (Requer 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 semelhante 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> @@ -415,8 +416,8 @@ <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> - <string name="settings.sync_enabled">Sincronização ativa</string> - <string name="settings.sync_enabled_summary">Verificar periodicamente ou não as listas de reprodução ou podcasts por alterações</string> + <string name="settings.sync_enabled">Ativar sincronização</string> + <string name="settings.sync_enabled_summary">Verificar ou não periodicamente as listas de reprodução ou podcasts por alterações</string> <string name="settings.sync_interval">Intervalo de sincronização</string> <string name="settings.sync_interval_15">15 minutos</string> <string name="settings.sync_interval_30">30 minutos</string> @@ -445,8 +446,8 @@ <string name="settings.menu_options.star_summary">Mostrar \"Marcar/Remover estrela\" nos menus</string> <string name="settings.menu_options.shared_summary">Mostrar \"Partilhar\" nos menus</string> <string name="settings.menu_options.rate_summary">Mostrar \"Classificar\" nos menus</string> - <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.browse_by_tags">Navegar por etiquetas</string> + <string name="settings.browse_by_tags_summary">Navegar por etiquetas 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 de voltar no ecrã inicial</string> <string name="settings.override_system_language">Sobrepor linguagem do sistema</string> @@ -462,11 +463,11 @@ <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 \"replay gain\" nos álbuns e faixas</string> - <string name="settings.replay_gain_type">Ler pelas tags</string> + <string name="settings.replay_gain_summary">Escalar ou não o volume da reprodução por etiquetas \"replay gain\" nos álbuns e faixas</string> + <string name="settings.replay_gain_type">Ler pelas etiquetas</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_type.album">Etiquetas nos álbuns</string> + <string name="settings.replay_gain_type.track">Etiquetas nas faixas</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> @@ -487,7 +488,12 @@ <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> + <string name="settings.casting.dlna_casting_enabled">Ativar DLNA</string> + <string name="settings.casting.dlna_casting_enabled.summary">Se tiver problemas com o descarregamento da bateria no Android 7.0 experimente desativar isto</string> + <string name="settings.rewind_interval">Intervalo de retrocesso</string> + <string name="settings.fastforward_interval">Intervalo de avanço</string> + <string name="share.create_error">Falha ao criar a partilha %s</string> <string name="shuffle.title">Aleatorizar por</string> <string name="shuffle.startYear">Ano de início:</string> <string name="shuffle.endYear">Ano de fim:</string> @@ -521,7 +527,7 @@ <string name="admin.change_email_invalid">Introduza um email válido</string> <string name="admin.change_password">Alterar palavra-passe</string> <string name="admin.change_password_success">A palavra-passe de %1$s foi alterada com sucesso</string> - <string name="admin.change_password_error">Falha ao alterar palavra-passe de %1$s</string> + <string name="admin.change_password_error">Falha ao alterar a palavra-passe de %1$s</string> <string name="admin.change_password_current_label">Palavra-passe atual:</string> <string name="admin.change_password_label">Nova palavra-passe:</string> <string name="admin.change_password_invalid">Introduza uma palavra-passe válida</string> diff --git a/app/src/main/res/xml/changelog.xml b/app/src/main/res/xml/changelog.xml index d31f6df6..8aa15153 100644 --- a/app/src/main/res/xml/changelog.xml +++ b/app/src/main/res/xml/changelog.xml @@ -1,5 +1,21 @@ <?xml version="1.0" encoding="utf-8"?> <changelog> + <release version="5.4.1" versioncode="198" releasedate="07/29/2018"> + <change>Fix Android Auto compatibility</change> + </release> + <release version="5.4" versioncode="197" releasedate="07/26/2018"> + <change>Add option to change rewind/fast forward interval (thanks KBerstene)</change> + <change>Auto: Play entire directory when selecting song (thanks hufman)</change> + <change>Auto: Show 50 songs instead of 3 (thanks hufman)</change> + <change>Auto: Fix playing from a bookmark when multiple bookmarks in directory (thanks hufman)</change> + <change>Add option to disable downloads while roaming (thanks The-Compiler)</change> + <change>Fix persistent notification showing different actions when paused</change> + <change>Fix OPUS files not showing up in Offline mode</change> + <change>Fix not being able to have servers with _ in the domain</change> + <change>Fix cache exceeding limit with long playlist</change> + <change>Fix error if null album when applying ReplayGain</change> + <change>Fix deadlock bug</change> + </release> <release version="5.3.5" versioncode="195" releasedate="04/18/2016"> <change>Add option to scan server for Subsonic 6.1+</change> <change>Enhanced custom playback speed UI (thanks SilentViking)</change> diff --git a/build.gradle b/build.gradle index b304f7fc..d5dfdd4f 100644 --- a/build.gradle +++ b/build.gradle @@ -3,6 +3,10 @@ buildscript { repositories { jcenter() + maven { + url 'https://maven.google.com/' + name 'Google' + } } dependencies { classpath 'com.android.tools.build:gradle:2.3.3' @@ -18,5 +22,6 @@ allprojects { maven { url 'http://4thline.org/m2' } + google() } } |