广播接收器不影响Android 4.0中的共享首选项(可能是3.1+)

时间:2012-05-05 19:36:47

标签: android broadcastreceiver sharedpreferences

所以我确实彻底搜寻了我的问题的答案;通常我几乎可以很容易地找到答案。

无论如何,基本上我有一个警报管理器设置,最终设置广播接收器。在接收器内部,它决定接收到哪个意图,删除共享首选项,然后设置启动活动的通知。问题是在我的4.0手机上没有成功删除共享首选项,但在我尝试过的任何以前的手机上(2.2,2.3),它都运行得很好。

我最终找到了Android 3.1和FLAG_INCLUDE_STOPPED_PACKAGES实现的文档。为了以防万一,我试着把它扔到意图上,但它仍然没有用。无论哪种方式,这不是启动活动的问题,而是简单删除共享偏好。

我希望这很清楚!我将在下面提供一些代码。

这是意图开始的地方:

Calendar cal = Calendar.getInstance();
int seconds = 5 * 60; // 1 * 24 * 60 * 60;
cal.add(Calendar.SECOND, seconds);

Intent intent = new Intent(SetAlertActivity.this, ReminderReceiver.class);
intent.putExtra("id", "FAlert");
//intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), FRAUD_ALERT_CODE, intent, 0);

AlarmManager alertManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alertManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);

settingsEditor = alertSettings.edit();
settingsEditor.putLong("AlertTime1", cal.getTimeInMillis());
settingsEditor.commit();

然后广播接收器onReceive():

    nContext = context;
    alertSettings = nContext.getSharedPreferences(MainActivity.PREFERENCE_FILENAME, 0);
    if (intent.getStringExtra("id").equals("FAlert"))
    {

        settingsEditor = alertSettings.edit();
        settingsEditor.remove("AlertTime1");
        settingsEditor.commit();

        String ns = Context.NOTIFICATION_SERVICE;
        int icon = R.drawable.ar_icon;
        CharSequence tickerText = nContext.getString(R.string.notification_ticker);
        CharSequence contentTitle = nContext.getString(R.string.notification_title);
        CharSequence contentText = nContext.getString(R.string.notification_text);
        long when = System.currentTimeMillis();

        NotificationManager mNotificationManager = (NotificationManager) nContext.getSystemService(ns);
        Notification notification = new Notification(icon, tickerText, when);

        Intent notificationIntent = new Intent(nContext, SetAlertActivity.class);
        PendingIntent contentIntent = PendingIntent.getActivity(nContext, 135, notificationIntent, 0);

        notification.defaults |= Notification.DEFAULT_SOUND;
        notification.defaults |= Notification.DEFAULT_LIGHTS;
        notification.flags |= Notification.FLAG_AUTO_CANCEL;
        notification.setLatestEventInfo(nContext, contentTitle, contentText, contentIntent);
        mNotificationManager.notify(NOTIFICATION_ID, notification);
    }

所以,正如我之前提到的,在4.0上的设备上(我没有任何3.X设备)

settingsEditor = alertSettings.edit();
settingsEditor.remove("AlertTime1");
settingsEditor.commit();

部分不起作用。活动将正确打开,但“AlertTime1”仍然存在。在2.2和2.3设备上,“AlertTime1”已成功删除。

叹息:D

感谢您的帮助!!

哦,如果需要,这是接收器的清单:

<receiver
    android:name="ReminderReceiver"
    android:process=":remote" >
</receiver>

这就是差异显示的地方:

    alertSettings = getSharedPreferences(AlertRenewActivity.PREFERENCE_FILENAME, 0);
    settingsEditor = alertSettings.edit();
    if (alertSettings.contains("AlertTime1"))
    {
        alertTime = alertSettings.getLong("AlertTime1", 0);
        timeLeft = (int) ((alertTime - System.currentTimeMillis()) / (1000L));
        daysLeft = timeLeft / (60 * 60 * 24);
        daysLeftView.setText(Integer.toString(daysLeft));
        setAlert.setEnabled(false);
        setAlert.setTextColor(R.color.dark_text);
    }
    else
    {
        daysLeftView.setText(R.string.no_alert_set);
    }

在我的旧手机上,它正确地重置为“无警报设置”,但在4.0手机上它仍显示“0”天(这就是它所说的,因为我只将警报设置为5分钟左右用于检测)。基本上,用户无法设置新警报,因为它没有正确重置,而且只能在我正在尝试的4.0手机上设置:P

5 个答案:

答案 0 :(得分:0)

使用Context.MODE_MULTI_PROCESS作为getSharedPreferences()的第二个参数。问题是您的广播接收器在与您的活动不同的进程中运行,并且从Android 3.0开始,多进程访问共享首选项的默认行为已更改。这应该可以解决4.x设备上的问题。

但是,Android 2.3中存在一个错误,导致多个进程同时访问共享首选项,在某些情况下无法可靠地工作。我们遇到过这种情况并且对此感到非常沮丧,因为它很难重现和解释(可能是某种时间问题)。

答案 1 :(得分:0)

我最终做的只是检查活动本身,“如果闹钟时间小于0,则删除闹钟时间。”这是一个解决方法;我没有收到任何其他不幸的答案。

答案 2 :(得分:0)

你应该删除android:process =&#34;:remote&#34;清单中接收器中的属性。 SharedPreferences不适用于新进程和:远程声明&#34;执行任何进程ID&#34;。

答案 3 :(得分:0)

我知道这是一个老问题,但也许我的回答对今天面临这个问题的其他人有帮助。 我刚刚找到了一个解决方案,它对我有用

提供服务并在其上实现您想要的工作,然后只需从您的广播接收器调用该服务,这意味着您的接收器的唯一工作就是调用将处理您想要的工作的服务。 / p>

答案 4 :(得分:-1)

简单的答案是:不要在接收器中做太多麻烦。相反,在相同的包层次结构中,将一个intent调用踢到另一个Activity,你就可以轻松地完成它。