【问题标题】:Sharedpreferences not accessable when activity started from broadcast receiver活动从广播接收器开始时无法访问共享首选项
【发布时间】:2014-03-01 13:36:34
【问题描述】:

(与我刚刚发布的另一个问题略有不同,如果违反规则,请道歉)

在我的活动1中,我正在设置一些共享偏好,接下来我通过一个意图启动另一个活动2,并从sharedpreferences设置一些文本视图......这一切都很好。

这是我的问题。 在我的第一个活动 1 中,我有一个带有待处理意图的 alarmmanger,这个待处理意图是用于锁定手机的广播接收器,然后启动活动 2。此活动与上面提到的第二个活动相同。然而,当这个活动从broadcastreceiver 开始时,没有一个文本视图是从sharedpreferences 加载的。这只发生在从 broadcastreceiver 启动 activity2 时。

SharedPreference 在活动一中设置为

SharedPreferences lockPreferences = getSharedPreferences("lockprefs", Context.MODE_PRIVATE);

在activity2中的访问方式相同

SharedPreferences lockPreferences = getSharedPreferences("lockprefs", Context.MODE_PRIVATE);

然后我可以得到字符串等

当从广播接收器启动activity2时,没有加载任何sharedprefs。

broadcastreceiver 位于不同的包名中,我将其移动到与活动相同的包中进行测试,但没有区别。

它快把我逼疯了,请帮忙! 谢谢

编辑

我有一个 GCMIntentService,这是我设置共享首选项的地方(基于从 GCM 收到的值)(我只包含了相关代码)

public class GcmIntentService extends IntentService {

public static final String PREFERENCE_NAME = "lockPreference";

  @Override
    protected void onHandleIntent(Intent intent) {

        SharedPreferences lockPreference = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor lockPrefsEditor;
        lockPrefsEditor = lockPreference.edit();

lockPrefsEditor.putString("newpassword", newpassword);
lockPrefsEditor.commit();

现在如果我启动 activity2 ,共享首选项会被正确读取。 但是,当尝试先从广播接收器访问时,它不起作用。

这是一个测试接收者

package com.myapp;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.util.Log;
import android.widget.Toast;

public class test extends BroadcastReceiver {


    public static final String TAG = "myapp";
    public static String newpassword = ""; 


 @Override
 public void onReceive(Context context, Intent intent) {


      Log.i(TAG,"test receiver");

      SharedPreferences lockPreference = context.getSharedPreferences(GcmIntentService.PREFERENCE_NAME, Context.MODE_PRIVATE);
      newpassword = lockPreference.getString("newpassword", "");
      Log.i(TAG, "Password from shared prefs: " + newpassword);

      Toast.makeText(context, "Sharedprefs password:" + newpassword, Toast.LENGTH_SHORT).show();


        }
}

toast 只显示 Sharedprefs 密码:

这是activity2,可以读取prefs没问题

public class Activity2 extends Activity  {


    String newpassword;



    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.set);


        //retrieve shared prefs
        SharedPreferences lockPreference = getSharedPreferences(GcmIntentService.PREFERENCE_NAME, Context.MODE_PRIVATE);
newpassword = lockPreference.getString("newpassword", "");

然后我可以创建一个toast 或其他任何东西。

我不明白为什么广播接收器会失败,这不是同一个上下文吗??

【问题讨论】:

  • 粘贴并删除了代码?解决了吗?
  • 请显示您尝试访问 SharedPreferences 的所有位置的代码 - BroadcastReceiver 代码显然是调试代码,但您不会在上下文中显示 Activity2 代码。

标签: android broadcastreceiver sharedpreferences


【解决方案1】:

除了Adb El-Rahman said 之外,SharedPreferences 还会根据您使用的context 从 XML 文件中加载。

如您所见,您正在使用传递给BroadcastReceiver 的上下文,这可能不是您的应用程序的上下文 - 因此将引用不同的首选项文件。它将是一个ReceiverRestrictedContext 实例。

但是,根据@CommonsWare's answer to another question,您应该能够通过在您的BroadcastReceiver 中调用context.getApplicationContext() 来使其工作。


顺便说一句,您应该注意不要在 BroadcastReceiver 中运行太多代码 - 系统似乎不喜欢这样。

【讨论】:

  • 我如何知道上下文是否正确?我只是指定了 context.getSharedPreferences ...这适用于活动 2,但不适用于广播接收器
  • BroadcastReceiver 的javadoc 中,它将上下文定义为“接收器运行的上下文”。我认为这意味着它可以是制作广播的应用程序,而不是你的应用程序。但是ActivityContext,它与您的应用程序相关联。所以基本上不要把这段代码放到一个广播接收器中,而是放到一个活动或服务中。保持您的 BroadcastReceiver 代码非常简短,以避免出现问题。
  • @Gary 我发现了一个相关问题,表明您应该能够从您的接收器访问您的SharedPreferences。我仍然认为这在生产中是一个坏主意,但我可以看到您正在尝试一些基本的调试。有兴趣知道你是否可以使用getApplicationContext()
  • 是的,它现在可以工作了,谢谢...我在接收器中没有做太多,但我需要从 sharedprefs 中设置 1 或 2 个值...。现在都可以工作了 :-)
【解决方案2】:

首先,您应该知道您通过getSharedPreference 方法创建的SharedPreference 文件在您的应用程序目录中表示为真实的XML 文件,因此如果您已经添加了值并提交了修改,那么您的所有编辑都应该存在。

其次,在您的项目中拥有 BroadcastReceiver 类应该采用与您的项目相同的 PackageName,即使它是在您的应用关闭时启动的。

现在您需要确保的是:

1)Activities 使用相同的 SharedPReference 文件,方法是在您的应用程序中创建一个 public constant 来保存文件名。

public final static String PREFERENCE_NAME = "com.example.mypackage.preference"

2)Activities 都使用相同的SharedPReference 文件,如下所示

SharedPreferences lockPreferences = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);

3)确保在其他文件尝试读取之前提交您的编辑。

lockPreferences.putBoolean(CONSTANT_KEY, true);
commit();

【讨论】:

  • 感谢您的帮助,我添加了一个公共常量,但它仍然无法正常工作
  • 别说不行。总是说出你遇到的异常或你有问题的行。如果您使用我正确提到的首选项,则不会有任何问题
  • 也不例外,因此证明很难解决问题...我在上面进行了编辑以显示我的测试
  • 不要问我是如何清理项目的,并且在添加公共常量后它现在可以工作了......感谢所有
  • 如果您使用的是 Eclipse,我相信您 :)。 @Gary 如果您发现我的回答有用,请不要忘记投票 :) thnx
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-20
  • 1970-01-01
相关资源
最近更新 更多