Broadcast receiver not affecting shared preferences in Android 4.0 (probably 3.1+)

。_饼干妹妹 提交于 2019-12-22 17:36:13

问题


So I have indeed searched thoroughly for an answer to my question; normally I can find answers pretty easily to pretty much anything.

Anyway, basically I have an alarm manager set up which eventually sets a broadcast receiver. Inside the receiver, it decides which intent has been received, removes a shared preference, and then sets a notification that starts the activity. The problem is that on my phones with 4.0 the shared preference item is not successfully deleted, but on any previous phones I've tried (2.2, 2.3) it works perfectly.

I did end up finding the documentation of Android 3.1 and the FLAG_INCLUDE_STOPPED_PACKAGES implementation. I tried throwing that onto the intent, just in case, but it still wasn't working. Either way, it's not the launching of the activity that is the problem, but the simple deletion of a shared preference.

I hope that's clear enough! I'll put in some of the code below.

This is where the intent is started:

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();

And then the broadcast receiver 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);
    }

So, as I mentioned before, on my devices on 4.0 (I don't have any 3.X devices) the

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

part isn't working. The activity will open correctly, but the "AlertTime1" is still there. On the 2.2 and 2.3 devices, the "AlertTime1" is successfully deleted.

sigh :D

Thanks for any help!!

Oh, and in case it's needed, here is my manifest for the receiver:

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

This is where the difference shows:

    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);
    }

On my older phones, it correctly resets to saying "No Alert Set" but on the 4.0 phones it still shows "0" days left (which is what it says since I'm only setting the alert to 5 minutes or so for testing). Basically, the user can't set a new alert because it hasn't reset correctly, and again, only on the 4.0 phones I'm trying :P


回答1:


Use Context.MODE_MULTI_PROCESS as the 2nd parameter to getSharedPreferences(). The problem is that you have the broadcast receiver running in a separate process from your activities, and as of Android 3.0 the default behaviour of multi-process access to shared preferences has changed. This should fix the problem for you on 4.x devices.

However, there is a bug in Android 2.3 which causes simultaneous access to shared preferences from multiple processes not to work reliably in some cases. We came across this and were very frustrated by it because it is difficult to reproduce and explain (probably some kind of timing issue).




回答2:


What I ended up doing was just having a check in the activity itself that says "if the alarm time is less than 0, delete the alarm time." It was a work around; I didn't receive any other answer that worked unfortunately.




回答3:


you should delete android:process=":remote" attribute in your receiver in the manifest. SharedPreferences does not work with new processes and :remote declares "do whatever the process id is ".




回答4:


I know this is an old question but maybe my answer will be helpful for others who facing this problem this days. I just found a solution and it worked for me.

make a service and implement the work you want on it, and then just call the service from your broadcast receiver, which means the only work of your receiver is to call the service which will handle the work you want to do.




回答5:


The simply answer is this: don't bother doing so much in a receiver. Instead, kick of an intent call to another Activity in the same package hierarchy and you'll be able to do it just as easily.



来源:https://stackoverflow.com/questions/10465318/broadcast-receiver-not-affecting-shared-preferences-in-android-4-0-probably-3-1

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!