【问题标题】:Shared Preferences are not being read correctly in a BroadcastReceiver未在 BroadcastReceiver 中正确读取共享首选项
【发布时间】:2012-01-08 00:59:00
【问题描述】:

我是安卓开发新手。我有一个问题,SharedPreferences 没有在 BroadcastReceiver 中被读取

背景:
我正在尝试编写一个没有 GUI 的 Android 应用程序。该应用程序每次都会做一些工作 单击应用程序图标,将设置写入共享首选项,在未来设置 3 秒钟的警报,然后退出(完成())。应用程序图标将快速连续单击 3 或 4 次。 BroadcastReceiver 和 Shared Preferences 可以让我跟踪它被点击的次数、最后一次点击的时间以及其他一些设置。

我在清单中用来抑制 GUI 的设置是

android:theme="@android:style/Theme.NoDisplay"

有3个文件

  1. 清单文件
  2. 我的主要活动文件 MyFirstTestActivity.java
  3. 我的广播接收器类 MyReceiver.java

当我快速连续多次单击应用程序图标时。 MyFirstTestActivity 类正确读取共享首选项“计数”设置并正确递增。 它设置警报并传递一个名为“CurrentCount”的额外数据 在我的广播接收器中,当我读取共享首选项和传递的额外数据时,它被卡在 1 处,它不会正确增加。

我试图通过比较的值在 MyReceiver.onReceive 中实现
传入的“Count” Shared Preference 和“CurrentCount” Intent extra 设置是同一个值 我会知道用户已经连续快速停止点击然后我可以向用户显示消息,而不是每次都显示消息它被称为。

下面是 Eclipse LogCat 日志的一部分

11-288 09:43:10.652:I/UpdateSettings(782):从首选项中读取计数值 -7
11-28 09:43:10.712:I/UpdateSettings(782):从首选项中回读计数 - 8

11-28 09:43:10.892: W/InputManagerService(112): 窗口已经聚焦,忽略焦点增益:com.android.internal.view.IInputMethodClient$Stub$Proxy@415ef6a8
11-28 09:43:11.012: W/NetworkManagementSocketTagger(112): setKernelCountSet(10040, 0) 失败,错误号 -2
11-28 09:43:13.772: I/MyReceiver(797): 测试
11-28 09:43:13.782:I/MyReceiver(797):首选项包含字段计数
11-28 09:43:13.792: I/MyReceiver(797): count=1
11-28 09:43:13.792: I/MyReceiver(797): currentCount=1

11-28 09:43:36.162: I/ActivityManager(112): 开始 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.mywebsite.myfirsttest/。 MyFirstTestActivity} 来自 pid 212
11-28 09:43:36.162: W/WindowManager(112): (180x300) 到 21005 层的屏幕截图失败 11-28 09:43:36.212: W/NetworkManagementSocketTagger(112): setKernelCountSet(10040, 1) 失败,错误号 -2
11-28 09:43:36.272: I/UpdateSettings(782): 读取首选项中的计数值 -8
11-28 09:43:36.362:I/UpdateSettings(782):从首选项中回读计数 - 9

11-28 09:43:36.583: W/InputManagerService(112): 窗口已经聚焦,忽略焦点增益:com.android.internal.view.IInputMethodClient$Stub$Proxy@41640fa8
11-28 09:43:36.653: W/NetworkManagementSocketTagger(112): setKernelCountSet(10040, 0) 失败,错误号 -2
11-28 09:43:39.402: I/MyReceiver(797): 测试
11-28 09:43:39.412: I/MyReceiver(797): Preferences 包含字段 Count
11-28 09:43:39.412: I/MyReceiver(797): count=1
11-28 09:43:39.412: I/MyReceiver(797): currentCount=1

11-28 09:44:27.072: D/dalvikvm(196): GC_CONCURRENT 释放 398K,6% 释放 10399K/10951K,暂停 5ms+4ms
11-28 09:47:46.312: W/ThrottleService(112): 无法找到 iface rmnet0 的统计数据

带有 UpdateSettings 标签的日志显示为正确更新 带有 MyReceiver 标签的日志没有正确读取最新的共享偏好值(或意图额外数据)

