aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
m---------ServerProxy0
-rw-r--r--app/build.gradle6
-rw-r--r--app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java10
-rw-r--r--app/src/main/java/github/daneren2005/dsub/domain/ServerInfo.java5
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/MainFragment.java4
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/SelectPlaylistFragment.java22
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/SettingsFragment.java13
-rw-r--r--app/src/main/java/github/daneren2005/dsub/provider/DLNARouteProvider.java15
-rw-r--r--app/src/main/java/github/daneren2005/dsub/service/AutoMediaBrowserService.java126
-rw-r--r--app/src/main/java/github/daneren2005/dsub/service/DownloadService.java3
-rw-r--r--app/src/main/java/github/daneren2005/dsub/service/RESTMusicService.java14
-rw-r--r--app/src/main/java/github/daneren2005/dsub/service/parser/ScanStatusParser.java18
-rw-r--r--app/src/main/java/github/daneren2005/dsub/updates/Updater.java1
-rw-r--r--app/src/main/java/github/daneren2005/dsub/updates/UpdaterNoDLNA.java41
-rw-r--r--app/src/main/java/github/daneren2005/dsub/util/Constants.java1
-rw-r--r--app/src/main/java/github/daneren2005/dsub/util/MediaRouteManager.java23
-rw-r--r--app/src/main/java/github/daneren2005/dsub/util/compat/RemoteControlClientLP.java4
-rw-r--r--app/src/main/res/menu/main.xml2
-rw-r--r--app/src/main/res/values-fr/strings.xml16
-rw-r--r--app/src/main/res/values/arrays.xml2
-rw-r--r--app/src/main/res/values/strings.xml5
-rw-r--r--app/src/main/res/xml/changelog.xml4
-rw-r--r--app/src/main/res/xml/settings_cast.xml10
-rw-r--r--build.gradle2
-rw-r--r--gradle/wrapper/gradle-wrapper.properties4
-rw-r--r--privacy.txt23
26 files changed, 336 insertions, 38 deletions
diff --git a/ServerProxy b/ServerProxy
-Subproject a4d957353db2634906e0d5099d7a078a111bfab
+Subproject d57fe9ee675350799e462ca6a472f70b39475a2
diff --git a/app/build.gradle b/app/build.gradle
index 0f2590d1..0ee48164 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,14 +2,14 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 24
- buildToolsVersion "23.0.3"
+ buildToolsVersion '25.0.0'
defaultConfig {
applicationId "github.daneren2005.dsub"
minSdkVersion 14
targetSdkVersion 23
- versionCode 191
- versionName '5.3.3'
+ versionCode 194
+ versionName '5.3.4'
setProperty("archivesBaseName", "DSub $versionName")
resConfigs "de", "es", "fr", "hu", "nl", "pt-rPT", "ru", "sv"
}
diff --git a/app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java b/app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java
index 0b10d7fb..a1c5ceef 100644
--- a/app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java
+++ b/app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java
@@ -250,12 +250,20 @@ public class SubsonicActivity extends AppCompatActivity implements OnItemSelecte
return;
}
- populateTabs();
getImageLoader().onUIVisible();
UpdateView.addActiveActivity();
}
@Override
+ protected void onResume() {
+ super.onResume();
+
+ // If this is in onStart is causes crashes when rotating screen in offline mode
+ // Actual root cause of error is `drawerItemSelected(newFragment);` in the offline mode branch of code
+ populateTabs();
+ }
+
+ @Override
protected void onStop() {
super.onStop();
diff --git a/app/src/main/java/github/daneren2005/dsub/domain/ServerInfo.java b/app/src/main/java/github/daneren2005/dsub/domain/ServerInfo.java
index e41a9503..5852210e 100644
--- a/app/src/main/java/github/daneren2005/dsub/domain/ServerInfo.java
+++ b/app/src/main/java/github/daneren2005/dsub/domain/ServerInfo.java
@@ -251,4 +251,9 @@ public class ServerInfo implements Serializable {
public static boolean hasNewestPodcastEpisodes(Context context) {
return ServerInfo.checkServerVersion(context, "1.13");
}
+
+ public static boolean canRescanServer(Context context) {
+ return ServerInfo.isMadsonic(context) ||
+ (ServerInfo.isStockSubsonic(context) && ServerInfo.checkServerVersion(context, "1.15"));
+ }
}
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/MainFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/MainFragment.java
index 8c2fa4bf..82e50b76 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/MainFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/MainFragment.java
@@ -67,8 +67,8 @@ public class MainFragment extends SelectRecyclerFragment<Integer> {
onFinishSetupOptionsMenu(menu);
try {
- if (!ServerInfo.isMadsonic(context) || !UserUtil.isCurrentAdmin()) {
- menu.setGroupVisible(R.id.madsonic, false);
+ if (!ServerInfo.canRescanServer(context) || !UserUtil.isCurrentAdmin()) {
+ menu.setGroupVisible(R.id.rescan_server, false);
}
} catch(Exception e) {
Log.w(TAG, "Error on setting madsonic invisible", e);
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SelectPlaylistFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SelectPlaylistFragment.java
index 28cf9911..5cb413fe 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/SelectPlaylistFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/SelectPlaylistFragment.java
@@ -1,5 +1,8 @@
package github.daneren2005.dsub.fragments;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
import android.support.v7.app.AlertDialog;
import android.content.DialogInterface;
import android.content.res.Resources;
@@ -342,7 +345,24 @@ public class SelectPlaylistFragment extends SelectRecyclerFragment<Playlist> {
private void syncPlaylist(Playlist playlist) {
SyncUtil.addSyncedPlaylist(context, playlist.getId());
- downloadPlaylist(playlist.getId(), playlist.getName(), true, true, false, false, true);
+
+ boolean syncImmediately;
+ if(Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_SYNC_WIFI, true)) {
+ ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo networkInfo = manager.getActiveNetworkInfo();
+
+ if(networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
+ syncImmediately = true;
+ } else {
+ syncImmediately = false;
+ }
+ } else {
+ syncImmediately = true;
+ }
+
+ if(syncImmediately) {
+ downloadPlaylist(playlist.getId(), playlist.getName(), true, true, false, false, true);
+ }
}
private void stopSyncPlaylist(final Playlist playlist) {
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SettingsFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SettingsFragment.java
index 584a205a..fa2ca340 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/SettingsFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/SettingsFragment.java
@@ -59,6 +59,7 @@ import github.daneren2005.dsub.service.MusicServiceFactory;
import github.daneren2005.dsub.util.Constants;
import github.daneren2005.dsub.util.FileUtil;
import github.daneren2005.dsub.util.LoadingTask;
+import github.daneren2005.dsub.util.MediaRouteManager;
import github.daneren2005.dsub.util.SyncUtil;
import github.daneren2005.dsub.util.Util;
import github.daneren2005.dsub.view.CacheLocationPreference;
@@ -200,6 +201,18 @@ public class SettingsFragment extends PreferenceCompatFragment implements Shared
ActivityCompat.requestPermissions(context, new String[]{ Manifest.permission.ACCESS_COARSE_LOCATION }, SubsonicActivity.PERMISSIONS_REQUEST_LOCATION);
}
}
+ } else if(Constants.PREFERENCES_KEY_DLNA_CASTING_ENABLED.equals(key)) {
+ DownloadService downloadService = DownloadService.getInstance();
+ if(downloadService != null) {
+ MediaRouteManager mediaRouter = downloadService.getMediaRouter();
+
+ Boolean enabled = sharedPreferences.getBoolean(key, true);
+ if (enabled) {
+ mediaRouter.addDLNAProvider();
+ } else {
+ mediaRouter.removeDLNAProvider();
+ }
+ }
}
scheduleBackup();
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 0f6975ba..0ee16723 100644
--- a/app/src/main/java/github/daneren2005/dsub/provider/DLNARouteProvider.java
+++ b/app/src/main/java/github/daneren2005/dsub/provider/DLNARouteProvider.java
@@ -71,6 +71,7 @@ public class DLNARouteProvider extends MediaRouteProvider {
private List<String> removing = new ArrayList<String>();
private AndroidUpnpService dlnaService;
private ServiceConnection dlnaServiceConnection;
+ private RegistryListener registryListener;
private boolean searchOnConnect = false;
public DLNARouteProvider(Context context) {
@@ -84,7 +85,7 @@ public class DLNARouteProvider extends MediaRouteProvider {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
dlnaService = (AndroidUpnpService) service;
- dlnaService.getRegistry().addListener(new RegistryListener() {
+ dlnaService.getRegistry().addListener(registryListener = new RegistryListener() {
@Override
public void remoteDeviceDiscoveryStarted(Registry registry, RemoteDevice remoteDevice) {
@@ -142,6 +143,7 @@ public class DLNARouteProvider extends MediaRouteProvider {
@Override
public void onServiceDisconnected(ComponentName name) {
dlnaService = null;
+ registryListener = null;
}
};
@@ -290,6 +292,17 @@ public class DLNARouteProvider extends MediaRouteProvider {
}
}
+ public void destroy() {
+ if(dlnaService != null) {
+ dlnaService.getRegistry().removeListener(registryListener);
+ registryListener = null;
+ }
+
+ if(dlnaServiceConnection != null) {
+ getContext().getApplicationContext().unbindService(dlnaServiceConnection);
+ }
+ }
+
private class DLNARouteController extends RouteController {
private DLNADevice device;
diff --git a/app/src/main/java/github/daneren2005/dsub/service/AutoMediaBrowserService.java b/app/src/main/java/github/daneren2005/dsub/service/AutoMediaBrowserService.java
index ece8ee95..35f6d37a 100644
--- a/app/src/main/java/github/daneren2005/dsub/service/AutoMediaBrowserService.java
+++ b/app/src/main/java/github/daneren2005/dsub/service/AutoMediaBrowserService.java
@@ -21,6 +21,7 @@ package github.daneren2005.dsub.service;
import android.annotation.TargetApi;
import android.content.Intent;
import android.media.MediaDescription;
+import android.media.MediaMetadata;
import android.media.browse.MediaBrowser;
import android.os.Build;
import android.os.Bundle;
@@ -33,8 +34,11 @@ import java.util.ArrayList;
import java.util.List;
import github.daneren2005.dsub.R;
+import github.daneren2005.dsub.domain.Artist;
+import github.daneren2005.dsub.domain.Indexes;
import github.daneren2005.dsub.domain.MusicDirectory;
import github.daneren2005.dsub.domain.MusicDirectory.Entry;
+import github.daneren2005.dsub.domain.MusicFolder;
import github.daneren2005.dsub.domain.Playlist;
import github.daneren2005.dsub.domain.PodcastChannel;
import github.daneren2005.dsub.domain.PodcastEpisode;
@@ -58,6 +62,8 @@ public class AutoMediaBrowserService extends MediaBrowserService {
private static final String PODCAST_PREFIX = "po-";
private static final String ALBUM_TYPE_PREFIX = "ty-";
private static final String MUSIC_DIRECTORY_PREFIX = "md-";
+ private static final String MUSIC_FOLDER_PREFIX = "mf-";
+ private static final String MUSIC_DIRECTORY_CONTENTS_PREFIX = "mdc-";
private DownloadService downloadService;
private Handler handler = new Handler();
@@ -89,6 +95,12 @@ public class AutoMediaBrowserService extends MediaBrowserService {
getPlayOptions(result, id, Constants.INTENT_EXTRA_NAME_ID);
} else if(BROWSER_LIBRARY.equals(parentId)) {
getLibrary(result);
+ } else if(parentId.startsWith(MUSIC_FOLDER_PREFIX)) {
+ String id = parentId.substring(MUSIC_FOLDER_PREFIX.length());
+ getIndexes(result, id);
+ } else if(parentId.startsWith(MUSIC_DIRECTORY_CONTENTS_PREFIX)) {
+ String id = parentId.substring(MUSIC_DIRECTORY_CONTENTS_PREFIX.length());
+ getMusicDirectory(result, id);
} else if(BROWSER_PLAYLISTS.equals(parentId)) {
getPlaylists(result);
} else if(parentId.startsWith(PLAYLIST_PREFIX)) {
@@ -115,10 +127,10 @@ public class AutoMediaBrowserService extends MediaBrowserService {
.setMediaId(BROWSER_ALBUM_LISTS);
mediaItems.add(new MediaBrowser.MediaItem(albumLists.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE));
- /*MediaDescription.Builder library = new MediaDescription.Builder();
+ MediaDescription.Builder library = new MediaDescription.Builder();
library.setTitle(downloadService.getString(R.string.button_bar_browse))
.setMediaId(BROWSER_LIBRARY);
- mediaItems.add(new MediaBrowser.MediaItem(library.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE));*/
+ mediaItems.add(new MediaBrowser.MediaItem(library.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE));
MediaDescription.Builder playlists = new MediaDescription.Builder();
playlists.setTitle(downloadService.getString(R.string.button_bar_playlists))
@@ -218,8 +230,106 @@ public class AutoMediaBrowserService extends MediaBrowserService {
result.detach();
}
- private void getLibrary(Result<List<MediaBrowser.MediaItem>> result) {
+ private void getLibrary(final Result<List<MediaBrowser.MediaItem>> result) {
+ new SilentServiceTask<List<MusicFolder>>(downloadService) {
+ @Override
+ protected List<MusicFolder> doInBackground(MusicService musicService) throws Throwable {
+ return musicService.getMusicFolders(false, downloadService, null);
+ }
+
+ @Override
+ protected void done(List<MusicFolder> folders) {
+ List<MediaBrowser.MediaItem> mediaItems = new ArrayList<>();
+
+ for(MusicFolder folder: folders) {
+ MediaDescription description = new MediaDescription.Builder()
+ .setTitle(folder.getName())
+ .setMediaId(MUSIC_FOLDER_PREFIX + folder.getId())
+ .build();
+
+ mediaItems.add(new MediaBrowser.MediaItem(description, MediaBrowser.MediaItem.FLAG_BROWSABLE));
+ }
+
+ result.sendResult(mediaItems);
+ }
+ }.execute();
+
+ result.detach();
+ }
+ private void getIndexes(final Result<List<MediaBrowser.MediaItem>> result, final String musicFolderId) {
+ new SilentServiceTask<Indexes>(downloadService) {
+ @Override
+ protected Indexes doInBackground(MusicService musicService) throws Throwable {
+ return musicService.getIndexes(musicFolderId, false, downloadService, null);
+ }
+
+ @Override
+ protected void done(Indexes indexes) {
+ List<MediaBrowser.MediaItem> mediaItems = new ArrayList<>();
+
+ // music directories
+ for(Artist artist : indexes.getArtists()) {
+ MediaDescription description = new MediaDescription.Builder()
+ .setTitle(artist.getName())
+ .setMediaId(MUSIC_DIRECTORY_CONTENTS_PREFIX + artist.getId())
+ .build();
+
+ mediaItems.add(new MediaBrowser.MediaItem(description, MediaBrowser.MediaItem.FLAG_BROWSABLE));
+ }
+
+ // music files
+ for(Entry entry: indexes.getEntries()) {
+ MediaDescription description = new MediaDescription.Builder()
+ .setTitle(entry.getTitle())
+ .setMediaId(MUSIC_DIRECTORY_PREFIX + entry.getId())
+ .build();
+ mediaItems.add(new MediaBrowser.MediaItem(description, MediaBrowser.MediaItem.FLAG_BROWSABLE));
+ }
+
+ result.sendResult(mediaItems);
+ }
+ }.execute();
+
+ result.detach();
+ }
+
+ private void getMusicDirectory(final Result<List<MediaBrowser.MediaItem>> result, final String musicDirectoryId) {
+ new SilentServiceTask<MusicDirectory>(downloadService) {
+ @Override
+ protected MusicDirectory doInBackground(MusicService musicService) throws Throwable {
+ return musicService.getMusicDirectory(musicDirectoryId, "", false, downloadService, null);
+ }
+
+ @Override
+ protected void done(MusicDirectory directory) {
+ List<MediaBrowser.MediaItem> mediaItems = new ArrayList<>();
+
+ addPlayOptions(mediaItems, musicDirectoryId, Constants.INTENT_EXTRA_NAME_ID);
+
+ for(Entry entry : directory.getChildren()) {
+ MediaDescription description;
+ if (entry.isDirectory()) {
+ // browse deeper
+ description = new MediaDescription.Builder()
+ .setTitle(entry.getTitle())
+ .setMediaId(MUSIC_DIRECTORY_CONTENTS_PREFIX + entry.getId())
+ .build();
+ } else {
+ // playback options for a single item
+ description = new MediaDescription.Builder()
+ .setTitle(entry.getTitle())
+ .setMediaId(MUSIC_DIRECTORY_PREFIX + entry.getId())
+ .build();
+ }
+
+ mediaItems.add(new MediaBrowser.MediaItem(description, MediaBrowser.MediaItem.FLAG_BROWSABLE));
+ }
+ result.sendResult(mediaItems);
+ }
+ }.execute();
+
+ result.detach();
}
private void getPlaylists(final Result<List<MediaBrowser.MediaItem>> result) {
@@ -341,10 +451,8 @@ public class AutoMediaBrowserService extends MediaBrowserService {
result.detach();
}
-
- private void getPlayOptions(Result<List<MediaBrowser.MediaItem>> result, String id, String idConstant) {
- List<MediaBrowser.MediaItem> mediaItems = new ArrayList<>();
+ private void addPlayOptions(List<MediaBrowser.MediaItem> mediaItems, String id, String idConstant) {
Bundle playAllExtras = new Bundle();
playAllExtras.putString(idConstant, id);
@@ -373,6 +481,12 @@ public class AutoMediaBrowserService extends MediaBrowserService {
.setMediaId("playLast-" + id)
.setExtras(playLastExtras);
mediaItems.add(new MediaBrowser.MediaItem(playLast.build(), MediaBrowser.MediaItem.FLAG_PLAYABLE));
+ }
+
+ private void getPlayOptions(Result<List<MediaBrowser.MediaItem>> result, String id, String idConstant) {
+ List<MediaBrowser.MediaItem> mediaItems = new ArrayList<>();
+
+ addPlayOptions(mediaItems, id, idConstant);
result.sendResult(mediaItems);
}
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 6d85d128..b346f499 100644
--- a/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java
+++ b/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java
@@ -1665,6 +1665,9 @@ public class DownloadService extends Service {
return controller;
}
+ public MediaRouteManager getMediaRouter() {
+ return mediaRouter;
+ }
public MediaRouteSelector getRemoteSelector() {
return mediaRouter.getSelector();
}
diff --git a/app/src/main/java/github/daneren2005/dsub/service/RESTMusicService.java b/app/src/main/java/github/daneren2005/dsub/service/RESTMusicService.java
index 1aa1d212..657ac4a9 100644
--- a/app/src/main/java/github/daneren2005/dsub/service/RESTMusicService.java
+++ b/app/src/main/java/github/daneren2005/dsub/service/RESTMusicService.java
@@ -177,7 +177,17 @@ public class RESTMusicService implements MusicService {
@Override
public void startRescan(Context context, ProgressListener listener) throws Exception {
- Reader reader = getReader(context, listener, "startRescan");
+ String startMethod = ServerInfo.isMadsonic(context, getInstance(context)) ? "startRescan" : "startScan";
+ String refreshMethod = null;
+ if(ServerInfo.isMadsonic(context, getInstance(context))) {
+ startMethod = "startRescan";
+ refreshMethod = "scanstatus";
+ } else {
+ startMethod = "startScan";
+ refreshMethod = "getScanStatus";
+ }
+
+ Reader reader = getReader(context, listener, startMethod);
try {
new ErrorParser(context, getInstance(context)).parse(reader);
} finally {
@@ -187,7 +197,7 @@ public class RESTMusicService implements MusicService {
// Now check if still running
boolean done = false;
while(!done) {
- reader = getReader(context, null, "scanstatus");
+ reader = getReader(context, null, refreshMethod);
try {
boolean running = new ScanStatusParser(context, getInstance(context)).parse(reader, listener);
if(running) {
diff --git a/app/src/main/java/github/daneren2005/dsub/service/parser/ScanStatusParser.java b/app/src/main/java/github/daneren2005/dsub/service/parser/ScanStatusParser.java
index ffb3ba05..acd00661 100644
--- a/app/src/main/java/github/daneren2005/dsub/service/parser/ScanStatusParser.java
+++ b/app/src/main/java/github/daneren2005/dsub/service/parser/ScanStatusParser.java
@@ -21,6 +21,7 @@ import org.xmlpull.v1.XmlPullParser;
import java.io.Reader;
import github.daneren2005.dsub.R;
+import github.daneren2005.dsub.domain.ServerInfo;
import github.daneren2005.dsub.util.ProgressListener;
public class ScanStatusParser extends AbstractParser {
@@ -32,14 +33,23 @@ public class ScanStatusParser extends AbstractParser {
public boolean parse(Reader reader, ProgressListener progressListener) throws Exception {
init(reader);
- Boolean started = null;
+ String scanName, scanningName;
+ if(ServerInfo.isMadsonic(context, instance)) {
+ scanName = "status";
+ scanningName = "started";
+ } else {
+ scanName = "scanStatus";
+ scanningName = "scanning";
+ }
+
+ Boolean scanning = null;
int eventType;
do {
eventType = nextParseEvent();
if (eventType == XmlPullParser.START_TAG) {
String name = getElementName();
- if("status".equals(name)) {
- started = getBoolean("started");
+ if(scanName.equals(name)) {
+ scanning = getBoolean(scanningName);
String msg = context.getResources().getString(R.string.parser_scan_count, getInteger("count"));
progressListener.updateProgress(msg);
@@ -51,6 +61,6 @@ public class ScanStatusParser extends AbstractParser {
validate();
- return started != null && started;
+ return scanning != null && scanning;
}
} \ No newline at end of file
diff --git a/app/src/main/java/github/daneren2005/dsub/updates/Updater.java b/app/src/main/java/github/daneren2005/dsub/updates/Updater.java
index bc053b1e..2dabb624 100644
--- a/app/src/main/java/github/daneren2005/dsub/updates/Updater.java
+++ b/app/src/main/java/github/daneren2005/dsub/updates/Updater.java
@@ -48,6 +48,7 @@ public class Updater {
this.context = context;
List<Updater> updaters = new ArrayList<Updater>();
updaters.add(new UpdaterSongPress());
+ updaters.add(new UpdaterNoDLNA());
SharedPreferences prefs = Util.getPreferences(context);
int lastVersion = prefs.getInt(Constants.LAST_VERSION, 0);
diff --git a/app/src/main/java/github/daneren2005/dsub/updates/UpdaterNoDLNA.java b/app/src/main/java/github/daneren2005/dsub/updates/UpdaterNoDLNA.java
new file mode 100644
index 00000000..a060c4fd
--- /dev/null
+++ b/app/src/main/java/github/daneren2005/dsub/updates/UpdaterNoDLNA.java
@@ -0,0 +1,41 @@
+/*
+ This file is part of Subsonic.
+ Subsonic is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ Subsonic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License
+ along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
+ Copyright 2016 (C) Scott Jackson
+*/
+
+package github.daneren2005.dsub.updates;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Build;
+
+import github.daneren2005.dsub.util.Constants;
+import github.daneren2005.dsub.util.Util;
+
+public class UpdaterNoDLNA extends Updater {
+ public UpdaterNoDLNA() {
+ super(534);
+ TAG = this.getClass().getSimpleName();
+ }
+
+ @Override
+ public void update(Context context) {
+ SharedPreferences prefs = Util.getPreferences(context);
+
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ SharedPreferences.Editor editor = prefs.edit();
+ editor.putBoolean(Constants.PREFERENCES_KEY_DLNA_CASTING_ENABLED, false);
+ editor.commit();
+ }
+ }
+}
diff --git a/app/src/main/java/github/daneren2005/dsub/util/Constants.java b/app/src/main/java/github/daneren2005/dsub/util/Constants.java
index b62729ab..281c87d7 100644
--- a/app/src/main/java/github/daneren2005/dsub/util/Constants.java
+++ b/app/src/main/java/github/daneren2005/dsub/util/Constants.java
@@ -178,6 +178,7 @@ public final class Constants {
public static final String PREFERENCES_KEY_CAST_CACHE = "castCache";
public static final String PREFERENCES_KEY_PLAYBACK_SPEED = "playbackSpeed";
public static final String PREFERENCES_KEY_CUSTOM_PLAYBACK_SPEED = "customPlaybackSpeed";
+ public static final String PREFERENCES_KEY_DLNA_CASTING_ENABLED = "dlnaCastingEnabled";
public static final String OFFLINE_SCROBBLE_COUNT = "scrobbleCount";
public static final String OFFLINE_SCROBBLE_ID = "scrobbleID";
diff --git a/app/src/main/java/github/daneren2005/dsub/util/MediaRouteManager.java b/app/src/main/java/github/daneren2005/dsub/util/MediaRouteManager.java
index 9aa54c4b..73ec6aec 100644
--- a/app/src/main/java/github/daneren2005/dsub/util/MediaRouteManager.java
+++ b/app/src/main/java/github/daneren2005/dsub/util/MediaRouteManager.java
@@ -48,6 +48,7 @@ public class MediaRouteManager extends MediaRouter.Callback {
private MediaRouteSelector selector;
private List<MediaRouteProvider> providers = new ArrayList<MediaRouteProvider>();
private List<MediaRouteProvider> onlineProviders = new ArrayList<MediaRouteProvider>();
+ private DLNARouteProvider dlnaProvider;
static {
try {
@@ -159,10 +160,8 @@ public class MediaRouteManager extends MediaRouter.Callback {
addOnlineProviders();
}
- if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
- DLNARouteProvider dlnaProvider = new DLNARouteProvider(downloadService);
- router.addProvider(dlnaProvider);
- providers.add(dlnaProvider);
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && Util.getPreferences(downloadService).getBoolean(Constants.PREFERENCES_KEY_DLNA_CASTING_ENABLED, true)) {
+ addDLNAProvider();
}
}
public void buildSelector() {
@@ -178,4 +177,20 @@ public class MediaRouteManager extends MediaRouter.Callback {
}
selector = builder.build();
}
+
+ public void addDLNAProvider() {
+ if(dlnaProvider == null) {
+ dlnaProvider = new DLNARouteProvider(downloadService);
+ router.addProvider(dlnaProvider);
+ providers.add(dlnaProvider);
+ }
+ }
+ public void removeDLNAProvider() {
+ if(dlnaProvider != null) {
+ router.removeProvider(dlnaProvider);
+ providers.remove(dlnaProvider);
+ dlnaProvider.destroy();
+ dlnaProvider = null;
+ }
+ }
}
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 d666afb2..00bca833 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
@@ -433,7 +433,9 @@ public class RemoteControlClientLP extends RemoteControlClientBase {
}
private void noResults() {
-
+ // Keep getting emails from Google that not playing something with no results is bad
+ downloadService.clear();
+ downloadService.setShufflePlayEnabled(true);
}
private class EventCallback extends MediaSession.Callback {
diff --git a/app/src/main/res/menu/main.xml b/app/src/main/res/menu/main.xml
index 4b542668..b264d4fa 100644
--- a/app/src/main/res/menu/main.xml
+++ b/app/src/main/res/menu/main.xml
@@ -14,7 +14,7 @@
android:title="@string/menu.shuffle"
compat:showAsAction="ifRoom|withText"/>
- <group android:id="@+id/madsonic">
+ <group android:id="@+id/rescan_server">
<item
android:id="@+id/menu_rescan"
android:title="@string/menu.rescan"/>
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 094b782d..f384060a 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -31,7 +31,7 @@
<string name="button_bar.playlists">Playlists</string>
<string name="button_bar.now_playing">Lecture en cours</string>
<string name="button_bar.podcasts">Podcasts</string>
- <string name="button_bar.bookmarks">Favoris</string>
+ <string name="button_bar.bookmarks">Signets</string>
<string name="button_bar.shares">Partages</string>
<string name="button_bar.chat">Chat</string>
<string name="button_bar.admin">Admin</string>
@@ -204,11 +204,11 @@
<string name="updated_playlist_error">Échec de la mise à jour \&quot;%s\&quot;, réessayer plus tard.</string>
<string name="removed_playlist">Titre %1$s retiré de \&quot;%2$s\&quot;</string>
- <string name="bookmark.delete">Supprimer le favori</string>
- <string name="bookmark.delete_title">Supprimer le favori pour</string>
- <string name="bookmark.deleted">Favori pour \&quot;%s\&quot; supprimé</string>
- <string name="bookmark.deleted_error">Échec de la suppression du favori pour \&quot;%s\&quot;</string>
- <string name="bookmark.details_title">Détails du favori</string>
+ <string name="bookmark.delete">Supprimer le signet</string>
+ <string name="bookmark.delete_title">Supprimer le signet pour</string>
+ <string name="bookmark.deleted">Signet pour \&quot;%s\&quot; supprimé</string>
+ <string name="bookmark.deleted_error">Échec de la suppression du signet pour \&quot;%s\&quot;</string>
+ <string name="bookmark.details_title">Détails du signet</string>
<string name="bookmark.details">Titre : %1$s
\nPosition : %2$s
\nCréé le : %3$s
@@ -361,8 +361,8 @@
<string name="settings.hide_widget_summary">Cacher le widget après avoir quitté l\'application</string>
<string name="settings.podcasts_enabled">Podcasts autorisés</string>
<string name="settings.podcasts_enabled_summary">Afficher ou non l\'accès aux podcasts</string>
- <string name="settings.bookmarks_enabled">Favoris autorisés</string>
- <string name="settings.bookmarks_enabled_summary">Afficher ou non l\'accès aux favoris</string>
+ <string name="settings.bookmarks_enabled">Signets autorisés</string>
+ <string name="settings.bookmarks_enabled_summary">Afficher ou non l\'accès aux signets</string>
<string name="settings.shares_enabled">Partages autorisés</string>
<string name="settings.shares_enabled_summary">Afficher ou non l\'accès aux partages</string>
<string name="settings.sync_title">Sync</string>
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
index e9aadce7..118ccc80 100644
--- a/app/src/main/res/values/arrays.xml
+++ b/app/src/main/res/values/arrays.xml
@@ -74,6 +74,7 @@
<string-array name="maxBitrateValues">
<item>32</item>
+ <item>48</item>
<item>64</item>
<item>80</item>
<item>96</item>
@@ -88,6 +89,7 @@
<string-array name="maxBitrateNames">
<item>@string/settings.max_bitrate_32</item>
+ <item>@string/settings.max_bitrate_48</item>
<item>@string/settings.max_bitrate_64</item>
<item>@string/settings.max_bitrate_80</item>
<item>@string/settings.max_bitrate_96</item>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 0d9c2aa1..b54e4ff2 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -321,6 +321,7 @@
<string name="settings.max_bitrate_wifi">Max Audio bitrate - Wi-Fi</string>
<string name="settings.max_bitrate_mobile">Max Audio bitrate - Mobile</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>
@@ -384,7 +385,7 @@
<string name="settings.temp_loss_nothing">Do Nothing</string>
<string name="settings.keep_played_count_title">Keep played songs</string>
<string name="settings.keep_played_count_none">Remove all played songs</string>
- <string name="settings.keep_played_count_one">Keep last played songs</string>
+ <string name="settings.keep_played_count_one">Keep last played song</string>
<string name="settings.keep_played_count_two">Keep 2 played songs</string>
<string name="settings.keep_played_count_three">Keep 3 played songs</string>
<string name="settings.disconnect_pause_title">Pause on Disconnect</string>
@@ -488,6 +489,8 @@
<string name="settings.heads_up_notification_summary">Show playing notifications as Heads Up notifications (Android Lollipop+ only)</string>
<string name="settings.casting_cache">Cache While Casting</string>
<string name="settings.casting_cache_summary">Cache currently playing songs while casting</string>
+ <string name="settings.casting.dlna_casting_enabled">DLNA Enabled</string>
+ <string name="settings.casting.dlna_casting_enabled.summary">If you are having battery drain problems on Android 7.0 try turning this off</string>
<string name="shuffle.title">Shuffle By</string>
<string name="shuffle.startYear">Start Year:</string>
diff --git a/app/src/main/res/xml/changelog.xml b/app/src/main/res/xml/changelog.xml
index 34697168..11257b04 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.4" versioncode="193" releasedate="11/28/2016">
+ <change>Added toggle for DLNA casting to fix battery issues some users are having on Android 7.0+</change>
+ <change>Fix rotating screen in offline mode</change>
+ </release>
<release version="5.3.3" versioncode="191" releasedate="11/9/2016">
<change>Add support for Android 7's split screen UI</change>
<change>Fix for Android 7 not playing</change>
diff --git a/app/src/main/res/xml/settings_cast.xml b/app/src/main/res/xml/settings_cast.xml
index c23ae04d..78bafdd4 100644
--- a/app/src/main/res/xml/settings_cast.xml
+++ b/app/src/main/res/xml/settings_cast.xml
@@ -28,4 +28,14 @@
android:key="castCache"
android:defaultValue="false"/>
</PreferenceCategory>
+
+ <PreferenceCategory
+ android:title="@string/settings.other_title">
+
+ <CheckBoxPreference
+ android:title="@string/settings.casting.dlna_casting_enabled"
+ android:summary="@string/settings.casting.dlna_casting_enabled.summary"
+ android:key="dlnaCastingEnabled"
+ android:defaultValue="true"/>
+ </PreferenceCategory>
</PreferenceScreen> \ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 5b7e9efd..b3146795 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,7 +5,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.2.2'
+ classpath 'com.android.tools.build:gradle:2.3.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index f9d370e8..a58c8fc3 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Tue Aug 16 16:00:21 PDT 2016
+#Tue Mar 07 08:58:29 PST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
diff --git a/privacy.txt b/privacy.txt
new file mode 100644
index 00000000..336f0bc0
--- /dev/null
+++ b/privacy.txt
@@ -0,0 +1,23 @@
+Privacy Policy
+General
+
+DSub For Subsonic ("DSub") is developed & maintained by one developer. As the developer of DSub, I do care about and respect your privacy.
+
+This Privacy Policy ("Policy") aims to describe how information obtained from users is collected, used and disclosed.
+
+By using DSub, you agree that your personal information will be handled as described in this Policy.
+Information being collected
+
+DSub does not collect any personally identifiable information.
+
+DSub requests the permission 'READ_PHONE_STATE'. This permission is used by DSub solely to determine whether you're in a phone call/the phone is ringing, so that music playback can be paused. This permission also grants access to some personally identifiable information (your phone's IMEI number, your phone number and your network/carrier). This personally identifiable information is never accessed, used, stored or disclosed by DSub.
+DSub requests the permission 'RECORD_AUDIO'. This permission is used by DSub to provide Equalizer functionality and no audio is ever stored or transmitted by DSub.
+
+Changes to the Policy
+
+If the Policy changes, the modification date below will be updated. The Policy may change from time to time, so please be sure to check back periodically.
+
+Last modified: 08 March, 2017.
+Contact
+
+If you have any questions about the Policy, please contact me via dsub.android@gmail.com.com