com.androzic.Preferences.java Source code

Java tutorial

Introduction

Here is the source code for com.androzic.Preferences.java

Source

/*
 * Androzic - android navigation client that uses OziExplorer maps (ozf2, ozfx3).
 * Copyright (C) 2010-2014 Andrey Novikov <http://andreynovikov.info/>
 * 
 * This file is part of Androzic application.
 * 
 * Androzic 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.
 * 
 * Androzic 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 Androzic. If not, see <http://www.gnu.org/licenses/>.
 */

package com.androzic;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.droidparts.widget.MultiSelectListPreference;
import org.mapsforge.map.rendertheme.XmlRenderThemeStyleLayer;
import org.mapsforge.map.rendertheme.XmlRenderThemeStyleMenu;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.app.backup.BackupManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.EditTextPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.support.v4.app.Fragment;
import android.support.v4.app.ListFragment;
import android.support.v4.preference.PreferenceFragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.util.Xml;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.androzic.map.online.TileProvider;
import com.androzic.ui.SeekbarPreference;
import com.androzic.util.XmlUtils;

public class Preferences extends ListFragment {
    private FragmentHolder fragmentHolderCallback;

    private final ArrayList<Header> headers = new ArrayList<>();
    private HeaderAdapter adapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        headers.clear();
        loadHeadersFromResource(R.xml.preference_headers, headers);
        adapter = new HeaderAdapter(getActivity(), headers);
        setListAdapter(adapter);

        /*
         * Androzic application = (Androzic) getApplication();
         * if (! application.isPaid)
         * {
         * for (int i = 0; i < getListAdapter().getCount(); i++)
         * {
         * if (R.id.pref_sharing == ((Header) getListAdapter().getItem(i)).id)
         * {
         * ((Header) getListAdapter().getItem(i)).summaryRes = R.string.donation_required;
         * ((Header) getListAdapter().getItem(i)).fragmentArguments.putBoolean("disable", true);
         * }
         * }
         * }
         */