这是我的 2 个源文件 MyFirstTestActivity.java

public class MyFirstTestActivity extends Activity {

    public static final String MY_PREFS = "TestPrefs";

    /** Called when the activity is first created. */
        @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Note: This application has no display 
        // See the manifest @android:style/Theme.NoDisplay"

        //Toast.makeText(this,"in onCreate", Toast.LENGTH_SHORT).show();

        // Increment the count shared setting 
        int count = updateSharedPreferenceSettings();
        // Send the alarm
        setMessageAlarm(count);
        // Exit the application
        finish();

    }


    private int updateSharedPreferenceSettings() {
        SharedPreferences prefs = this.getSharedPreferences(MyFirstTestActivity.MY_PREFS, Context.MODE_WORLD_READABLE);


        int count = 1;
        if(prefs.contains("Count")) {
            count = prefs.getInt("Count", 1);
            Log.i("UpdateSettings", "Read Value of Count from Preferences -" +     String.valueOf(count));
            count = count+1;
        }

        Editor editor = prefs.edit();
        editor.putInt("Count", count);
        editor.commit();
        Log.i("UpdateSettings", "Read Back Count from Preferences - " +             prefs.getInt("Count", 0));

        return count;
    }

   private void setMessageAlarm(int currentCount) {
       Intent intent = new Intent(MyFirstTestActivity.this, MyReceiver.class);
       intent.putExtra("CurrentCount", currentCount);

       PendingIntent appIntent = 
            PendingIntent.getBroadcast(MyFirstTestActivity.this, 0, intent, 0);


       Calendar c = Calendar.getInstance();
       c.setTimeInMillis(System.currentTimeMillis());
       c.add(Calendar.SECOND, 3);

       // Set the alarm for 3 seconds in the future
       AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
       am.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), appIntent); 
   }
}

我的接收器源文件 MyReceiver.java

    public class MyReceiver extends BroadcastReceiver {


    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("MyReceiver", "Test");

        SharedPreferences prefs =     context.getSharedPreferences(MyFirstTestActivity.MY_PREFS, Context.MODE_WORLD_READABLE);
        if(prefs.contains("Count")) {
        Log.i("MyReceiver", "Preferences Contains the field Count");

        int count = prefs.getInt("Count", -2);
            Log.i("MyReceiver", "count=" + String.valueOf(count));

            int currentCount = intent.getIntExtra("CurrentCount", -3);
            Log.i("MyReceiver", "currentCount=" + String.valueOf(currentCount));    
    }
        else {
            Log.i("MyReceiver", "Preferences Does NOT Contains the field Count");
            }

}

}

我的清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mywebsite.myfirsttest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="14" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name="com.mywebsite.myfirsttest.MyFirstTestActivity"
            android:theme="@android:style/Theme.NoDisplay"
             >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver  android:name="com.mywebsite.myfirsttest.MyReceiver" android:process=":remote"></receiver>
    </application>

</manifest>

为什么 MyReceiver.java 没有获取最后一个 SharedPreferences,而是在第一次设置警报时卡住了该值? 使用传入MyReceiver的Context合适吗?

【问题讨论】:

  • 我认为你从来没有深究过这个?! :)
  • 你解决过这个问题吗?

标签: android broadcastreceiver sharedpreferences alarmmanager


【解决方案1】:

我有一些关于你的代码的问题.....

  1. 我在清单或活动中没有看到任何广播接收器的意图过滤器。

  2. 你应该写

    SharedPreferences.Editor editor = prefs.edit();
    

updateSharedPreferenceSettings() 方法中将其保存在 SharedPreferences 中。

【讨论】:

    【解决方案2】:

    我在这种情况下遇到了类似的问题:从 BroadcastReceiver 读取 SharedPreferences

    简单的答案是:不要费心在接收器中做太多事情。相反,启动对同一包层次结构中的另一个 Activity 的意图调用,您将能够同样轻松地做到这一点。

    【讨论】:

    • 这不是简单的答案,根本不是答案
    猜你喜欢
    • 1970-01-01
    • 2020-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    • 1970-01-01
    相关资源
    最近更新 更多