默认共享首选项在Service中给出了错误的值

时间:2014-05-15 09:41:33

标签: android sharedpreferences

我有一个PreferenceFragment,我在XML中定义了一个CheckBoxPreference。我需要在服务中检查这个值,但它总是给我旧值。我注意到当我重新启动应用程序时,该值已正确更改。

我的偏好片段:

public class OptionsFragment extends PreferenceFragment 
{

    public static final String WIFI_ONLY = "wifi";

    private SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(MyApplication.getInstance());

    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.config);
    }

 }

我的config.xml:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

    <CheckBoxPreference
        android:defaultValue="true"
        android:key="wifi"
        android:summary="Check if you want to use wifi only"
        android:title="Use Wifi only" />

</PreferenceScreen>

我的服务:

SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MyApplication.getInstance());        
Log.d(TAG, "isWifiOnly : "+settings.getBoolean(OptionsFragment.WIFI_ONLY, true));

无论是否更改,日志始终返回相同的值,除非我重新启动应用程序。另外,在我的MainActivity中,我在OnCreate()中有这一行:

PreferenceManager.setDefaultValues(getApplicationContext(), R.xml.config, false);

如果需要,它会使用默认值创建配置文件。

我做错了什么,问题是什么?

2 个答案:

答案 0 :(得分:7)

我找到了一个解决方案,感谢这个链接Managing SharedPreferences in both PreferenceActivity and Service within same app并感谢Andrew T.:

问题是多进程模式。如果你有一个服务,它在清单中使用android:process =&#34;&#34; (这是我的情况)然后设置多进程模式是必要的。

这就是我所做的:

在PreferenceFragment中:

public static final String CONFIG_NAME = "pref";

...

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


    getPreferenceManager().setSharedPreferencesName(CONFIG_NAME);
    getPreferenceManager().setSharedPreferencesMode(Context.MODE_MULTI_PROCESS);

    addPreferencesFromResource(R.xml.config);

    ...
}

我的服务:

SharedPreferences settings = MyApplication.getInstance().getSharedPreferences(OptionsFragment.CONFIG_NAME, Context.MODE_MULTI_PROCESS);

我以这种方式在MainActivity中设置默认值:

PreferenceManager.setDefaultValues(getApplicationContext(), OptionsFragment.CONFIG_NAME, Context.MODE_MULTI_PROCESS, R.xml.config, false);

现在它工作正常。希望它会有所帮助!

再次感谢Andrew T.

答案 1 :(得分:2)

我在最后几天遇到同样的问题......

我有一个带有布局和键的preference.xml,并在收听更改时将其膨胀到PreferenceFragment中,从而通知服务我的应用程序有任何更改。 关键部分是设置SharedPreference访问权限的模式:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.preferences);
    getPreferenceManager().setSharedPreferencesMode(Context.MODE_MULTI_PROCESS);
}

Context.MODE_MULTI_PROCESS标志使提交()适用于所有访问进程,因此即使我的服务也可以直接访问刚刚更改的值。

@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
{
    if(SettingsManager.setupIsValid(getActivity())){
        Intent startServiceIntent = new Intent(getActivity(), IntentService.class);
        startServiceIntent.setAction("PREFERENCES_CHANGED");
        getActivity().startService(startServiceIntent);
    } else {
        Toast.makeText(getActivity(), getString(R.string.settings_incomplete), Toast.LENGTH_SHORT).show();
    }
}

这将首先检查魔法,并在设置有效时通知服务更改。

这允许在所有进程中使用多个进程并始终使用当前首选项值。

P.S。:直接访问然后看起来像这样

SharedPreferences prefs = context.getSharedPreferences(context.getPackageName() + "_preferences", Context.MODE_MULTI_PROCESS);