        /*
         * if (getArguments().hasExtra("pref"))
         * {
         * for (int i = 0; i < getListAdapter().getCount(); i++)
         * {
         * if (getIntent().getIntExtra("pref", -1) == ((Header) getListAdapter().getItem(i)).id)
         * {
         * startWithFragment(((Header) getListAdapter().getItem(i)).fragment, ((Header) getListAdapter().getItem(i)).fragmentArguments, null, 0);
         * finish();
         * }
         * }
         * }
         */
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            fragmentHolderCallback = (FragmentHolder) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement FragmentHolder");
        }
    }

    @Override
    public void onListItemClick(ListView lv, View v, int position, long id) {
        Header header = adapter.getItem(position);

        Fragment fragment = Fragment.instantiate(getActivity(), header.fragment);
        Bundle args = header.fragmentArguments;
        if (args == null)
            args = new Bundle();
        //TODO We should use breadcrumbs or remove them from parser
        args.putString("title", (String) header.getTitle(getResources()));
        args.putInt("help", header.help);
        fragment.setArguments(args);

        fragmentHolderCallback.addFragment(fragment, header.fragment);
    }

    /**
     * Parse the given XML file as a header description, adding each
     * parsed Header into the target list.
     *
     * @param resid
     *            The XML resource to load and parse.
     * @param target
     *            The list in which the parsed headers should be placed.
     */
    public void loadHeadersFromResource(int resid, List<Header> target) {
        Androzic application = Androzic.getApplication();
        XmlResourceParser parser = null;
        try {
            Resources resources = getResources();
            parser = resources.getXml(resid);
            AttributeSet attrs = Xml.asAttributeSet(parser);

            int type;
            //noinspection StatementWithEmptyBody
            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) {
                // Parse next until start tag is found
            }

            String nodeName = parser.getName();
            if (!"preference-headers".equals(nodeName)) {
                throw new RuntimeException("XML document must start with <preference-headers> tag; found" + nodeName
                        + " at " + parser.getPositionDescription());
            }

            Bundle curBundle = null;

            final int outerDepth = parser.getDepth();
            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                    continue;
                }

                nodeName = parser.getName();
                if ("header".equals(nodeName)) {
                    Header header = new Header();

                    TypedArray sa = resources.obtainAttributes(attrs, R.styleable.PreferenceHeader);
                    header.id = sa.getResourceId(R.styleable.PreferenceHeader_id, (int) HEADER_ID_UNDEFINED);
                    TypedValue tv = sa.peekValue(R.styleable.PreferenceHeader_title);
                    if (tv != null && tv.type == TypedValue.TYPE_STRING) {
                        if (tv.resourceId != 0) {
                            header.titleRes = tv.resourceId;
                        } else {
                            header.title = tv.string;
                        }
                    }
                    tv = sa.peekValue(R.styleable.PreferenceHeader_summary);
                    if (tv != null && tv.type == TypedValue.TYPE_STRING) {
                        if (tv.resourceId != 0) {
                            header.summaryRes = tv.resourceId;
                        } else {
                            header.summary = tv.string;
                        }
                    }
                    tv = sa.peekValue(R.styleable.PreferenceHeader_breadCrumbTitle);
                    if (tv != null && tv.type == TypedValue.TYPE_STRING) {
                        if (tv.resourceId != 0) {
                            header.breadCrumbTitleRes = tv.resourceId;
                        } else {
                            header.breadCrumbTitle = tv.string;
                        }
                    }
                    tv = sa.peekValue(R.styleable.PreferenceHeader_breadCrumbShortTitle);
                    if (tv != null && tv.type == TypedValue.TYPE_STRING) {
                        if (tv.resourceId != 0) {
                            header.breadCrumbShortTitleRes = tv.resourceId;
                        } else {
                            header.breadCrumbShortTitle = tv.string;
                        }
                    }
                    header.iconRes = sa.getResourceId(R.styleable.PreferenceHeader_icon, 0);
                    header.fragment = sa.getString(R.styleable.PreferenceHeader_fragment);
                    header.help = sa.getResourceId(R.styleable.PreferenceHeader_help, 0);
                    sa.recycle();

                    if (curBundle == null) {
                        curBundle = new Bundle();
                    }

                    final int innerDepth = parser.getDepth();
                    while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                            && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
                        if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                            continue;
                        }

                        String innerNodeName = parser.getName();
                        if (innerNodeName.equals("extra")) {
                            resources.parseBundleExtra(innerNodeName, attrs, curBundle);
                            XmlUtils.skipCurrentTag(parser);

                        } else if (innerNodeName.equals("intent")) {
                            header.intent = Intent.parseIntent(resources, parser, attrs);

                        } else {
                            XmlUtils.skipCurrentTag(parser);
                        }
                    }

                    if (curBundle.size() > 0) {
                        header.fragmentArguments = curBundle;
                        curBundle = null;
                    }

                    if (header.id == R.id.pref_plugins && application.getPluginsPreferences().size() == 0)
                        continue;

                    target.add(header);
                } else {
                    XmlUtils.skipCurrentTag(parser);
                }
            }

        } catch (XmlPullParserException | IOException e) {
            throw new RuntimeException("Error parsing headers", e);
        } finally {
            if (parser != null)
                parser.close();
        }

    }

    private static class HeaderAdapter extends ArrayAdapter<Header> {
        private static class HeaderViewHolder {
            ImageView icon;
            TextView title;
            TextView summary;
        }

        private LayoutInflater mInflater;

        public HeaderAdapter(Context context, List<Header> objects) {
            super(context, 0, objects);
            mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            HeaderViewHolder holder;
            View view;

            if (convertView == null) {
                view = mInflater.inflate(R.layout.preference_header_item, parent, false);
                holder = new HeaderViewHolder();
                holder.icon = (ImageView) view.findViewById(android.R.id.icon);
                holder.title = (TextView) view.findViewById(android.R.id.title);
                holder.summary = (TextView) view.findViewById(android.R.id.summary);
                view.setTag(holder);
            } else {
                view = convertView;
                holder = (HeaderViewHolder) view.getTag();
            }

            // All view fields must be updated every time, because the view may be recycled
            Header header = getItem(position);
            holder.icon.setImageResource(header.iconRes);
            holder.title.setText(header.getTitle(getContext().getResources()));
            CharSequence summary = header.getSummary(getContext().getResources());
            if (!TextUtils.isEmpty(summary)) {
                holder.summary.setVisibility(View.VISIBLE);
                holder.summary.setText(summary);
            } else {
                holder.summary.setVisibility(View.GONE);
            }

            return view;
        }
    }

    /**
     * Default value for {@link Header#id Header.id} indicating that no
     * identifier value is set. All other values (including those below -1)
     * are valid.
     */
    public static final long HEADER_ID_UNDEFINED = -1;

    /**
     * Description of a single Header item that the user can select.
     */
    public static final class Header implements Parcelable {
        public int help;

        /**
         * Identifier for this header, to correlate with a new list when
         * it is updated. The default value is {@link PreferenceActivity#HEADER_ID_UNDEFINED}, meaning no id.
         * 
         * @attr ref android.R.styleable#PreferenceHeader_id
         */
        public long id = HEADER_ID_UNDEFINED;

        /**
         * Resource ID of title of the header that is shown to the user.
         * 
         * @attr ref android.R.styleable#PreferenceHeader_title
         */
        public int titleRes;

        /**
         * Title of the header that is shown to the user.
         * 
         * @attr ref android.R.styleable#PreferenceHeader_title
         */
        public CharSequence title;

        /**
         * Resource ID of optional summary describing what this header controls.
         * 
         * @attr ref android.R.styleable#PreferenceHeader_summary
         */
        public int summaryRes;

        /**
         * Optional summary describing what this header controls.
         * 
         * @attr ref android.R.styleable#PreferenceHeader_summary
         */
        public CharSequence summary;

        /**
         * Resource ID of optional text to show as the title in the bread crumb.
         * 
         * @attr ref android.R.styleable#PreferenceHeader_breadCrumbTitle
         */
        public int breadCrumbTitleRes;

        /**
         * Optional text to show as the title in the bread crumb.
         * 
         * @attr ref android.R.styleable#PreferenceHeader_breadCrumbTitle
         */
        public CharSequence breadCrumbTitle;

        /**
         * Resource ID of optional text to show as the short title in the bread crumb.
         * 
         * @attr ref android.R.styleable#PreferenceHeader_breadCrumbShortTitle
         */
        public int breadCrumbShortTitleRes;

        /**
         * Optional text to show as the short title in the bread crumb.
         * 
         * @attr ref android.R.styleable#PreferenceHeader_breadCrumbShortTitle
         */
        public CharSequence breadCrumbShortTitle;

        /**
         * Optional icon resource to show for this header.
         * 
         * @attr ref android.R.styleable#PreferenceHeader_icon
         */
        public int iconRes;

        /**
         * Full class name of the fragment to display when this header is
         * selected.
         * 
         * @attr ref android.R.styleable#PreferenceHeader_fragment
         */
        public String fragment;

        /**
         * Optional arguments to supply to the fragment when it is
         * instantiated.
         */
        public Bundle fragmentArguments;

        /**
         * Intent to launch when the preference is selected.
         */
        public Intent intent;

        /**
         * Optional additional data for use by subclasses of PreferenceActivity.
         */
        public Bundle extras;

        public Header() {
            // Empty
        }

        /**
         * Return the currently set title. If {@link #titleRes} is set,
         * this resource is loaded from <var>res</var> and returned. Otherwise {@link #title} is returned.
         */
        public CharSequence getTitle(Resources res) {
            if (titleRes != 0) {
                return res.getText(titleRes);
            }
            return title;
        }

        /**
         * Return the currently set summary. If {@link #summaryRes} is set,
         * this resource is loaded from <var>res</var> and returned. Otherwise {@link #summary} is returned.
         */
        public CharSequence getSummary(Resources res) {
            if (summaryRes != 0) {
                return res.getText(summaryRes);
            }
            return summary;
        }

        /**
         * Return the currently set bread crumb title. If {@link #breadCrumbTitleRes} is set,
         * this resource is loaded from <var>res</var> and returned. Otherwise {@link #breadCrumbTitle} is returned.
         */
        public CharSequence getBreadCrumbTitle(Resources res) {
            if (breadCrumbTitleRes != 0) {
                return res.getText(breadCrumbTitleRes);
            }
            return breadCrumbTitle;
        }

        /**
         * Return the currently set bread crumb short title. If {@link #breadCrumbShortTitleRes} is set,
         * this resource is loaded from <var>res</var> and returned. Otherwise {@link #breadCrumbShortTitle} is returned.
         */
        public CharSequence getBreadCrumbShortTitle(Resources res) {
            if (breadCrumbShortTitleRes != 0) {
                return res.getText(breadCrumbShortTitleRes);
            }
            return breadCrumbShortTitle;
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeLong(id);
            dest.writeInt(titleRes);
            TextUtils.writeToParcel(title, dest, flags);
            dest.writeInt(summaryRes);
            TextUtils.writeToParcel(summary, dest, flags);
            dest.writeInt(breadCrumbTitleRes);
            TextUtils.writeToParcel(breadCrumbTitle, dest, flags);
            dest.writeInt(breadCrumbShortTitleRes);
            TextUtils.writeToParcel(breadCrumbShortTitle, dest, flags);
            dest.writeInt(iconRes);
            dest.writeString(fragment);
            dest.writeBundle(fragmentArguments);
            if (intent != null) {
                dest.writeInt(1);
                intent.writeToParcel(dest, flags);
            } else {
                dest.writeInt(0);
            }
            dest.writeBundle(extras);
        }

        public void readFromParcel(Parcel in) {
            id = in.readLong();
            titleRes = in.readInt();
            title = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
            summaryRes = in.readInt();
            summary = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
            breadCrumbTitleRes = in.readInt();
            breadCrumbTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
            breadCrumbShortTitleRes = in.readInt();
            breadCrumbShortTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
            iconRes = in.readInt();
            fragment = in.readString();
            fragmentArguments = in.readBundle();
            if (in.readInt() != 0) {
                intent = Intent.CREATOR.createFromParcel(in);
            }
            extras = in.readBundle();
        }

        Header(Parcel in) {
            readFromParcel(in);
        }

        public static final Creator<Header> CREATOR = new Creator<Header>() {
            public Header createFromParcel(Parcel source) {
                return new Header(source);
            }

            public Header[] newArray(int size) {
                return new Header[size];
            }
        };
    }

    public static class PreferencesFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener {
        private int help;

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setHasOptionsMenu(true);

            Bundle arguments = getArguments();

            if (arguments == null)
                return;

            String resource = arguments.getString("resource");
            if (resource != null) {
                int res = getActivity().getResources().getIdentifier(resource, "xml",
                        getActivity().getPackageName());
                addPreferencesFromResource(res);
            }

            if (arguments.getBoolean("disable", false)) {
                PreferenceScreen screen = getPreferenceScreen();
                for (int i = 0; i < screen.getPreferenceCount(); i++) {
                    getPreferenceScreen().getPreference(i).setEnabled(false);
                }
            }

            help = arguments.getInt("help", 0);
        }

        @Override
        public void onResume() {
            super.onResume();

            // initialize list summaries
            initSummaries(getPreferenceScreen());
            getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
            ((AppCompatActivity) getActivity()).getSupportActionBar()
                    .setSubtitle(getArguments().getString("title"));
        }

        @Override
        public void onPause() {
            super.onPause();

            getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
            ((AppCompatActivity) getActivity()).getSupportActionBar().setSubtitle(null);
        }

        @Override
        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
            inflater.inflate(R.menu.help_menu, menu);
            super.onCreateOptionsMenu(menu, inflater);
        }

        @Override
        public void onPrepareOptionsMenu(final Menu menu) {
            menu.findItem(R.id.action_help).setVisible(help != 0);
        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
            case R.id.action_help:
                PreferencesHelpDialog dialog = new PreferencesHelpDialog(help);
                dialog.show(getFragmentManager(), "dialog");
                return true;
            default:
                return super.onOptionsItemSelected(item);
            }
        }

        @SuppressLint("NewApi")
        public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
            if (key.equals(getString(R.string.pref_folder_root))) {
                Androzic application = Androzic.getApplication();
                String root = sharedPreferences.getString(key, Environment.getExternalStorageDirectory()
                        + File.separator + getString(R.string.def_folder_prefix));
                application.setRootPath(root);
            } else if (key.equals(getString(R.string.pref_folder_map))) {
                final ProgressDialog pd = new ProgressDialog(getActivity());
                pd.setIndeterminate(true);
                pd.setMessage(getString(R.string.msg_initializingmaps));
                pd.show();

                new Thread(new Runnable() {
                    public void run() {
                        Androzic application = Androzic.getApplication();
                        application.setMapPath(sharedPreferences.getString(key,
                                getActivity().getResources().getString(R.string.def_folder_map)));
                        pd.dismiss();
                    }
                }).start();
            } else if (key.equals(getString(R.string.pref_charset))) {
                final ProgressDialog pd = new ProgressDialog(getActivity());
                pd.setIndeterminate(true);
                pd.setMessage(getString(R.string.msg_initializingmaps));
                pd.show();

                new Thread(new Runnable() {
                    public void run() {
                        Androzic application = Androzic.getApplication();
                        application.charset = sharedPreferences.getString(key, "UTF-8");
                        application.resetMaps();
                        pd.dismiss();
                    }
                }).start();
            }

            Preference pref = findPreference(key);
            setPrefSummary(pref);

            if (key.equals(getString(R.string.pref_locale))) {
                new AlertDialog.Builder(getActivity()).setTitle(R.string.restart_needed)
                        .setIcon(android.R.drawable.ic_dialog_alert)
                        .setMessage(getString(R.string.restart_needed_explained)).setCancelable(false)
                        .setPositiveButton(R.string.ok, null).show();
            }
            // TODO change intent name
            getActivity().sendBroadcast(new Intent("onSharedPreferenceChanged").putExtra("key", key));
            try {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO)
                    BackupManager.dataChanged("com.androzic");
            } catch (NoClassDefFoundError e) {
            }
        }

        protected void setPrefSummary(Preference pref) {
            if (pref instanceof MultiSelectListPreference) {
                CharSequence[] summaries = ((MultiSelectListPreference) pref).getCheckedEntries();
                if (summaries != null) {
                    StringBuffer summary = new StringBuffer("");
                    for (int i = 0; i < summaries.length; i++) {
                        summary.append(summaries[i]);
                        if (i < summaries.length - 1) {
                            summary.append(", ");
                        }
                    }
                    pref.setSummary(summary);
                }
            }
            if (pref instanceof ListPreference) {
                CharSequence summary = ((ListPreference) pref).getEntry();
                if (summary != null) {
                    pref.setSummary(summary);
                }
            } else if (pref instanceof EditTextPreference) {
                CharSequence summary = ((EditTextPreference) pref).getText();
                if (summary != null) {
                    pref.setSummary(summary);
                }
            } else if (pref instanceof SeekbarPreference) {
                CharSequence summary = ((SeekbarPreference) pref).getText();
                if (summary != null) {
                    pref.setSummary(summary);
                }
            }
        }

        private void initSummaries(PreferenceGroup preference) {
            for (int i = preference.getPreferenceCount() - 1; i >= 0; i--) {
                Preference pref = preference.getPreference(i);
                setPrefSummary(pref);

                if (pref instanceof PreferenceGroup || pref instanceof PreferenceScreen) {
                    initSummaries((PreferenceGroup) pref);
                }
            }
        }
    }

    @SuppressWarnings("UnusedDeclaration")
    public static class PluginsPreferencesFragment extends Preferences.PreferencesFragment {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            PreferenceScreen root = getPreferenceManager().createPreferenceScreen(getActivity());
            root.setTitle(R.string.pref_plugins_title);
            setPreferenceScreen(root);

            Androzic application = (Androzic) getActivity().getApplication();
            Map<String, Intent> plugins = application.getPluginsPreferences();

            for (String plugin : plugins.keySet()) {
                Preference preference = new Preference(getActivity());
                preference.setTitle(plugin);
                preference.setIntent(plugins.get(plugin));
                root.addPreference(preference);
            }
        }
    }

    @SuppressWarnings("UnusedDeclaration")
    public static class MapPreferencesFragment extends Preferences.PreferencesFragment {
        String themeSelection;

        @Override
        public void onResume() {
            initThemeList();
            initPoiList();
            initProviderList();

            super.onResume();
        }

        @Override
        public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
            if (key.equals(getString(R.string.pref_vectormap_theme))) {
                Androzic application = Androzic.getApplication();
                XmlRenderThemeStyleMenu xmlRenderThemeStyleMenu = application.xmlRenderThemeStyleMenu;
                themeSelection = sharedPreferences.getString(key, xmlRenderThemeStyleMenu.getDefaultValue());
                initPoiList();
            } else if (key.equals(getString(R.string.pref_vectormap_poi))) {
                SharedPreferences.Editor editor = sharedPreferences.edit();
                editor.putString(key + "_" + themeSelection, sharedPreferences.getString(key, "---"));
                editor.commit();
            }
            super.onSharedPreferenceChanged(sharedPreferences, key);
        }

        private void initThemeList() {
            Androzic application = Androzic.getApplication();
            XmlRenderThemeStyleMenu xmlRenderThemeStyleMenu = application.xmlRenderThemeStyleMenu;

            ListPreference themePreference = (ListPreference) findPreference(
                    getString(R.string.pref_vectormap_theme));
            // This is the user language for the app, in 'en', 'de' etc format
            // No dialects are supported at the moment
            String language = Locale.getDefault().getLanguage();
            Map<String, XmlRenderThemeStyleLayer> baseLayers = xmlRenderThemeStyleMenu.getLayers();
            int visibleStyles = 0;
            for (XmlRenderThemeStyleLayer baseLayer : baseLayers.values()) {
                if (baseLayer.isVisible())
                    visibleStyles++;
            }

            String[] entries = new String[visibleStyles];
            String[] values = new String[visibleStyles];
            int i = 0;
            for (XmlRenderThemeStyleLayer baseLayer : baseLayers.values()) {
                if (baseLayer.isVisible()) {
                    entries[i] = baseLayer.getTitle(language);
                    values[i] = baseLayer.getId();
                    i++;
                }
            }

            themePreference.setDefaultValue(xmlRenderThemeStyleMenu.getDefaultValue());
            themePreference.setEntries(entries);
            themePreference.setEntryValues(values);

            themeSelection = themePreference.getValue();
            // We need to check that the selection stored is actually a valid getLayer in the current
            // rendertheme.
            if (themeSelection == null || !xmlRenderThemeStyleMenu.getLayers().containsKey(themeSelection)) {
                themeSelection = xmlRenderThemeStyleMenu.getLayer(xmlRenderThemeStyleMenu.getDefaultValue())
                        .getId();
                themePreference.setValue(themeSelection);
            }
            themePreference.setSummary(xmlRenderThemeStyleMenu.getLayer(themeSelection).getTitle(language));
        }

        private void initPoiList() {
            Androzic application = Androzic.getApplication();
            XmlRenderThemeStyleMenu xmlRenderThemeStyleMenu = application.xmlRenderThemeStyleMenu;

            String language = Locale.getDefault().getLanguage();

            MultiSelectListPreference poiPreference = (MultiSelectListPreference) findPreference(
                    getString(R.string.pref_vectormap_poi));

            int poiTypes = 0, defaultTypes = 0;
            for (XmlRenderThemeStyleLayer overlay : xmlRenderThemeStyleMenu.getLayer(themeSelection)
                    .getOverlays()) {
                poiTypes++;
                if (overlay.isEnabled())
                    defaultTypes++;
            }

            String[] entries = new String[poiTypes];
            String[] values = new String[poiTypes];
            String[] defaults = new String[defaultTypes];
            int i = 0, j = 0;
            for (XmlRenderThemeStyleLayer overlay : xmlRenderThemeStyleMenu.getLayer(themeSelection)
                    .getOverlays()) {
                entries[i] = overlay.getTitle(language);
                values[i] = overlay.getId();
                i++;
                if (overlay.isEnabled()) {
                    defaults[j] = overlay.getId();
                    j++;
                }
            }
            StringBuilder sb = new StringBuilder();
            for (i = 0; i < defaultTypes; i++) {
                sb.append(defaults[i]);
                if (i < defaultTypes - 1)
                    sb.append(MultiSelectListPreference.SEP);
            }
            String defaultPoi = sb.toString();
            Log.e("PREF", "Default: " + defaultPoi);
            String value = poiPreference.getSharedPreferences()
                    .getString(poiPreference.getKey() + "_" + themeSelection, "---");
            Log.e("PREF", "Value: " + value);
            if ("---".equals(value))
                poiPreference.setValue(defaultPoi);
            else
                poiPreference.setValue(value);
            poiPreference.setDefaultValue(defaultPoi);
            poiPreference.setEntries(entries);
            poiPreference.setEntryValues(values);
            setPrefSummary(poiPreference);
        }

        private void initProviderList() {
            Androzic application = Androzic.getApplication();

            // Enumerate online providers
            MultiSelectListPreference mapPreference = (MultiSelectListPreference) findPreference(
                    getString(R.string.pref_onlinemap));
            // initialize map list
            List<TileProvider> providers = application.getOnlineMaps();
            String[] entries = new String[providers.size()];
            String[] values = new String[providers.size()];
            int i = 0;
            for (TileProvider provider : providers) {
                entries[i] = provider.name;
                values[i] = provider.code;
                i++;
            }
            mapPreference.setEntries(entries);
            mapPreference.setEntryValues(values);
        }
    }
}