package de.blau.android.prefs; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import android.annotation.SuppressLint; import android.content.Context; import android.content.SharedPreferences; import android.content.res.Resources; import android.content.res.Resources.NotFoundException; import android.os.Build; import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.Log; import de.blau.android.R; import de.blau.android.contract.Urls; import de.blau.android.osm.Server; import de.blau.android.presets.Preset; import de.blau.android.resources.DataStyle; /** * Convenience class for parsing and holding the application's SharedPreferences. * * @author mb */ public class Preferences { private static String DEBUG_TAG = "Preferences"; private final AdvancedPrefDatabase advancedPrefs; private final boolean isStatsVisible; private final boolean isToleranceVisible; private final boolean isAntiAliasingEnabled; private final boolean isOpenStreetBugsEnabled; private final boolean isPhotoLayerEnabled; private final boolean isKeepScreenOnEnabled; private final boolean useBackForUndo; private final boolean largeDragArea; private final boolean tagFormEnabled; private String backgroundLayer; private final String overlayLayer; private final String scaleLayer; private final String mapProfile; private final String followGPSbutton; private final String fullscreenMode; private int gpsInterval; private float gpsDistance; private float maxStrokeWidth; private int tileCacheSize; // in MB private int downloadRadius; // in m private float maxDownloadSpeed; // in km/h private int bugDownloadRadius; private float maxBugDownloadSpeed; // in km/h private Set<String> taskFilter; // can't be final private final boolean forceContextMenu; private final boolean enableNameSuggestions; private final boolean enableAutoPreset; private final boolean closeChangesetOnSave; private final boolean splitActionBarEnabled; private final String gpsSource; private final String gpsTcpSource; private final String offsetServer; private final String osmoseServer; private final boolean showCameraAction; private final boolean generateAlerts; private int maxAlertDistance; private final boolean lightThemeEnabled; private Set<String> addressTags; // can't be final private final boolean voiceCommandsEnabled; private final boolean leaveGpsDisabled; private final boolean showIcons; private final boolean showWayIcons; private int maxInlineValues; private int maxTileDownloadThreads; private int notificationCacheSize; private int autoLockDelay; private final boolean alwaysDrawBoundingBoxes; private final boolean jsConsoleEnabled; private final static String DEFAULT_MAP_PROFILE = "Color Round Nodes"; private final SharedPreferences prefs; private final Resources r; /** * * @param cty Android context * @throws IllegalArgumentException * @throws NotFoundException */ @SuppressLint("NewApi") public Preferences(Context ctx) throws IllegalArgumentException, NotFoundException { prefs = PreferenceManager.getDefaultSharedPreferences(ctx); r = ctx.getResources(); advancedPrefs = new AdvancedPrefDatabase(ctx); // we're not using acra.disable - ensure it isn't present if (prefs.contains("acra.disable")) { SharedPreferences.Editor editor = prefs.edit(); editor.remove("acra.disable"); editor.commit(); } // we *are* using acra.enable if (!prefs.contains("acra.enable")) { SharedPreferences.Editor editor = prefs.edit(); editor.putBoolean("acra.enable", true); editor.commit(); } try { maxStrokeWidth = Float.parseFloat(prefs.getString(r.getString(R.string.config_maxStrokeWidth_key), "16")); } catch (NumberFormatException e) { Log.w(DEBUG_TAG, "error parsing config_maxStrokeWidth_key=" + prefs.getString(r.getString(R.string.config_maxStrokeWidth_key), "10")); maxStrokeWidth = 16; } try { tileCacheSize = Integer.parseInt(prefs.getString(r.getString(R.string.config_tileCacheSize_key), "10")); } catch (NumberFormatException e) { Log.w(DEBUG_TAG, "error parsing config_tileCacheSize_key=" + prefs.getString(r.getString(R.string.config_tileCacheSize_key), "10")); tileCacheSize = 100; } try { downloadRadius = Integer.parseInt(prefs.getString(r.getString(R.string.config_extTriggeredDownloadRadius_key), "50")); } catch (NumberFormatException e) { Log.w(DEBUG_TAG, "error parsing config_extTriggeredDownloadRadius_key=" + prefs.getString(r.getString(R.string.config_extTriggeredDownloadRadius_key), "50")); downloadRadius = 50; } try { maxDownloadSpeed = Float.parseFloat(prefs.getString(r.getString(R.string.config_maxDownloadSpeed_key), "6")); } catch (NumberFormatException e) { Log.w(DEBUG_TAG, "error parsing config_maxDownloadSpeed_key=" + prefs.getString(r.getString(R.string.config_maxDownloadSpeed_key), "6")); maxDownloadSpeed = 6f; } try { bugDownloadRadius = Integer.parseInt(prefs.getString(r.getString(R.string.config_bugDownloadRadius_key), "200")); } catch (NumberFormatException e) { Log.w(DEBUG_TAG, "error parsing config_extTriggeredDownloadRadius_key=" + prefs.getString(r.getString(R.string.config_bugDownloadRadius_key), "200")); bugDownloadRadius = 200; } try { maxBugDownloadSpeed = Float.parseFloat(prefs.getString(r.getString(R.string.config_maxBugDownloadSpeed_key), "30")); } catch (NumberFormatException e) { Log.w(DEBUG_TAG, "error parsing config_maxDownloadSpeed_key=" + prefs.getString(r.getString(R.string.config_maxBugDownloadSpeed_key), "30")); maxBugDownloadSpeed = 30f; } taskFilter = new HashSet<String>(Arrays.asList(r.getStringArray(R.array.bug_filter_defaults))); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { taskFilter = prefs.getStringSet(r.getString(R.string.config_bugFilter_key), taskFilter); } isStatsVisible = prefs.getBoolean(r.getString(R.string.config_showStats_key), false); isToleranceVisible = prefs.getBoolean(r.getString(R.string.config_showTolerance_key), true); isAntiAliasingEnabled = prefs.getBoolean(r.getString(R.string.config_enableAntiAliasing_key), true); isOpenStreetBugsEnabled = prefs.getBoolean(r.getString(R.string.config_enableOpenStreetBugs_key), false); isPhotoLayerEnabled = prefs.getBoolean(r.getString(R.string.config_enablePhotoLayer_key), false); tagFormEnabled = prefs.getBoolean(r.getString(R.string.config_tagFormEnabled_key), true); isKeepScreenOnEnabled = prefs.getBoolean(r.getString(R.string.config_enableKeepScreenOn_key), false); useBackForUndo = prefs.getBoolean(r.getString(R.string.config_use_back_for_undo_key), false); largeDragArea = prefs.getBoolean(r.getString(R.string.config_largeDragArea_key), false); enableNameSuggestions = prefs.getBoolean(r.getString(R.string.config_enableNameSuggestions_key), true); enableAutoPreset = prefs.getBoolean(r.getString(R.string.config_enableAutoPreset_key), true); closeChangesetOnSave = prefs.getBoolean(r.getString(R.string.config_closeChangesetOnSave_key), true); splitActionBarEnabled = prefs.getBoolean(r.getString(R.string.config_splitActionBarEnabled_key), true); backgroundLayer = prefs.getString(r.getString(R.string.config_backgroundLayer_key), null); overlayLayer = prefs.getString(r.getString(R.string.config_overlayLayer_key), null); scaleLayer = prefs.getString(r.getString(R.string.config_scale_key), "SCALE_METRIC"); String tempMapProfile = prefs.getString(r.getString(R.string.config_mapProfile_key), null); // check if we actually still have the profile if (DataStyle.getStyle(tempMapProfile) == null) { if (DataStyle.getStyle(DEFAULT_MAP_PROFILE) == null) { Log.w(DEBUG_TAG, "Using builtin default profile instead of " + tempMapProfile + " and " + DEFAULT_MAP_PROFILE); mapProfile = DataStyle.getBuiltinStyleName(); // built-in fall back } else { Log.w(DEBUG_TAG, "Using default profile"); mapProfile = DEFAULT_MAP_PROFILE; } } else { mapProfile = tempMapProfile; } gpsSource = prefs.getString(r.getString(R.string.config_gps_source_key), "internal"); gpsTcpSource = prefs.getString(r.getString(R.string.config_gps_source_tcp_key), "127.0.0.1:1958"); try { gpsDistance = Float.parseFloat(prefs.getString(r.getString(R.string.config_gps_distance_key), "2.0")); gpsInterval = Integer.parseInt(prefs.getString(r.getString(R.string.config_gps_interval_key), "1000")); } catch (NumberFormatException e) { Log.w(DEBUG_TAG, "error parsing config_gps_distance_key or config_gps_interval_key"); gpsDistance = 2.0f; gpsInterval = 1000; } forceContextMenu = prefs.getBoolean(r.getString(R.string.config_forceContextMenu_key), false); offsetServer = prefs.getString(r.getString(R.string.config_offsetServer_key), Urls.DEFAULT_OFFSET_SERVER); osmoseServer = prefs.getString(r.getString(R.string.config_offsetServer_key), Urls.DEFAULT_OSMOSE_SERVER); showCameraAction = prefs.getBoolean(r.getString(R.string.config_showCameraAction_key), true); generateAlerts = prefs.getBoolean(r.getString(R.string.config_generateAlerts_key), false); try { maxAlertDistance = Integer.parseInt(prefs.getString(r.getString(R.string.config_maxAlertDistance_key), "100")); } catch (NumberFormatException e) { Log.w(DEBUG_TAG, "error parsing config_maxAlertDistance_key"); maxAlertDistance = 100; } // light theme now always default lightThemeEnabled = prefs.getBoolean(r.getString(R.string.config_enableLightTheme_key), true); addressTags = new HashSet<String>(Arrays.asList(r.getStringArray(R.array.address_tags_defaults))); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { addressTags = prefs.getStringSet(r.getString(R.string.config_addressTags_key), addressTags); } voiceCommandsEnabled = prefs.getBoolean(r.getString(R.string.config_voiceCommandsEnabled_key), false); leaveGpsDisabled = prefs.getBoolean(r.getString(R.string.config_leaveGpsDisabled_key), false); showIcons = prefs.getBoolean(r.getString(R.string.config_showIcons_key), true); showWayIcons = prefs.getBoolean(r.getString(R.string.config_showWayIcons_key), true); followGPSbutton = prefs.getString(r.getString(R.string.config_followGPSbutton_key), "LEFT"); fullscreenMode = prefs.getString(r.getString(R.string.config_fullscreenMode_key), Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ? r.getString(R.string.full_screen_auto) : r.getString(R.string.full_screen_never)); try { maxInlineValues = Integer.parseInt(prefs.getString(r.getString(R.string.config_maxInlineValues_key), "4")); } catch (NumberFormatException e) { Log.w(DEBUG_TAG, "error parsing config_maxInlineValues_key=" + prefs.getString(r.getString(R.string.config_maxInlineValues_key), "4")); maxInlineValues = 4; } try { maxTileDownloadThreads = Integer.parseInt(prefs.getString(r.getString(R.string.config_maxTileDownloadThreads_key), "2")); } catch (NumberFormatException e) { Log.w(DEBUG_TAG, "error parsing config_maxTileDownloadThreads_key=" + prefs.getString(r.getString(R.string.config_maxTileDownloadThreads_key), "2")); maxTileDownloadThreads = 2; } try { notificationCacheSize = Integer.parseInt(prefs.getString(r.getString(R.string.config_notificationCacheSize_key), "5")); } catch (NumberFormatException e) { Log.w(DEBUG_TAG, "error parsing config_notificationCacheSize_key=" + prefs.getString(r.getString(R.string.config_notificationCacheSize_key), "5")); notificationCacheSize = 5; } try { autoLockDelay = Integer.parseInt(prefs.getString(r.getString(R.string.config_autoLockDelay_key), "60")); } catch (NumberFormatException e) { Log.w(DEBUG_TAG, "error parsing config_autoLockDelay_key=" + prefs.getString(r.getString(R.string.config_autoLockDelay_key), "60")); autoLockDelay = 60; } alwaysDrawBoundingBoxes = prefs.getBoolean(r.getString(R.string.config_alwaysDrawBoundingBoxes_key), true); jsConsoleEnabled = prefs.getBoolean(r.getString(R.string.config_js_console_key), false); } /** * @return the maximum width of a stroke */ public float getMaxStrokeWidth() { return maxStrokeWidth; } /** * @return the size of the tile cache in MB */ public int getTileCacheSize() { return tileCacheSize; } /** * @return */ public boolean isStatsVisible() { return isStatsVisible; } /** * @return */ public boolean isToleranceVisible() { return isToleranceVisible; } /** * @return */ public boolean isAntiAliasingEnabled() { return isAntiAliasingEnabled; } /** * @return */ public boolean areBugsEnabled() { return isOpenStreetBugsEnabled; } /** * Set the status of the tasks/bugs display * @param on if true enable */ public void setBugsEnabled(boolean on) { prefs.edit().putBoolean(r.getString(R.string.config_enableOpenStreetBugs_key), on).commit(); } /** * @return */ public boolean isPhotoLayerEnabled() { return isPhotoLayerEnabled; } /** * @return */ public boolean tagFormEnabled() { return tagFormEnabled; } /** * * @return */ public boolean isKeepScreenOnEnabled() { return isKeepScreenOnEnabled; } /** * @return */ public boolean useBackForUndo() { return useBackForUndo; } /** * @return */ public boolean largeDragArea() { return largeDragArea; } /** * @return */ public String backgroundLayer() { return backgroundLayer; } public void setBackGroundLayer(String name) { backgroundLayer = name; prefs.edit().putString(r.getString(R.string.config_backgroundLayer_key), name).commit(); } /** * @return */ public String overlayLayer() { return overlayLayer; } /** * @return */ public String scaleLayer() { return scaleLayer; } /** * @return */ public String getMapProfile() { return mapProfile; } /** * @return */ public Server getServer() { return advancedPrefs.getServerObject(); } public Preset[] getPreset() { return advancedPrefs.getCurrentPresetObject(); } public boolean getShowIcons() { return showIcons; } public boolean getShowWayIcons() { return showWayIcons; } /** * @return */ public String getGpsSource() { return gpsSource; } /** * @return */ public String getGpsTcpSource() { return gpsTcpSource; } /** * @return */ public int getGpsInterval() { return gpsInterval; } /** * @return */ public float getGpsDistance() { return gpsDistance; } public boolean getForceContextMenu() { return forceContextMenu; } public boolean getEnableNameSuggestions() { return enableNameSuggestions; } /** * @return */ public int getDownloadRadius() { return downloadRadius; } /** * @return */ public float getMaxDownloadSpeed() { return maxDownloadSpeed; } public int getBugDownloadRadius() { return bugDownloadRadius; } public float getMaxBugDownloadSpeed() { return maxBugDownloadSpeed; } public Set<String> taskFilter() { return taskFilter; } public boolean enableAutoPreset() { // return enableAutoPreset; } /** * @return */ public boolean closeChangesetOnSave() { return closeChangesetOnSave; } public boolean splitActionBarEnabled() { return splitActionBarEnabled; } public String getOffsetServer() { return offsetServer; } public String getOsmoseServer() { return offsetServer; } public boolean showCameraAction() { return showCameraAction; } public boolean generateAlerts() { return generateAlerts; } public boolean lightThemeEnabled() { return lightThemeEnabled; } public Set<String> addressTags() { return addressTags; } public int getMaxAlertDistance() { return maxAlertDistance; } public boolean voiceCommandsEnabled() { return voiceCommandsEnabled; } public boolean leaveGpsDisabled() { return leaveGpsDisabled; } public String followGPSbuttonPosition() { return followGPSbutton; } public String getFullscreenMode() { return fullscreenMode; } public int getMaxInlineValues() { return maxInlineValues; } public int getMaxTileDownloadThreads() { return maxTileDownloadThreads; } public int getNotificationCacheSize() { if (notificationCacheSize < 1) { Log.e(DEBUG_TAG,"Notification cache size smaller than 1"); return 1; } return notificationCacheSize; } public int getAutolockDelay() { return 1000*autoLockDelay; } public void setAutoDownload(boolean on) { prefs.edit().putBoolean(r.getString(R.string.config_autoDownload_key), on).commit(); } public boolean getAutoDownload() { String key = r.getString(R.string.config_autoDownload_key); if (!prefs.contains(key)) { // create the entry setAutoDownload(false); } return prefs.getBoolean(key, false); } public void setContrastValue(float cValue){ prefs.edit().putFloat(r.getString(R.string.config_contrastValue_key),cValue).commit(); } public float getContrastValue(){ String key = r.getString(R.string.config_contrastValue_key); if (!prefs.contains(key)) { // create the entry setContrastValue(0); } return prefs.getFloat(key, 0); } public void setBugAutoDownload(boolean on) { prefs.edit().putBoolean(r.getString(R.string.config_bugAutoDownload_key), on).commit(); } public boolean getBugAutoDownload() { String key = r.getString(R.string.config_bugAutoDownload_key); if (!prefs.contains(key)) { // create the entry setBugAutoDownload(false); } return prefs.getBoolean(key, false); } public void setShowGPS(boolean on) { prefs.edit().putBoolean(r.getString(R.string.config_showGPS_key), on).commit(); } public boolean getShowGPS() { String key = r.getString(R.string.config_showGPS_key); if (!prefs.contains(key)) { // create the entry setShowGPS(true); } return prefs.getBoolean(key, true); } public boolean getAlwaysDrawBoundingBoxes() { return alwaysDrawBoundingBoxes; } public void enableTagFilter(boolean on) { prefs.edit().putBoolean(r.getString(R.string.config_tagFilter_key), on).commit(); } public boolean getEnableTagFilter() { String key = r.getString(R.string.config_tagFilter_key); if (!prefs.contains(key)) { // create the entry enableTagFilter(false); } return prefs.getBoolean(key, false); } public void enablePresetFilter(boolean on) { prefs.edit().putBoolean(r.getString(R.string.config_presetFilter_key), on).commit(); } public boolean getEnablePresetFilter() { String key = r.getString(R.string.config_presetFilter_key); if (!prefs.contains(key)) { // create the entry enablePresetFilter(false); } return prefs.getBoolean(key, false); } public void setGeocoder(int index) { prefs.edit().putInt(r.getString(R.string.config_geocoder_key), index).commit(); } public int getGeocoder() { String key = r.getString(R.string.config_geocoder_key); if (!prefs.contains(key)) { // create the entry setGeocoder(0); } return prefs.getInt(key, 0); } public boolean isJsConsoleEnabled() { return jsConsoleEnabled; } /** * Get a string from shared preferences * * @param prefKey preference key as a string resource * @return the strings or null if nothing was found */ @Nullable public String getString(int prefKey) { try { String key = r.getString(prefKey); return prefs.getString(key, null); } catch (Exception ex) { Log.e(DEBUG_TAG,"getString " + ex.getMessage()); return null; } } /** * Save a string to shared preferences * * @param prefKey preference key as a string resource * @param s string value to save */ public void putString(int prefKey, @NonNull String s) { try { String key = r.getString(prefKey); if (key != null) { prefs.edit().putString(r.getString(prefKey), s).commit(); } else { Log.e(DEBUG_TAG,"" + prefKey + " is not a valid string resource"); } } catch (Exception ex) { Log.e(DEBUG_TAG,"putString " + ex.getMessage()); } } }