我能在服务中获取共享首选项中的数据吗?

52

我正在开发一款Android应用程序,使用的是Android 2.2版本。

在我的应用程序中,我正在捕获GPS数据并将其发送到服务中,时间间隔为1小时。如果用户退出应用程序,它也能正常工作(这是必需的)。

我正在使用2个服务(用户自定义),一个用于捕获GPS数据,另一个用于将数据发送到服务器。

下面是我的疑问:

  • 在服务中,我们可以使用共享首选项吗?

  • 如果我们在应用程序的任何活动中存储任何数据在共享首选项中,那么我们能否通过共享首选项在服务中使用该数据?


最佳答案在这里找到:https://dev59.com/Cmw15IYBdhLWcg3wtd8g?lq=1 - Ajit Kumar Dubey
6个回答

47
您可以通过调用PreferenceManager.getDefaultSharedPreferences(Context context)来访问默认的共享首选项实例,该实例在所有ActivityService类之间共享。
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);

这对于存储简单的原始数据类型(例如布尔值)或可序列化对象非常好。然而,如果您要捕获大量位置数据,则可能考虑改用SQLite数据库。


4
这篇答案结合了这篇文章:服务中的上下文在onStart或onStartCommand之前是不可见的:https://dev59.com/oVvUa4cB1Zd3GeqPxNFU,对我来说解决了这个问题。 - class
2
你可以始终传递服务的 getApplicationContext() 方法的结果。 - twaddington
@twaddington 如果我们使用 getSharedPreferences(String, Context),那么偏好设置就不会被共享了吗? - Sohaib
@twaddington:我也在我的活动和服务中使用共享首选项,例如mPrefsRead = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE);。但有时,我从首选项中获取默认值,例如如果我写mPrefsWrite.putBoolean(KEY, true),但在读取时得到false,例如mPrefsRead.getBoolean(KEY_LOGIN_STATUS, false);。我还确认了该值没有被设置为false。我的应用程序和服务作为不同的进程运行,这导致从首选项中获取默认值,正如一些SO答案所说。您的答案能否解决这个问题? - Madhan
这是正确的答案,感谢twaddington的帮助。例如,在下面的MyService类和方法中:@Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate"); SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); String email = preferences.getString("email_address", "default@google.com"); mythread = new MyThread(email); Toast.makeText(this, email, Toast.LENGTH_LONG).show(); } - Dung

18


我找到了解决方案。
在一个服务内,我们调用以下方法来获取共享偏好设置。

myapp.bmodel.getApplicationContext().getSharedPreferences("myPrefs_capture_gps_per_hour", Context.MODE_PRIVATE);
在上述代码中,myapp 是应用程序类的一个对象,该类派生自 Application 类。

8

您需要一个上下文来访问共享首选项。最好的方法是创建MyApplication作为Application类的后代,在那里实例化preferences并在应用程序的其余部分中使用它们作为MyApplication.preferences:

public class MyApplication extends Application {
    public static SharedPreferences preferences;

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

        preferences = getSharedPreferences( getPackageName() + "_preferences", MODE_PRIVATE);

例如,如果您需要在其他地方访问您的首选项,您可以调用此方法来读取首选项:
String str = MyApplication.preferences.getString( KEY, DEFAULT );

或者你可以调用以下代码将某些内容保存到首选项中:

MyApplication.preferences.edit().putString( KEY, VALUE ).commit();

(不要忘记在添加或更改首选项后调用commit()!)

2
这在技术上是可行的,但为什么不直接使用提供的PreferenceManager#getDefaultSharedPreferences(Context context);静态方法呢?那正是它的用途。 - twaddington
1
@twaddington 你应该更仔细地阅读。我的答案允许在context不可用时访问首选项。 - lenik
2
当然可以,但他特别询问如何在ActivityService中使用共享首选项,这两者都有可用的Context - twaddington
1
无论您提供哪个上下文,getDefaultSharedPreferences 都应该始终返回相同的 SharedPreference 实例。 - twaddington
MyApplication需要在任何活动中的变量内创建吗? - gumuruh
显示剩余2条评论

8

是的,Shivkumar,你可以像在Activity中一样正常地在任何类型的服务中使用共享偏好设置。

同样的

SharedPreferences preferences = getSharedPreferences("<PrefName>",
            MODE_PRIVATE);

简单!同样地,对于getResources、getString等等... IntentService类继承自Context。 - Stephen Hosking

5

有两种方式创建SharedPreference实例:

第一种情况:

SharedPreferences preferences = activity.getSharedPreferences("<PrefName>", MODE_PRIVATE);

案例2:

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);

请注意,如果在不同的位置创建相同名称(情况1)或相同上下文(情况2)的首选项,则它们仍然是相同的,并且可以共享数据,这是显而易见的。


0
在一个服务中,我会使用:
  SharedPreferences sharedPref = getApplicationContext().getSharedPreferences(Constants.SHARED_PREF, Context.MODE_PRIVATE);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接