android 动态预填充首选项

android pre populate preferences dynamically

我想以编程方式检查是否安装了 sd 卡,如果是,让用户选择在外部和内部存储之间切换。

我在 preferences.xml.

中组织了其他静态设置

如果我开始更动态地使用首选项,似乎我必须在代码中重写 xml 文件的所有设置。

或者是否有一个选项可以增强 xml 中的首选项,以及仅在需要时使用的代码中的首选项?

谢谢

如果可能,将此添加到清单中以在 SD 卡上安装应用程序:

android:installLocation="preferExternal">

验证sd卡是否可写可读使用此方法:

private boolean isExternalStorageWritable() {
       return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);}

获取 sdCard 上的应用程序文件夹(externalStorageVolumes[0] 是主文件夹):

File[] externalStorageVolumes =
    ContextCompat.getExternalFilesDirs(getApplicationContext(), null);

Oficial documentation

我自己摸索出来的,看起来有点笨拙,但是很管用

再一次:我的问题是我在 xml 文件中预先配置了某些设置选项,如下所述: Preferences with XML

这是我的 preferences.xml:

<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">

    <PreferenceCategory app:title="@string/download_header">
        <SwitchPreferenceCompat
            app:key="dl_background"
            app:title="@string/background_behaviour"
            app:defaultValue="false"/>
        <ListPreference
            app:title="@string/dl_qual"
            app:defaultValue="@string/low_qual"
            app:key="dl_qual"
            app:entries="@array/dl_qual_arry"
            app:entryValues="@array/dl_qual_arry"/>
    </PreferenceCategory>
    <PreferenceCategory app:title="@string/tc_header">
        <SwitchPreferenceCompat
            app:key="tc_installed"
            app:title="@string/tc_behaviour"
            app:defaultValue="false"/>
        <ListPreference
            app:title="@string/dl_dir_root"
            app:key="dl_dir_root"/>
    </PreferenceCategory>
</PreferenceScreen>

在这里您可以定义映射到 ListPrefrence 对象的数组。

每个选项列表然后从一个资源 xml 文件中填充实际的列表条目。

我在上面的第一个 ListPreference“dl_qual”中使用了这种方法。

这是 resource.xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="dl_qual_arry">
        <item>Higher quality (128kbps)</item>
        <item>Lower quality (64kbps)</item>
    </string-array>
</resources>

但后来我有了插入一个 ListPreference 的想法,其中选项列表的值仅在运行时已知。

这是我在“dl_dir_root”上方的第二个 ListPreference。

我懒得重写(并提前阅读如何做)代码中的完整设置 activity。

所以我在我的 SettingsActivity 中得到了这个 SettingsFragment:

public static class SettingsFragment extends PreferenceFragmentCompat {
    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        //First, lets check whether we have initialized preferences already
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
        String selectedDir = prefs.getString("dl_dir_root", "INIT");

        setPreferencesFromResource(R.xml.root_preferences, rootKey);
        PreferenceScreen root = getPreferenceScreen();
        ListPreference  dlDirRoot = root.findPreference("dl_dir_root");
        CharSequence[] arryValues = BBCWorldServiceDownloaderUtils.getStoragePaths(getContext());
        CharSequence[] arryEntrys = BBCWorldServiceDownloaderUtils.getStoragePaths(getContext());
        dlDirRoot.setEntries(arryEntrys);
        dlDirRoot.setEntryValues(arryValues);


        if(selectedDir.equals("INIT")) {
            //Initialize value/index
            dlDirRoot.setDefaultValue(arryValues[0]);
            dlDirRoot.setValueIndex(0);
        }
        else{
            //Position at already selected value/index
            dlDirRoot.setDefaultValue(selectedDir);
            dlDirRoot.setValue(selectedDir);
            dlDirRoot.setValueIndex(dlDirRoot.findIndexOfValue(selectedDir));

        }
    }
}

首先应用预定义的 xml,然后访问“dl_dir_root”的 ListPreference 对象并添加选项:

ListPreference  dlDirRoot = root.findPreference("dl_dir_root");
    CharSequence[] arryValues = BBCWorldServiceDownloaderUtils.getStoragePaths(getContext());
    CharSequence[] arryEntrys = BBCWorldServiceDownloaderUtils.getStoragePaths(getContext());
    dlDirRoot.setEntries(arryEntrys);
    dlDirRoot.setEntryValues(arryValues);

其余的是 checking/keeping 调用之间的状态 activity。

如果有人知道更优雅的方式,我会很好奇。

最佳

马蒂亚斯