diff --git a/dependencies.gradle b/dependencies.gradle index b0066103..4aa7f035 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -3,10 +3,10 @@ ext.versions = [ targetSdk : 22, compileSdk : 22, - buildTools : "25.0.2", + buildTools : "22.0.1", androidTools : "2.2.3", - androidSupport : "25.1.0", + androidSupport : "22.2.1", ] ext.gradlePlugins = [ @@ -14,5 +14,6 @@ ext.gradlePlugins = [ ] ext.androidSupport = [ - support : "com.android.support:support-v4:$versions.androidSupport" + support : "com.android.support:support-v4:$versions.androidSupport", + design : "com.android.support:design:$versions.androidSupport", ] \ No newline at end of file diff --git a/ultrasonic/build.gradle b/ultrasonic/build.gradle index 5287aeb9..17f7b5f1 100644 --- a/ultrasonic/build.gradle +++ b/ultrasonic/build.gradle @@ -22,4 +22,7 @@ dependencies { compile project(':menudrawer') compile project(':pulltorefresh') compile project(':library') + + compile androidSupport.support + compile androidSupport.design } diff --git a/ultrasonic/src/main/AndroidManifest.xml b/ultrasonic/src/main/AndroidManifest.xml index 7757a028..670846ad 100644 --- a/ultrasonic/src/main/AndroidManifest.xml +++ b/ultrasonic/src/main/AndroidManifest.xml @@ -15,10 +15,6 @@ - - + + newActivity) - { - startActivityForResultWithoutTransition(currentActivity, new Intent(currentActivity, newActivity)); - } - - protected void startActivityForResultWithoutTransition(Activity currentActivity, Intent intent) - { - startActivityForResult(intent, 0); - Util.disablePendingTransition(currentActivity); - } -} diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/ResultActivity.java b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/ResultActivity.java index 26a57c2a..4d956892 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/ResultActivity.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/ResultActivity.java @@ -2,6 +2,7 @@ package org.moire.ultrasonic.activity; import android.app.Activity; import android.content.Intent; +import android.support.v7.app.AppCompatActivity; import org.moire.ultrasonic.util.Constants; import org.moire.ultrasonic.util.Util; @@ -9,7 +10,7 @@ import org.moire.ultrasonic.util.Util; /** * Created by Joshua Bahnsen on 12/30/13. */ -public class ResultActivity extends Activity +public class ResultActivity extends AppCompatActivity { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/ServerSettingsActivity.java b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/ServerSettingsActivity.java new file mode 100644 index 00000000..8b36dce3 --- /dev/null +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/ServerSettingsActivity.java @@ -0,0 +1,63 @@ +package org.moire.ultrasonic.activity; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.ActionBar; +import android.support.v7.app.AppCompatActivity; +import android.view.MenuItem; + +import org.moire.ultrasonic.R; +import org.moire.ultrasonic.fragment.ServerSettingsFragment; +import org.moire.ultrasonic.util.Util; + +public class ServerSettingsActivity extends AppCompatActivity { + public static final String ARG_SERVER_ID = "argServerId"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + applyTheme(); + super.onCreate(savedInstanceState); + + final Bundle extras = getIntent().getExtras(); + if (!extras.containsKey(ARG_SERVER_ID)) { + finish(); + return; + } + + if (savedInstanceState == null) { + configureActionBar(); + + final int serverId = extras.getInt(ARG_SERVER_ID); + getFragmentManager().beginTransaction() + .add(android.R.id.content, ServerSettingsFragment.newInstance(serverId)) + .commit(); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } + + private void applyTheme() { + String theme = Util.getTheme(this); + + if ("dark".equalsIgnoreCase(theme) || "fullscreen".equalsIgnoreCase(theme)) { + setTheme(R.style.UltraSonicTheme); + } else if ("light".equalsIgnoreCase(theme) || "fullscreenlight".equalsIgnoreCase(theme)) { + setTheme(R.style.UltraSonicTheme_Light); + } + } + + private void configureActionBar() { + final ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setDisplayShowHomeEnabled(true); + actionBar.setDisplayHomeAsUpEnabled(true); + } + } +} diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SettingsActivity.java b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SettingsActivity.java index c3962cbf..d96436b9 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SettingsActivity.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SettingsActivity.java @@ -18,870 +18,26 @@ */ package org.moire.ultrasonic.activity; -import android.app.ActionBar; -import android.app.Dialog; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Build; import android.os.Bundle; -import android.preference.CheckBoxPreference; -import android.preference.EditTextPreference; -import android.preference.ListPreference; -import android.preference.Preference; -import android.preference.PreferenceCategory; -import android.preference.PreferenceManager; -import android.preference.PreferenceScreen; -import android.provider.SearchRecentSuggestions; -import android.text.InputType; -import android.util.Log; -import android.view.MenuItem; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.TextView; +import android.support.v7.app.ActionBar; import org.moire.ultrasonic.R; -import org.moire.ultrasonic.provider.SearchSuggestionProvider; -import org.moire.ultrasonic.service.DownloadService; -import org.moire.ultrasonic.service.DownloadServiceImpl; -import org.moire.ultrasonic.service.MusicService; -import org.moire.ultrasonic.service.MusicServiceFactory; -import org.moire.ultrasonic.util.Constants; -import org.moire.ultrasonic.util.ErrorDialog; -import org.moire.ultrasonic.util.FileUtil; -import org.moire.ultrasonic.util.ImageLoader; -import org.moire.ultrasonic.util.ModalBackgroundTask; -import org.moire.ultrasonic.util.TimeSpanPreference; -import org.moire.ultrasonic.util.Util; - -import net.simonvt.menudrawer.MenuDrawer; -import net.simonvt.menudrawer.Position; - -import java.io.File; -import java.net.URL; -import java.util.LinkedHashMap; -import java.util.Map; - -public class SettingsActivity extends PreferenceResultActivity implements SharedPreferences.OnSharedPreferenceChangeListener, OnClickListener -{ - private static final String TAG = SettingsActivity.class.getSimpleName(); - private final Map serverSettings = new LinkedHashMap(); - private boolean testingConnection; - private ListPreference theme; - private ListPreference videoPlayer; - private ListPreference maxBitrateWifi; - private ListPreference maxBitrateMobile; - private ListPreference cacheSize; - private EditTextPreference cacheLocation; - private ListPreference preloadCount; - private ListPreference bufferLength; - private ListPreference incrementTime; - private ListPreference networkTimeout; - private ListPreference maxAlbums; - private ListPreference maxSongs; - private ListPreference maxArtists; - private ListPreference defaultAlbums; - private ListPreference defaultSongs; - private ListPreference defaultArtists; - private ListPreference chatRefreshInterval; - private ListPreference directoryCacheTime; - private CheckBoxPreference mediaButtonsEnabled; - private CheckBoxPreference lockScreenEnabled; - private CheckBoxPreference sendBluetoothNotifications; - private CheckBoxPreference sendBluetoothAlbumArt; - private ListPreference viewRefresh; - private ListPreference imageLoaderConcurrency; - private EditTextPreference sharingDefaultDescription; - private EditTextPreference sharingDefaultGreeting; - private TimeSpanPreference sharingDefaultExpiration; - private int maxServerCount = 10; - private int minServerCount; - - private static final String STATE_MENUDRAWER = "org.moire.ultrasonic.menuDrawer"; - private static final String STATE_ACTIVE_VIEW_ID = "org.moire.ultrasonic.activeViewId"; - private static final String STATE_ACTIVE_POSITION = "org.moire.ultrasonic.activePosition"; - - public MenuDrawer menuDrawer; - private int activePosition = 1; - private int menuActiveViewId; - private int activeServers; - View chatMenuItem; - View bookmarksMenuItem; - View sharesMenuItem; - PreferenceCategory serversCategory; - Preference addServerPreference; - SharedPreferences settings; +import org.moire.ultrasonic.fragment.SettingsFragment; +public class SettingsActivity extends SubsonicTabActivity { @Override public void onCreate(Bundle savedInstanceState) { - applyTheme(); super.onCreate(savedInstanceState); - addPreferencesFromResource(R.xml.settings); + getFragmentManager().beginTransaction() + .replace(android.R.id.content, new SettingsFragment()) + .commit(); - if (savedInstanceState != null) - { - activePosition = savedInstanceState.getInt(STATE_ACTIVE_POSITION); - menuActiveViewId = savedInstanceState.getInt(STATE_ACTIVE_VIEW_ID); - } - - menuDrawer = MenuDrawer.attach(this, MenuDrawer.Type.BEHIND, Position.LEFT, MenuDrawer.MENU_DRAG_WINDOW); - menuDrawer.setMenuView(R.layout.menu_main); - - chatMenuItem = findViewById(R.id.menu_chat); - bookmarksMenuItem = findViewById(R.id.menu_bookmarks); - sharesMenuItem = findViewById(R.id.menu_shares); - - findViewById(R.id.menu_home).setOnClickListener(this); - findViewById(R.id.menu_browse).setOnClickListener(this); - findViewById(R.id.menu_search).setOnClickListener(this); - findViewById(R.id.menu_playlists).setOnClickListener(this); - sharesMenuItem.setOnClickListener(this); - chatMenuItem.setOnClickListener(this); - bookmarksMenuItem.setOnClickListener(this); - findViewById(R.id.menu_now_playing).setOnClickListener(this); - findViewById(R.id.menu_settings).setOnClickListener(this); - findViewById(R.id.menu_about).setOnClickListener(this); - findViewById(R.id.menu_exit).setOnClickListener(this); - - ActionBar actionBar = getActionBar(); - - if (actionBar != null) - { - actionBar.setDisplayHomeAsUpEnabled(true); - } - - View browseMenuItem = findViewById(R.id.menu_settings); - menuDrawer.setActiveView(browseMenuItem); - - TextView activeView = (TextView) findViewById(menuActiveViewId); - - if (activeView != null) - { - menuDrawer.setActiveView(activeView); - } - - theme = (ListPreference) findPreference(Constants.PREFERENCES_KEY_THEME); - videoPlayer = (ListPreference) findPreference(Constants.PREFERENCES_KEY_VIDEO_PLAYER); - maxBitrateWifi = (ListPreference) findPreference(Constants.PREFERENCES_KEY_MAX_BITRATE_WIFI); - maxBitrateMobile = (ListPreference) findPreference(Constants.PREFERENCES_KEY_MAX_BITRATE_MOBILE); - cacheSize = (ListPreference) findPreference(Constants.PREFERENCES_KEY_CACHE_SIZE); - cacheLocation = (EditTextPreference) findPreference(Constants.PREFERENCES_KEY_CACHE_LOCATION); - preloadCount = (ListPreference) findPreference(Constants.PREFERENCES_KEY_PRELOAD_COUNT); - bufferLength = (ListPreference) findPreference(Constants.PREFERENCES_KEY_BUFFER_LENGTH); - incrementTime = (ListPreference) findPreference(Constants.PREFERENCES_KEY_INCREMENT_TIME); - networkTimeout = (ListPreference) findPreference(Constants.PREFERENCES_KEY_NETWORK_TIMEOUT); - maxAlbums = (ListPreference) findPreference(Constants.PREFERENCES_KEY_MAX_ALBUMS); - maxSongs = (ListPreference) findPreference(Constants.PREFERENCES_KEY_MAX_SONGS); - maxArtists = (ListPreference) findPreference(Constants.PREFERENCES_KEY_MAX_ARTISTS); - defaultArtists = (ListPreference) findPreference(Constants.PREFERENCES_KEY_DEFAULT_ARTISTS); - defaultSongs = (ListPreference) findPreference(Constants.PREFERENCES_KEY_DEFAULT_SONGS); - defaultAlbums = (ListPreference) findPreference(Constants.PREFERENCES_KEY_DEFAULT_ALBUMS); - chatRefreshInterval = (ListPreference) findPreference(Constants.PREFERENCES_KEY_CHAT_REFRESH_INTERVAL); - directoryCacheTime = (ListPreference) findPreference(Constants.PREFERENCES_KEY_DIRECTORY_CACHE_TIME); - mediaButtonsEnabled = (CheckBoxPreference) findPreference(Constants.PREFERENCES_KEY_MEDIA_BUTTONS); - lockScreenEnabled = (CheckBoxPreference) findPreference(Constants.PREFERENCES_KEY_SHOW_LOCK_SCREEN_CONTROLS); - sendBluetoothAlbumArt = (CheckBoxPreference) findPreference(Constants.PREFERENCES_KEY_SEND_BLUETOOTH_ALBUM_ART); - sendBluetoothNotifications = (CheckBoxPreference) findPreference(Constants.PREFERENCES_KEY_SEND_BLUETOOTH_NOTIFICATIONS); - viewRefresh = (ListPreference) findPreference(Constants.PREFERENCES_KEY_VIEW_REFRESH); - imageLoaderConcurrency = (ListPreference) findPreference(Constants.PREFERENCES_KEY_IMAGE_LOADER_CONCURRENCY); - sharingDefaultDescription = (EditTextPreference) findPreference(Constants.PREFERENCES_KEY_DEFAULT_SHARE_DESCRIPTION); - sharingDefaultGreeting = (EditTextPreference) findPreference(Constants.PREFERENCES_KEY_DEFAULT_SHARE_GREETING); - sharingDefaultExpiration = (TimeSpanPreference) findPreference(Constants.PREFERENCES_KEY_DEFAULT_SHARE_EXPIRATION); - - sharingDefaultGreeting.setText(Util.getShareGreeting(this)); - - Preference clearSearchPreference = findPreference(Constants.PREFERENCES_KEY_CLEAR_SEARCH_HISTORY); - - if (clearSearchPreference != null) - { - clearSearchPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() - { - @Override - public boolean onPreferenceClick(Preference preference) - { - SearchRecentSuggestions suggestions = new SearchRecentSuggestions(SettingsActivity.this, SearchSuggestionProvider.AUTHORITY, SearchSuggestionProvider.MODE); - suggestions.clearHistory(); - Util.toast(SettingsActivity.this, R.string.settings_search_history_cleared); - return false; - } - }); - } - - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) - { - PreferenceCategory playbackControlSettings = (PreferenceCategory) findPreference(Constants.PREFERENCES_KEY_PLAYBACK_CONTROL_SETTINGS); - CheckBoxPreference gaplessPlaybackEnabled = (CheckBoxPreference) findPreference(Constants.PREFERENCES_KEY_GAPLESS_PLAYBACK); - - if (gaplessPlaybackEnabled != null) - { - gaplessPlaybackEnabled.setChecked(false); - gaplessPlaybackEnabled.setEnabled(false); - - if (playbackControlSettings != null) - { - playbackControlSettings.removePreference(gaplessPlaybackEnabled); - } - } - } - - settings = PreferenceManager.getDefaultSharedPreferences(this); - activeServers = settings.getInt(Constants.PREFERENCES_KEY_ACTIVE_SERVERS, 0); - - serversCategory = (PreferenceCategory) findPreference(Constants.PREFERENCES_KEY_SERVERS_KEY); - - addServerPreference = new Preference(this); - addServerPreference.setKey(Constants.PREFERENCES_KEY_ADD_SERVER); - addServerPreference.setPersistent(false); - addServerPreference.setTitle(getResources().getString(R.string.settings_server_add_server)); - addServerPreference.setEnabled(activeServers < maxServerCount); - - serversCategory.addPreference(addServerPreference); - - for (int i = 1; i <= activeServers; i++) - { - final int instanceValue = i; - - serversCategory.addPreference(addServer(i)); - - Preference testConnectionPreference = findPreference(Constants.PREFERENCES_KEY_TEST_CONNECTION + i); - - if (testConnectionPreference != null) - { - testConnectionPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() - { - @Override - public boolean onPreferenceClick(Preference preference) - { - testConnection(instanceValue); - return false; - } - }); - } - - String instance = String.valueOf(i); - serverSettings.put(instance, new ServerSettings(instance)); - } - - addServerPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() - { - @Override - public boolean onPreferenceClick(Preference preference) - { - if (activeServers == maxServerCount) - { - return false; - } - - activeServers++; - - SharedPreferences.Editor prefEditor = settings.edit(); - prefEditor.putInt(Constants.PREFERENCES_KEY_ACTIVE_SERVERS, activeServers); - prefEditor.commit(); - - Preference addServerPreference = findPreference(Constants.PREFERENCES_KEY_ADD_SERVER); - - if (addServerPreference != null) - { - serversCategory.removePreference(addServerPreference); - } - - serversCategory.addPreference(addServer(activeServers)); - - if (addServerPreference != null) - { - serversCategory.addPreference(addServerPreference); - addServerPreference.setEnabled(activeServers < maxServerCount); - } - - String instance = String.valueOf(activeServers); - serverSettings.put(instance, new ServerSettings(instance)); - - applyTheme(); - - return true; - } - }); - - SharedPreferences preferences = Util.getPreferences(this); - preferences.registerOnSharedPreferenceChangeListener(this); + final ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setSubtitle(R.string.menu_settings); } - - update(); - } - - @Override - protected void onPostCreate(Bundle bundle) - { - super.onPostCreate(bundle); - - int visibility = Util.isOffline(this) ? View.GONE : View.VISIBLE; - chatMenuItem.setVisibility(visibility); - bookmarksMenuItem.setVisibility(visibility); - sharesMenuItem.setVisibility(visibility); - } - - private PreferenceScreen addServer(final int instance) - { - final PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(this); - - if (screen != null) - { - screen.setTitle(R.string.settings_server_unused); - screen.setKey(Constants.PREFERENCES_KEY_SERVER + instance); - } - - final EditTextPreference serverNamePreference = new EditTextPreference(this); - serverNamePreference.setKey(Constants.PREFERENCES_KEY_SERVER_NAME + instance); - serverNamePreference.setDefaultValue(getResources().getString(R.string.settings_server_unused)); - serverNamePreference.setTitle(R.string.settings_server_name); - - if (serverNamePreference.getText() == null) - { - serverNamePreference.setText(getResources().getString(R.string.settings_server_unused)); - } - - serverNamePreference.setSummary(serverNamePreference.getText()); - - final EditTextPreference serverUrlPreference = new EditTextPreference(this); - serverUrlPreference.setKey(Constants.PREFERENCES_KEY_SERVER_URL + instance); - serverUrlPreference.getEditText().setInputType(InputType.TYPE_TEXT_VARIATION_URI); - serverUrlPreference.setDefaultValue("http://yourhost"); - serverUrlPreference.setTitle(R.string.settings_server_address); - - if (serverUrlPreference.getText() == null) - { - serverUrlPreference.setText("http://yourhost"); - } - - serverUrlPreference.setSummary(serverUrlPreference.getText()); - - if (screen != null) - { - screen.setSummary(serverUrlPreference.getText()); - } - - final EditTextPreference serverUsernamePreference = new EditTextPreference(this); - serverUsernamePreference.setKey(Constants.PREFERENCES_KEY_USERNAME + instance); - serverUsernamePreference.setTitle(R.string.settings_server_username); - - final EditTextPreference serverPasswordPreference = new EditTextPreference(this); - serverPasswordPreference.setKey(Constants.PREFERENCES_KEY_PASSWORD + instance); - serverPasswordPreference.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); - serverPasswordPreference.setSummary("***"); - serverPasswordPreference.setTitle(R.string.settings_server_password); - - final CheckBoxPreference serverEnabledPreference = new CheckBoxPreference(this); - serverEnabledPreference.setDefaultValue(true); - serverEnabledPreference.setKey(Constants.PREFERENCES_KEY_SERVER_ENABLED + instance); - serverEnabledPreference.setTitle(R.string.equalizer_enabled); - - final CheckBoxPreference jukeboxEnabledPreference = new CheckBoxPreference(this); - jukeboxEnabledPreference.setDefaultValue(false); - jukeboxEnabledPreference.setKey(Constants.PREFERENCES_KEY_JUKEBOX_BY_DEFAULT + instance); - jukeboxEnabledPreference.setTitle(R.string.jukebox_is_default); - - Preference serverRemoveServerPreference = new Preference(this); - serverRemoveServerPreference.setKey(Constants.PREFERENCES_KEY_REMOVE_SERVER + instance); - serverRemoveServerPreference.setPersistent(false); - serverRemoveServerPreference.setTitle(R.string.settings_server_remove_server); - - serverRemoveServerPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() - { - @Override - public boolean onPreferenceClick(Preference preference) - { - - if (activeServers == minServerCount) - { - return false; - } - - // Reset values to null so when we ask for them again they are new - serverNamePreference.setText(null); - serverUrlPreference.setText(null); - serverUsernamePreference.setText(null); - serverPasswordPreference.setText(null); - serverEnabledPreference.setChecked(true); - jukeboxEnabledPreference.setChecked(false); - - if (instance < activeServers) - { - - int activeServer = Util.getActiveServer(SettingsActivity.this); - for (int i = instance; i <= activeServers; i++) - { - Util.removeInstanceName(SettingsActivity.this, i, activeServer); - } - } - - activeServers--; - - if (screen != null) - { - serversCategory.removePreference(screen); - Dialog dialog = screen.getDialog(); - - if (dialog != null) - { - dialog.dismiss(); - } - } - - SharedPreferences.Editor prefEditor = settings.edit(); - prefEditor.putInt(Constants.PREFERENCES_KEY_ACTIVE_SERVERS, activeServers); - prefEditor.commit(); - - addServerPreference.setEnabled(activeServers < maxServerCount); - - return true; - } - }); - - Preference serverTestConnectionPreference = new Preference(this); - serverTestConnectionPreference.setKey(Constants.PREFERENCES_KEY_TEST_CONNECTION + instance); - serverTestConnectionPreference.setPersistent(false); - serverTestConnectionPreference.setTitle(R.string.settings_test_connection_title); - - serverTestConnectionPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() - { - @Override - public boolean onPreferenceClick(Preference preference) - { - testConnection(instance); - return false; - } - }); - - if (screen != null) - { - screen.addPreference(serverNamePreference); - screen.addPreference(serverUrlPreference); - screen.addPreference(serverUsernamePreference); - screen.addPreference(serverPasswordPreference); - screen.addPreference(serverEnabledPreference); - screen.addPreference(jukeboxEnabledPreference); - screen.addPreference(serverRemoveServerPreference); - screen.addPreference(serverTestConnectionPreference); - } - - return screen; - } - - private void applyTheme() - { - String theme = Util.getTheme(this); - - // Support the old fullscreen themes as well, for upgrade purposes - if ("dark".equalsIgnoreCase(theme) || "fullscreen".equalsIgnoreCase(theme)) - { - setTheme(R.style.UltraSonicTheme); - } - else if ("light".equalsIgnoreCase(theme) || "fullscreenlight".equalsIgnoreCase(theme)) - { - setTheme(R.style.UltraSonicTheme_Light); - } - } - - @Override - protected void onDestroy() - { - super.onDestroy(); - - SharedPreferences prefs = Util.getPreferences(this); - prefs.unregisterOnSharedPreferenceChangeListener(this); - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) - { - Log.d(TAG, "Preference changed: " + key); - update(); - - if (Constants.PREFERENCES_KEY_HIDE_MEDIA.equals(key)) - { - setHideMedia(sharedPreferences.getBoolean(key, false)); - } - else if (Constants.PREFERENCES_KEY_MEDIA_BUTTONS.equals(key)) - { - setMediaButtonsEnabled(sharedPreferences.getBoolean(key, true)); - } - else if (Constants.PREFERENCES_KEY_CACHE_LOCATION.equals(key)) - { - setCacheLocation(sharedPreferences.getString(key, "")); - } - else if (Constants.PREFERENCES_KEY_SEND_BLUETOOTH_NOTIFICATIONS.equals(key)) - { - setBluetoothPreferences(sharedPreferences.getBoolean(key, true)); - } - else if (Constants.PREFERENCES_KEY_IMAGE_LOADER_CONCURRENCY.equals(key)) - { - setImageLoaderConcurrency(Integer.parseInt(sharedPreferences.getString(key, "5"))); - } - } - - private void update() - { - if (testingConnection) - { - return; - } - - theme.setSummary(theme.getEntry()); - videoPlayer.setSummary(videoPlayer.getEntry()); - maxBitrateWifi.setSummary(maxBitrateWifi.getEntry()); - maxBitrateMobile.setSummary(maxBitrateMobile.getEntry()); - cacheSize.setSummary(cacheSize.getEntry()); - cacheLocation.setSummary(cacheLocation.getText()); - preloadCount.setSummary(preloadCount.getEntry()); - bufferLength.setSummary(bufferLength.getEntry()); - incrementTime.setSummary(incrementTime.getEntry()); - networkTimeout.setSummary(networkTimeout.getEntry()); - maxAlbums.setSummary(maxAlbums.getEntry()); - maxArtists.setSummary(maxArtists.getEntry()); - maxSongs.setSummary(maxSongs.getEntry()); - defaultAlbums.setSummary(defaultAlbums.getEntry()); - defaultArtists.setSummary(defaultArtists.getEntry()); - defaultSongs.setSummary(defaultSongs.getEntry()); - chatRefreshInterval.setSummary(chatRefreshInterval.getEntry()); - directoryCacheTime.setSummary(directoryCacheTime.getEntry()); - viewRefresh.setSummary(viewRefresh.getEntry()); - imageLoaderConcurrency.setSummary(imageLoaderConcurrency.getEntry()); - sharingDefaultExpiration.setSummary(sharingDefaultExpiration.getText()); - sharingDefaultDescription.setSummary(sharingDefaultDescription.getText()); - sharingDefaultGreeting.setSummary(sharingDefaultGreeting.getText()); - - if (!mediaButtonsEnabled.isChecked()) - { - lockScreenEnabled.setChecked(false); - lockScreenEnabled.setEnabled(false); - } - - if (!sendBluetoothNotifications.isChecked()) - { - sendBluetoothAlbumArt.setChecked(false); - sendBluetoothAlbumArt.setEnabled(false); - } - - for (ServerSettings ss : serverSettings.values()) - { - ss.update(); - } - } - - private static void setImageLoaderConcurrency(int concurrency) - { - SubsonicTabActivity instance = SubsonicTabActivity.getInstance(); - - if (instance != null) - { - ImageLoader imageLoader = instance.getImageLoader(); - - if (imageLoader != null) - { - imageLoader.stopImageLoader(); - imageLoader.setConcurrency(concurrency); - } - } - } - - private void setHideMedia(boolean hide) - { - File nomediaDir = new File(FileUtil.getUltraSonicDirectory(), ".nomedia"); - if (hide && !nomediaDir.exists()) - { - if (!nomediaDir.mkdir()) - { - Log.w(TAG, "Failed to create " + nomediaDir); - } - } - else if (nomediaDir.exists()) - { - if (!nomediaDir.delete()) - { - Log.w(TAG, "Failed to delete " + nomediaDir); - } - } - Util.toast(this, R.string.settings_hide_media_toast, false); - } - - private void setMediaButtonsEnabled(boolean enabled) - { - if (enabled) - { - lockScreenEnabled.setEnabled(true); - Util.registerMediaButtonEventReceiver(this); - } - else - { - lockScreenEnabled.setEnabled(false); - Util.unregisterMediaButtonEventReceiver(this); - } - } - - private void setBluetoothPreferences(boolean enabled) - { - if (enabled) - { - sendBluetoothAlbumArt.setEnabled(true); - } - else - { - sendBluetoothAlbumArt.setEnabled(false); - } - } - - private void setCacheLocation(String path) - { - File dir = new File(path); - - if (!FileUtil.ensureDirectoryExistsAndIsReadWritable(dir)) - { - Util.toast(this, R.string.settings_cache_location_error, false); - - // Reset it to the default. - String defaultPath = FileUtil.getDefaultMusicDirectory().getPath(); - if (!defaultPath.equals(path)) - { - SharedPreferences prefs = Util.getPreferences(this); - SharedPreferences.Editor editor = prefs.edit(); - editor.putString(Constants.PREFERENCES_KEY_CACHE_LOCATION, defaultPath); - editor.commit(); - cacheLocation.setSummary(defaultPath); - cacheLocation.setText(defaultPath); - } - - // Clear download queue. - DownloadService downloadService = DownloadServiceImpl.getInstance(); - downloadService.clear(); - } - } - - private void testConnection(final int instance) - { - ModalBackgroundTask task = new ModalBackgroundTask(this, false) - { - private int previousInstance; - - @Override - protected Boolean doInBackground() throws Throwable - { - updateProgress(R.string.settings_testing_connection); - - previousInstance = Util.getActiveServer(SettingsActivity.this); - testingConnection = true; - Util.setActiveServer(SettingsActivity.this, instance); - try - { - MusicService musicService = MusicServiceFactory.getMusicService(SettingsActivity.this); - musicService.ping(SettingsActivity.this, this); - return musicService.isLicenseValid(SettingsActivity.this, null); - } - finally - { - Util.setActiveServer(SettingsActivity.this, previousInstance); - testingConnection = false; - } - } - - @Override - protected void done(Boolean licenseValid) - { - if (licenseValid) - { - Util.toast(SettingsActivity.this, R.string.settings_testing_ok); - } - else - { - Util.toast(SettingsActivity.this, R.string.settings_testing_unlicensed); - } - } - - @Override - protected void cancel() - { - super.cancel(); - Util.setActiveServer(SettingsActivity.this, previousInstance); - } - - @Override - protected void error(Throwable error) - { - Log.w(TAG, error.toString(), error); - new ErrorDialog(SettingsActivity.this, String.format("%s %s", getResources().getString(R.string.settings_connection_failure), getErrorMessage(error)), false); - } - }; - task.execute(); - } - - private class ServerSettings - { - private EditTextPreference serverName; - private EditTextPreference serverUrl; - private EditTextPreference username; - private PreferenceScreen screen; - - private ServerSettings(String instance) - { - - screen = (PreferenceScreen) findPreference("server" + instance); - serverName = (EditTextPreference) findPreference(Constants.PREFERENCES_KEY_SERVER_NAME + instance); - serverUrl = (EditTextPreference) findPreference(Constants.PREFERENCES_KEY_SERVER_URL + instance); - username = (EditTextPreference) findPreference(Constants.PREFERENCES_KEY_USERNAME + instance); - - serverUrl.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() - { - @Override - public boolean onPreferenceChange(Preference preference, Object value) - { - try - { - String url = (String) value; - new URL(url); - if (!url.equals(url.trim()) || url.contains("@")) - { - throw new Exception(); - } - } - catch (Exception x) - { - new ErrorDialog(SettingsActivity.this, R.string.settings_invalid_url, false); - return false; - } - return true; - } - }); - - username.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() - { - @Override - public boolean onPreferenceChange(Preference preference, Object value) - { - String username = (String) value; - if (username == null || !username.equals(username.trim())) - { - new ErrorDialog(SettingsActivity.this, R.string.settings_invalid_username, false); - return false; - } - return true; - } - }); - } - - public void update() - { - serverName.setSummary(serverName.getText()); - serverUrl.setSummary(serverUrl.getText()); - username.setSummary(username.getText()); - screen.setSummary(serverUrl.getText()); - screen.setTitle(serverName.getText()); - } - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) - { - switch (item.getItemId()) - { - case android.R.id.home: - menuDrawer.toggleMenu(); - return true; - } - - return super.onOptionsItemSelected(item); - } - - @Override - protected void onRestoreInstanceState(Bundle inState) - { - super.onRestoreInstanceState(inState); - menuDrawer.restoreState(inState.getParcelable(STATE_MENUDRAWER)); - } - - @Override - protected void onSaveInstanceState(Bundle outState) - { - super.onSaveInstanceState(outState); - outState.putParcelable(STATE_MENUDRAWER, menuDrawer.saveState()); - outState.putInt(STATE_ACTIVE_VIEW_ID, menuActiveViewId); - outState.putInt(STATE_ACTIVE_POSITION, activePosition); - } - - @Override - public void onBackPressed() - { - final int drawerState = menuDrawer.getDrawerState(); - - if (drawerState == MenuDrawer.STATE_OPEN || drawerState == MenuDrawer.STATE_OPENING) - { - menuDrawer.closeMenu(true); - return; - } - - super.onBackPressed(); - } - - @Override - public void onClick(View v) - { - menuActiveViewId = v.getId(); - menuDrawer.setActiveView(v); - - Intent intent; - - switch (menuActiveViewId) - { - case R.id.menu_home: - intent = new Intent(this, MainActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - startActivityForResultWithoutTransition(this, intent); - break; - case R.id.menu_browse: - intent = new Intent(this, SelectArtistActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - startActivityForResultWithoutTransition(this, intent); - break; - case R.id.menu_search: - intent = new Intent(this, SearchActivity.class); - intent.putExtra(Constants.INTENT_EXTRA_REQUEST_SEARCH, true); - startActivityForResultWithoutTransition(this, intent); - break; - case R.id.menu_playlists: - intent = new Intent(this, SelectPlaylistActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - startActivityForResultWithoutTransition(this, intent); - break; - case R.id.menu_shares: - intent = new Intent(this, ShareActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - startActivityForResultWithoutTransition(this, intent); - break; - case R.id.menu_chat: - startActivityForResultWithoutTransition(this, ChatActivity.class); - break; - case R.id.menu_bookmarks: - startActivityForResultWithoutTransition(this, BookmarkActivity.class); - break; - case R.id.menu_now_playing: - startActivityForResultWithoutTransition(this, DownloadActivity.class); - break; - case R.id.menu_settings: - startActivityForResultWithoutTransition(this, SettingsActivity.class); - break; - case R.id.menu_about: - startActivityForResultWithoutTransition(this, HelpActivity.class); - break; - case R.id.menu_exit: - intent = new Intent(this, MainActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - intent.putExtra(Constants.INTENT_EXTRA_NAME_EXIT, true); - startActivityForResultWithoutTransition(this, intent); - break; - } - - menuDrawer.closeMenu(true); } } \ No newline at end of file diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SubsonicTabActivity.java b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SubsonicTabActivity.java index 3756c76a..3189aae2 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SubsonicTabActivity.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SubsonicTabActivity.java @@ -19,7 +19,6 @@ package org.moire.ultrasonic.activity; import android.annotation.SuppressLint; -import android.app.ActionBar; import android.app.AlertDialog; import android.app.Dialog; import android.app.Notification; @@ -36,6 +35,7 @@ import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Handler; +import android.support.v7.app.ActionBar; import android.util.Log; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -52,6 +52,9 @@ import android.widget.ImageView; import android.widget.RemoteViews; import android.widget.TextView; +import net.simonvt.menudrawer.MenuDrawer; +import net.simonvt.menudrawer.Position; + import org.moire.ultrasonic.R; import org.moire.ultrasonic.domain.MusicDirectory; import org.moire.ultrasonic.domain.MusicDirectory.Entry; @@ -75,9 +78,6 @@ import org.moire.ultrasonic.util.TimeSpanPicker; import org.moire.ultrasonic.util.Util; import org.moire.ultrasonic.util.VideoPlayerType; -import net.simonvt.menudrawer.MenuDrawer; -import net.simonvt.menudrawer.Position; - import java.io.File; import java.io.PrintWriter; import java.util.ArrayList; @@ -1276,7 +1276,7 @@ public class SubsonicTabActivity extends ResultActivity implements OnClickListen protected void setActionBarDisplayHomeAsUp(boolean enabled) { - ActionBar actionBar = getActionBar(); + ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { @@ -1286,7 +1286,7 @@ public class SubsonicTabActivity extends ResultActivity implements OnClickListen protected void setActionBarTitle(CharSequence title) { - ActionBar actionBar = getActionBar(); + ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { @@ -1296,7 +1296,7 @@ public class SubsonicTabActivity extends ResultActivity implements OnClickListen protected void setActionBarTitle(int id) { - ActionBar actionBar = getActionBar(); + ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { @@ -1306,7 +1306,7 @@ public class SubsonicTabActivity extends ResultActivity implements OnClickListen protected CharSequence getActionBarTitle() { - ActionBar actionBar = getActionBar(); + ActionBar actionBar = getSupportActionBar(); CharSequence title = null; if (actionBar != null) @@ -1319,7 +1319,7 @@ public class SubsonicTabActivity extends ResultActivity implements OnClickListen protected void setActionBarSubtitle(CharSequence title) { - ActionBar actionBar = getActionBar(); + ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { @@ -1329,7 +1329,7 @@ public class SubsonicTabActivity extends ResultActivity implements OnClickListen protected void setActionBarSubtitle(int id) { - ActionBar actionBar = getActionBar(); + ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { @@ -1339,7 +1339,7 @@ public class SubsonicTabActivity extends ResultActivity implements OnClickListen protected CharSequence getActionBarSubtitle() { - ActionBar actionBar = getActionBar(); + ActionBar actionBar = getSupportActionBar(); CharSequence subtitle = null; if (actionBar != null) diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/ServerSettingsFragment.java b/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/ServerSettingsFragment.java new file mode 100644 index 00000000..6c8e4d9e --- /dev/null +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/ServerSettingsFragment.java @@ -0,0 +1,282 @@ +package org.moire.ultrasonic.fragment; + +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.CheckBoxPreference; +import android.preference.EditTextPreference; +import android.preference.Preference; +import android.preference.PreferenceFragment; +import android.preference.PreferenceManager; +import android.support.annotation.Nullable; +import android.util.Log; +import android.view.View; + +import org.moire.ultrasonic.R; +import org.moire.ultrasonic.service.MusicService; +import org.moire.ultrasonic.service.MusicServiceFactory; +import org.moire.ultrasonic.util.Constants; +import org.moire.ultrasonic.util.ErrorDialog; +import org.moire.ultrasonic.util.ModalBackgroundTask; +import org.moire.ultrasonic.util.Util; + +import java.net.URL; + +/** + * Settings for Subsonic server. + */ +public class ServerSettingsFragment extends PreferenceFragment + implements Preference.OnPreferenceChangeListener, + Preference.OnPreferenceClickListener { + private static final String LOG_TAG = ServerSettingsFragment.class.getSimpleName(); + private static final String ARG_SERVER_ID = "serverId"; + + private EditTextPreference serverNamePref; + private EditTextPreference serverUrlPref; + private EditTextPreference serverUsernamePref; + private EditTextPreference serverPasswordPref; + private CheckBoxPreference equalizerPref; + private CheckBoxPreference jukeboxPref; + private Preference removeServerPref; + private Preference testConnectionPref; + + private int serverId; + private SharedPreferences sharedPreferences; + + public static ServerSettingsFragment newInstance(final int serverId) { + final ServerSettingsFragment fragment = new ServerSettingsFragment(); + final Bundle args = new Bundle(); + args.putInt(ARG_SERVER_ID, serverId); + fragment.setArguments(args); + + return fragment; + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + serverId = getArguments().getInt(ARG_SERVER_ID); + sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); + + addPreferencesFromResource(R.xml.server_settings); + } + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + serverNamePref = (EditTextPreference) findPreference(getString(R.string.settings_server_name)); + serverUrlPref = (EditTextPreference) findPreference(getString(R.string.settings_server_address)); + serverUsernamePref = (EditTextPreference) findPreference(getString(R.string.settings_server_username)); + serverPasswordPref = (EditTextPreference) findPreference(getString(R.string.settings_server_password)); + equalizerPref = (CheckBoxPreference) findPreference(getString(R.string.equalizer_enabled)); + jukeboxPref = (CheckBoxPreference) findPreference(getString(R.string.jukebox_is_default)); + removeServerPref = findPreference(getString(R.string.settings_server_remove_server)); + testConnectionPref = findPreference(getString(R.string.settings_test_connection_title)); + + setupPreferencesValues(); + setupPreferencesListeners(); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + if (preference == serverNamePref) { + sharedPreferences.edit() + .putString(Constants.PREFERENCES_KEY_SERVER_NAME + serverId, (String) newValue) + .apply(); + updateName(); + return true; + } else if (preference == serverUrlPref) { + final String url = (String) newValue; + try { + new URL(url); + if (!url.equals(url.trim()) || url.contains("@")) { + throw new Exception(); + } + } catch (Exception x) { + new ErrorDialog(getActivity(), R.string.settings_invalid_url, false); + return false; + } + + sharedPreferences.edit() + .putString(Constants.PREFERENCES_KEY_SERVER_URL + serverId, url) + .apply(); + updateUrl(); + return true; + } else if (preference == serverUsernamePref) { + String username = (String) newValue; + if (username == null || !username.equals(username.trim())) { + new ErrorDialog(getActivity(), R.string.settings_invalid_username, false); + return false; + } + + sharedPreferences.edit() + .putString(Constants.PREFERENCES_KEY_USERNAME + serverId, username) + .apply(); + updateUsername(); + return true; + } else if (preference == serverPasswordPref) { + sharedPreferences.edit() + .putString(Constants.PREFERENCES_KEY_PASSWORD + serverId, (String) newValue) + .apply(); + updatePassword(); + return true; + } else if (preference == equalizerPref) { + sharedPreferences.edit() + .putBoolean(Constants.PREFERENCES_KEY_SERVER_ENABLED + serverId, (Boolean) newValue) + .apply(); + return true; + } else if (preference == jukeboxPref) { + sharedPreferences.edit() + .putBoolean(Constants.PREFERENCES_KEY_JUKEBOX_BY_DEFAULT + serverId, (Boolean) newValue) + .apply(); + return true; + } + return false; + } + + @Override + public boolean onPreferenceClick(Preference preference) { + if (preference == removeServerPref) { + removeServer(); + return true; + } else if (preference == testConnectionPref) { + testConnection(); + return true; + } + return false; + } + + private void setupPreferencesValues() { + updateName(); + updateUrl(); + updateUsername(); + updatePassword(); + + if (!sharedPreferences.contains(Constants.PREFERENCES_KEY_SERVER_ENABLED + serverId)) { + sharedPreferences.edit() + .putBoolean(Constants.PREFERENCES_KEY_SERVER_ENABLED + serverId, true) + .apply(); + } + equalizerPref.setChecked(sharedPreferences + .getBoolean(Constants.PREFERENCES_KEY_SERVER_ENABLED + serverId, true)); + + jukeboxPref.setChecked(sharedPreferences + .getBoolean(Constants.PREFERENCES_KEY_JUKEBOX_BY_DEFAULT + serverId, false)); + } + + private void updatePassword() { + serverPasswordPref.setText(sharedPreferences + .getString(Constants.PREFERENCES_KEY_PASSWORD + serverId, "***")); + serverPasswordPref.setSummary("***"); + } + + private void updateUsername() { + serverUsernamePref.setText(sharedPreferences + .getString(Constants.PREFERENCES_KEY_USERNAME + serverId, + getString(R.string.settings_server_username))); + } + + private void updateUrl() { + final String serverUrl = sharedPreferences + .getString(Constants.PREFERENCES_KEY_SERVER_URL + serverId, + getString(R.string.settings_server_address_unset)); + serverUrlPref.setText(serverUrl); + serverUrlPref.setSummary(serverUrl); + } + + private void updateName() { + final String serverName = sharedPreferences + .getString(Constants.PREFERENCES_KEY_SERVER_NAME + serverId, + getString(R.string.settings_server_unused)); + serverNamePref.setText(serverName); + serverNamePref.setSummary(serverName); + } + + private void setupPreferencesListeners() { + serverNamePref.setOnPreferenceChangeListener(this); + serverUrlPref.setOnPreferenceChangeListener(this); + serverUsernamePref.setOnPreferenceChangeListener(this); + serverPasswordPref.setOnPreferenceChangeListener(this); + equalizerPref.setOnPreferenceChangeListener(this); + jukeboxPref.setOnPreferenceChangeListener(this); + + removeServerPref.setOnPreferenceClickListener(this); + testConnectionPref.setOnPreferenceClickListener(this); + } + + private void testConnection() { + ModalBackgroundTask task = new ModalBackgroundTask(getActivity(), false) { + private int previousInstance; + + @Override + protected Boolean doInBackground() throws Throwable { + updateProgress(R.string.settings_testing_connection); + + final Context context = getActivity(); + previousInstance = Util.getActiveServer(context); + Util.setActiveServer(context, serverId); + try { + MusicService musicService = MusicServiceFactory.getMusicService(context); + musicService.ping(context, this); + return musicService.isLicenseValid(context, null); + } finally { + Util.setActiveServer(context, previousInstance); + } + } + + @Override + protected void done(Boolean licenseValid) { + if (licenseValid) { + Util.toast(getActivity(), R.string.settings_testing_ok); + } else { + Util.toast(getActivity(), R.string.settings_testing_unlicensed); + } + } + + @Override + protected void cancel() { + super.cancel(); + Util.setActiveServer(getActivity(), previousInstance); + } + + @Override + protected void error(Throwable error) { + Log.w(LOG_TAG, error.toString(), error); + new ErrorDialog(getActivity(), String.format("%s %s", getResources().getString(R.string.settings_connection_failure), getErrorMessage(error)), false); + } + }; + task.execute(); + } + + private void removeServer() { + int activeServers = sharedPreferences + .getInt(Constants.PREFERENCES_KEY_ACTIVE_SERVERS, 0); + + // Reset values to null so when we ask for them again they are new + sharedPreferences.edit() + .remove(Constants.PREFERENCES_KEY_SERVER_NAME + serverId) + .remove(Constants.PREFERENCES_KEY_SERVER_URL + serverId) + .remove(Constants.PREFERENCES_KEY_USERNAME + serverId) + .remove(Constants.PREFERENCES_KEY_PASSWORD + serverId) + .remove(Constants.PREFERENCES_KEY_SERVER_ENABLED + serverId) + .remove(Constants.PREFERENCES_KEY_JUKEBOX_BY_DEFAULT + serverId) + .apply(); + + if (serverId < activeServers) { + int activeServer = Util.getActiveServer(getActivity()); + for (int i = serverId; i <= activeServers; i++) { + Util.removeInstanceName(getActivity(), i, activeServer); + } + } + + activeServers--; + + sharedPreferences.edit() + .putInt(Constants.PREFERENCES_KEY_ACTIVE_SERVERS, activeServers) + .apply(); + + getActivity().finish(); + } +} diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/SettingsFragment.java b/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/SettingsFragment.java new file mode 100644 index 00000000..472c49d1 --- /dev/null +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/SettingsFragment.java @@ -0,0 +1,375 @@ +package org.moire.ultrasonic.fragment; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.preference.CheckBoxPreference; +import android.preference.EditTextPreference; +import android.preference.ListPreference; +import android.preference.Preference; +import android.preference.PreferenceCategory; +import android.preference.PreferenceFragment; +import android.preference.PreferenceManager; +import android.provider.SearchRecentSuggestions; +import android.support.annotation.Nullable; +import android.util.Log; +import android.view.View; + +import org.moire.ultrasonic.R; +import org.moire.ultrasonic.activity.ServerSettingsActivity; +import org.moire.ultrasonic.activity.SubsonicTabActivity; +import org.moire.ultrasonic.provider.SearchSuggestionProvider; +import org.moire.ultrasonic.service.DownloadService; +import org.moire.ultrasonic.service.DownloadServiceImpl; +import org.moire.ultrasonic.util.Constants; +import org.moire.ultrasonic.util.FileUtil; +import org.moire.ultrasonic.util.ImageLoader; +import org.moire.ultrasonic.util.TimeSpanPreference; +import org.moire.ultrasonic.util.Util; + +import java.io.File; + +/** + * Shows main app settings. + */ +public class SettingsFragment extends PreferenceFragment + implements SharedPreferences.OnSharedPreferenceChangeListener { + private static final String LOG_TAG = SettingsFragment.class.getSimpleName(); + + private ListPreference theme; + private ListPreference videoPlayer; + private ListPreference maxBitrateWifi; + private ListPreference maxBitrateMobile; + private ListPreference cacheSize; + private EditTextPreference cacheLocation; + private ListPreference preloadCount; + private ListPreference bufferLength; + private ListPreference incrementTime; + private ListPreference networkTimeout; + private ListPreference maxAlbums; + private ListPreference maxSongs; + private ListPreference maxArtists; + private ListPreference defaultAlbums; + private ListPreference defaultSongs; + private ListPreference defaultArtists; + private ListPreference chatRefreshInterval; + private ListPreference directoryCacheTime; + private CheckBoxPreference mediaButtonsEnabled; + private CheckBoxPreference lockScreenEnabled; + private CheckBoxPreference sendBluetoothNotifications; + private CheckBoxPreference sendBluetoothAlbumArt; + private ListPreference viewRefresh; + private ListPreference imageLoaderConcurrency; + private EditTextPreference sharingDefaultDescription; + private EditTextPreference sharingDefaultGreeting; + private TimeSpanPreference sharingDefaultExpiration; + private PreferenceCategory serversCategory; + + private int maxServerCount = 10; + private SharedPreferences settings; + private int activeServers; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + addPreferencesFromResource(R.xml.settings); + + settings = PreferenceManager.getDefaultSharedPreferences(getActivity()); + } + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + theme = (ListPreference) findPreference(Constants.PREFERENCES_KEY_THEME); + videoPlayer = (ListPreference) findPreference(Constants.PREFERENCES_KEY_VIDEO_PLAYER); + maxBitrateWifi = (ListPreference) findPreference(Constants.PREFERENCES_KEY_MAX_BITRATE_WIFI); + maxBitrateMobile = (ListPreference) findPreference(Constants.PREFERENCES_KEY_MAX_BITRATE_MOBILE); + cacheSize = (ListPreference) findPreference(Constants.PREFERENCES_KEY_CACHE_SIZE); + cacheLocation = (EditTextPreference) findPreference(Constants.PREFERENCES_KEY_CACHE_LOCATION); + preloadCount = (ListPreference) findPreference(Constants.PREFERENCES_KEY_PRELOAD_COUNT); + bufferLength = (ListPreference) findPreference(Constants.PREFERENCES_KEY_BUFFER_LENGTH); + incrementTime = (ListPreference) findPreference(Constants.PREFERENCES_KEY_INCREMENT_TIME); + networkTimeout = (ListPreference) findPreference(Constants.PREFERENCES_KEY_NETWORK_TIMEOUT); + maxAlbums = (ListPreference) findPreference(Constants.PREFERENCES_KEY_MAX_ALBUMS); + maxSongs = (ListPreference) findPreference(Constants.PREFERENCES_KEY_MAX_SONGS); + maxArtists = (ListPreference) findPreference(Constants.PREFERENCES_KEY_MAX_ARTISTS); + defaultArtists = (ListPreference) findPreference(Constants.PREFERENCES_KEY_DEFAULT_ARTISTS); + defaultSongs = (ListPreference) findPreference(Constants.PREFERENCES_KEY_DEFAULT_SONGS); + defaultAlbums = (ListPreference) findPreference(Constants.PREFERENCES_KEY_DEFAULT_ALBUMS); + chatRefreshInterval = (ListPreference) findPreference(Constants.PREFERENCES_KEY_CHAT_REFRESH_INTERVAL); + directoryCacheTime = (ListPreference) findPreference(Constants.PREFERENCES_KEY_DIRECTORY_CACHE_TIME); + mediaButtonsEnabled = (CheckBoxPreference) findPreference(Constants.PREFERENCES_KEY_MEDIA_BUTTONS); + lockScreenEnabled = (CheckBoxPreference) findPreference(Constants.PREFERENCES_KEY_SHOW_LOCK_SCREEN_CONTROLS); + sendBluetoothAlbumArt = (CheckBoxPreference) findPreference(Constants.PREFERENCES_KEY_SEND_BLUETOOTH_ALBUM_ART); + sendBluetoothNotifications = (CheckBoxPreference) findPreference(Constants.PREFERENCES_KEY_SEND_BLUETOOTH_NOTIFICATIONS); + viewRefresh = (ListPreference) findPreference(Constants.PREFERENCES_KEY_VIEW_REFRESH); + imageLoaderConcurrency = (ListPreference) findPreference(Constants.PREFERENCES_KEY_IMAGE_LOADER_CONCURRENCY); + sharingDefaultDescription = (EditTextPreference) findPreference(Constants.PREFERENCES_KEY_DEFAULT_SHARE_DESCRIPTION); + sharingDefaultGreeting = (EditTextPreference) findPreference(Constants.PREFERENCES_KEY_DEFAULT_SHARE_GREETING); + sharingDefaultExpiration = (TimeSpanPreference) findPreference(Constants.PREFERENCES_KEY_DEFAULT_SHARE_EXPIRATION); + serversCategory = (PreferenceCategory) findPreference(Constants.PREFERENCES_KEY_SERVERS_KEY); + + sharingDefaultGreeting.setText(Util.getShareGreeting(getActivity())); + setupClearSearchPreference(); + setupGaplessControlSettingsV14(); + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + update(); + } + + @Override + public void onResume() { + super.onResume(); + + setupServersCategory(); + SharedPreferences preferences = Util.getPreferences(getActivity()); + preferences.registerOnSharedPreferenceChangeListener(this); + } + + @Override + public void onPause() { + super.onPause(); + + SharedPreferences prefs = Util.getPreferences(getActivity()); + prefs.unregisterOnSharedPreferenceChangeListener(this); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + Log.d(LOG_TAG, "Preference changed: " + key); + update(); + + if (Constants.PREFERENCES_KEY_HIDE_MEDIA.equals(key)) { + setHideMedia(sharedPreferences.getBoolean(key, false)); + } else if (Constants.PREFERENCES_KEY_MEDIA_BUTTONS.equals(key)) { + setMediaButtonsEnabled(sharedPreferences.getBoolean(key, true)); + } else if (Constants.PREFERENCES_KEY_CACHE_LOCATION.equals(key)) { + setCacheLocation(sharedPreferences.getString(key, "")); + } else if (Constants.PREFERENCES_KEY_SEND_BLUETOOTH_NOTIFICATIONS.equals(key)) { + setBluetoothPreferences(sharedPreferences.getBoolean(key, true)); + } else if (Constants.PREFERENCES_KEY_IMAGE_LOADER_CONCURRENCY.equals(key)) { + setImageLoaderConcurrency(Integer.parseInt(sharedPreferences.getString(key, "5"))); + } + } + + private void setupClearSearchPreference() { + Preference clearSearchPreference = findPreference(Constants.PREFERENCES_KEY_CLEAR_SEARCH_HISTORY); + + if (clearSearchPreference != null) { + clearSearchPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + SearchRecentSuggestions suggestions = + new SearchRecentSuggestions(getActivity(), + SearchSuggestionProvider.AUTHORITY, + SearchSuggestionProvider.MODE); + suggestions.clearHistory(); + Util.toast(getActivity(), R.string.settings_search_history_cleared); + return false; + } + }); + } + } + + private void setupGaplessControlSettingsV14() { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { + PreferenceCategory playbackControlSettings = + (PreferenceCategory) findPreference(Constants.PREFERENCES_KEY_PLAYBACK_CONTROL_SETTINGS); + CheckBoxPreference gaplessPlaybackEnabled = + (CheckBoxPreference) findPreference(Constants.PREFERENCES_KEY_GAPLESS_PLAYBACK); + + if (gaplessPlaybackEnabled != null) { + gaplessPlaybackEnabled.setChecked(false); + gaplessPlaybackEnabled.setEnabled(false); + + if (playbackControlSettings != null) { + playbackControlSettings.removePreference(gaplessPlaybackEnabled); + } + } + } + } + + private void setupServersCategory() { + activeServers = settings.getInt(Constants.PREFERENCES_KEY_ACTIVE_SERVERS, 0); + final Preference addServerPreference = new Preference(getActivity()); + addServerPreference.setKey(Constants.PREFERENCES_KEY_ADD_SERVER); + addServerPreference.setPersistent(false); + addServerPreference.setTitle(getResources().getString(R.string.settings_server_add_server)); + addServerPreference.setEnabled(activeServers < maxServerCount); + + serversCategory.removeAll(); + serversCategory.addPreference(addServerPreference); + + for (int i = 1; i <= activeServers; i++) { + final int serverId = i; + Preference preference = new Preference(getActivity()); + preference.setPersistent(false); + preference.setTitle(settings.getString(Constants.PREFERENCES_KEY_SERVER_NAME + serverId, + getString(R.string.settings_server_name))); + preference.setSummary(settings.getString(Constants.PREFERENCES_KEY_SERVER_URL + serverId, + getString(R.string.settings_server_address_unset))); + preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + final Intent intent = new Intent(getActivity(), ServerSettingsActivity.class); + intent.putExtra(ServerSettingsActivity.ARG_SERVER_ID, serverId); + startActivity(intent); + return true; + } + }); + serversCategory.addPreference(preference); + } + + addServerPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + if (activeServers == maxServerCount) { + return false; + } + + activeServers++; + + settings.edit() + .putInt(Constants.PREFERENCES_KEY_ACTIVE_SERVERS, activeServers) + .apply(); + + Preference addServerPreference = findPreference(Constants.PREFERENCES_KEY_ADD_SERVER); + + if (addServerPreference != null) { + serversCategory.removePreference(addServerPreference); + } + + Preference newServerPrefs = new Preference(getActivity()); + newServerPrefs.setTitle(getString(R.string.settings_server_name)); + newServerPrefs.setSummary(getString(R.string.settings_server_address_unset)); + newServerPrefs.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + final Intent intent = new Intent(getActivity(), ServerSettingsActivity.class); + intent.putExtra(ServerSettingsActivity.ARG_SERVER_ID, activeServers); + startActivity(intent); + return true; + } + }); + serversCategory.addPreference(newServerPrefs); + + if (addServerPreference != null) { + serversCategory.addPreference(addServerPreference); + addServerPreference.setEnabled(activeServers < maxServerCount); + } + + return true; + } + }); + } + + private void update() { + theme.setSummary(theme.getEntry()); + videoPlayer.setSummary(videoPlayer.getEntry()); + maxBitrateWifi.setSummary(maxBitrateWifi.getEntry()); + maxBitrateMobile.setSummary(maxBitrateMobile.getEntry()); + cacheSize.setSummary(cacheSize.getEntry()); + cacheLocation.setSummary(cacheLocation.getText()); + preloadCount.setSummary(preloadCount.getEntry()); + bufferLength.setSummary(bufferLength.getEntry()); + incrementTime.setSummary(incrementTime.getEntry()); + networkTimeout.setSummary(networkTimeout.getEntry()); + maxAlbums.setSummary(maxAlbums.getEntry()); + maxArtists.setSummary(maxArtists.getEntry()); + maxSongs.setSummary(maxSongs.getEntry()); + defaultAlbums.setSummary(defaultAlbums.getEntry()); + defaultArtists.setSummary(defaultArtists.getEntry()); + defaultSongs.setSummary(defaultSongs.getEntry()); + chatRefreshInterval.setSummary(chatRefreshInterval.getEntry()); + directoryCacheTime.setSummary(directoryCacheTime.getEntry()); + viewRefresh.setSummary(viewRefresh.getEntry()); + imageLoaderConcurrency.setSummary(imageLoaderConcurrency.getEntry()); + sharingDefaultExpiration.setSummary(sharingDefaultExpiration.getText()); + sharingDefaultDescription.setSummary(sharingDefaultDescription.getText()); + sharingDefaultGreeting.setSummary(sharingDefaultGreeting.getText()); + + if (!mediaButtonsEnabled.isChecked()) { + lockScreenEnabled.setChecked(false); + lockScreenEnabled.setEnabled(false); + } + + if (!sendBluetoothNotifications.isChecked()) { + sendBluetoothAlbumArt.setChecked(false); + sendBluetoothAlbumArt.setEnabled(false); + } + } + + private static void setImageLoaderConcurrency(int concurrency) { + SubsonicTabActivity instance = SubsonicTabActivity.getInstance(); + + if (instance != null) { + ImageLoader imageLoader = instance.getImageLoader(); + + if (imageLoader != null) { + imageLoader.stopImageLoader(); + imageLoader.setConcurrency(concurrency); + } + } + } + + private void setHideMedia(boolean hide) { + File nomediaDir = new File(FileUtil.getUltraSonicDirectory(), ".nomedia"); + if (hide && !nomediaDir.exists()) { + if (!nomediaDir.mkdir()) { + Log.w(LOG_TAG, "Failed to create " + nomediaDir); + } + } else if (nomediaDir.exists()) { + if (!nomediaDir.delete()) { + Log.w(LOG_TAG, "Failed to delete " + nomediaDir); + } + } + Util.toast(getActivity(), R.string.settings_hide_media_toast, false); + } + + private void setMediaButtonsEnabled(boolean enabled) { + if (enabled) { + lockScreenEnabled.setEnabled(true); + Util.registerMediaButtonEventReceiver(getActivity()); + } else { + lockScreenEnabled.setEnabled(false); + Util.unregisterMediaButtonEventReceiver(getActivity()); + } + } + + private void setBluetoothPreferences(boolean enabled) { + if (enabled) { + sendBluetoothAlbumArt.setEnabled(true); + } else { + sendBluetoothAlbumArt.setEnabled(false); + } + } + + private void setCacheLocation(String path) { + File dir = new File(path); + + if (!FileUtil.ensureDirectoryExistsAndIsReadWritable(dir)) { + Util.toast(getActivity(), R.string.settings_cache_location_error, false); + + // Reset it to the default. + String defaultPath = FileUtil.getDefaultMusicDirectory().getPath(); + if (!defaultPath.equals(path)) { + Util.getPreferences(getActivity()).edit() + .putString(Constants.PREFERENCES_KEY_CACHE_LOCATION, defaultPath) + .apply(); + cacheLocation.setSummary(defaultPath); + cacheLocation.setText(defaultPath); + } + + // Clear download queue. + DownloadService downloadService = DownloadServiceImpl.getInstance(); + downloadService.clear(); + } + } +} diff --git a/ultrasonic/src/main/res/values/strings.xml b/ultrasonic/src/main/res/values/strings.xml index 9249b973..2f523aba 100644 --- a/ultrasonic/src/main/res/values/strings.xml +++ b/ultrasonic/src/main/res/values/strings.xml @@ -392,6 +392,7 @@ 12 albumArt Multiple Years + http://yourhost No songs diff --git a/ultrasonic/src/main/res/values/styles.xml b/ultrasonic/src/main/res/values/styles.xml index f8589503..deb1d19e 100644 --- a/ultrasonic/src/main/res/values/styles.xml +++ b/ultrasonic/src/main/res/values/styles.xml @@ -1,15 +1,15 @@ - - - diff --git a/ultrasonic/src/main/res/values/themes.xml b/ultrasonic/src/main/res/values/themes.xml index 0c3dae13..8eaafcd7 100644 --- a/ultrasonic/src/main/res/values/themes.xml +++ b/ultrasonic/src/main/res/values/themes.xml @@ -1,7 +1,7 @@ - -