Edit shared preferences using repeating alarm - java

I am trying to change one key of the shared preferences file at the end of the day. So here is what I managed to find on the internet:
boolean alarmUp = (PendingIntent.getBroadcast(this, 0,
new Intent(this, AlarmResetFoodAdded.class),
PendingIntent.FLAG_NO_CREATE) != null);
if (!alarmUp) {
setAlarm();
}
Function setAlarm():
private void setAlarm() {
alarmMgr = (AlarmManager)this.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmResetFoodAdded.class);
alarmIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 14);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
}
AlarmResetFoodAdded.java:
#Override
public void onReceive(Context context, Intent intent)
{
pref = context.getSharedPreferences(AppControl.PREF, Activity.MODE_PRIVATE);
prefEditor = pref.edit();
prefEditor.putInt("foodAdded", 0);
prefEditor.commit();
}
I am testing this using the device simulator with API 28. I tried to set the time to about 13:59. Then I'd wait until about 14:01 because it is inExactRepeating, but the key foodAdded in the preferences file stay the same, even when I reopen the app.
I'm pretty sure the alarm is up because when I debug alarmUp, the value is false the first time, then when I reopen it, it is true.

I think you should use prefEditor.apply(); instead of prefEditor.commit(); in your onReceive method.

Related

setRepeating() function is not workingproperly (AlarmManger Android)

I was using setRepeating() function to schedule events in my Application. According to Android documentation setRepeating() is not exact from API level 19+.In the app, when it is time to alarm (every day at 23:59) broadcast receiver is called. However, this broadcast receiver is being called too early(ex: sometimes it is being called right after I set the alarm although there are more than 10 hours until 23:00)
Here is my code:
set Alarm function:
public void setEmaResetAlarm(Context context) {
alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManagerMorning = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
intentResetNight = new Intent(context, EMAAlarmRcvr.class);
intentResetNight.putExtra("ema_reset_night", true); //time to reset EMA to 0
intentResetMorning = new Intent(context, EMAAlarmRcvr.class);
intentResetMorning.putExtra("ema_reset_morning", true); //time to reset EMA to 0
intentRemove = new Intent(context, EmaDismissReceiver.class);
intentRemove.putExtra("ema_pop_up_remove", true); // time to remove EMA pop up
pendingIntentResetNight = PendingIntent.getBroadcast(context, 10, intentResetNight, PendingIntent.FLAG_UPDATE_CURRENT);
pendingIntentResetMorning = PendingIntent.getBroadcast(context, 8, intentResetMorning, PendingIntent.FLAG_UPDATE_CURRENT);
pendingIntentRemove = PendingIntent.getBroadcast(context, 11, intentRemove, PendingIntent.FLAG_UPDATE_CURRENT);
if (alarmManager == null || alarmManagerMorning == null)
return;
emaTimeSubscription = context.getSharedPreferences("SubscriptionCheck", Context.MODE_PRIVATE);
int hour1 = Integer.parseInt(emaTimeSubscription.getString("hours1", null));
int hour2 = Integer.parseInt(emaTimeSubscription.getString("hours2", null));
int hour3 = Integer.parseInt(emaTimeSubscription.getString("hours3", null));
Calendar firingCallReset = Calendar.getInstance();
firingCallReset.set(Calendar.HOUR_OF_DAY, 23); // at 11:59pm
firingCallReset.set(Calendar.MINUTE, 59); // Particular minute
firingCallReset.set(Calendar.SECOND, 0); // particular second
firingCallReset.set(Calendar.MILLISECOND, 0); // particular second
//alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, firingCallReset.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntentResetNight);
Calendar firingCalResetMorning = Calendar.getInstance();
firingCalResetMorning.set(Calendar.HOUR_OF_DAY, 9); // at 9:30am
firingCalResetMorning.set(Calendar.MINUTE, 30); // Particular minute
firingCalResetMorning.set(Calendar.SECOND, 0); // particular second
firingCalResetMorning.set(Calendar.MILLISECOND, 0); // particular second
//alarmManagerMorning.setRepeating(AlarmManager.RTC_WAKEUP, firingCalResetMorning.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntentResetMorning);
//remove EMA pop up
Calendar firingCalRemove11 = Calendar.getInstance();
firingCalRemove11.set(Calendar.HOUR_OF_DAY, hour1 + 1); // at 11:01am
firingCalRemove11.set(Calendar.MINUTE, 1); // Particular minute
firingCalRemove11.set(Calendar.SECOND, 0); // particular second
firingCalRemove11.set(Calendar.MILLISECOND, 0); // particular second
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, firingCalRemove11.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntentRemove);
Calendar firingCalRemove15 = Calendar.getInstance();
firingCalRemove15.set(Calendar.HOUR_OF_DAY, hour2 + 1); // at 3:01pm
firingCalRemove15.set(Calendar.MINUTE, 1); // Particular minute
firingCalRemove15.set(Calendar.SECOND, 0); // particular second
firingCalRemove15.set(Calendar.MILLISECOND, 0); // particular second
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, firingCalRemove15.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntentRemove);
Calendar firingCalRemove19 = Calendar.getInstance();
firingCalRemove19.set(Calendar.HOUR_OF_DAY, hour3 + 1); // at 7:01pm
firingCalRemove19.set(Calendar.MINUTE, 1); // Particular minute
firingCalRemove19.set(Calendar.SECOND, 0); // particular second
firingCalRemove19.set(Calendar.MILLISECOND, 0); // particular second
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, firingCalRemove19.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntentRemove);
}
BroadcastReceiver to be called:
public class EMAAlarmRcvr extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
SharedPreferences loginPrefs = context.getSharedPreferences("UserLogin", MODE_PRIVATE);
SharedPreferences configPrefs = context.getSharedPreferences("Rewards", MODE_PRIVATE);
//For resetting ema prefr (11:59 PM ) and (9:30 AM )
if (intent.getBooleanExtra("ema_reset_night", false) || intent.getBooleanExtra("ema_reset_morning", false)) {
SharedPreferences.Editor ema_editor = configPrefs.edit();
SharedPreferences.Editor hrm_editor = configPrefs.edit();
Log.e("TAG", "onReceive: TaskManager" );
hrm_editor.putBoolean("hrm_completed", false);
hrm_editor.apply();
ema_editor.putBoolean("ema1_answered", false);
ema_editor.putBoolean("ema2_answered", false);
ema_editor.putBoolean("ema3_answered", false);
ema_editor.putInt("ema_answered_count", 0);
ema_editor.apply();
SharedPreferences.Editor loginEditor = loginPrefs.edit();
loginEditor.putBoolean("ema_btn_make_visible", false);
loginEditor.apply();
}
}
}
Before setting a new alarm you should cancel any previous alarms as:
alarmManager.cancel(pendingIntent);
Also, use same pending intent that you use to create a new alarm to cancel old set one because is used as unique identifier, so:
// cancel old alarm
alarmManager.cancel(pendingIntentRemove);
// then create new one
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, firingCalRemove11.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntentRemove);
You get called at random times because is created a new alarm

Alarm Manager is repeating more than once a day when using AlarmManager.INTERVAL_DAY

MainActivity.java
Intent intent = new Intent(this, AlarmReceiver24.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
AlarmManager alarmMgr = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY,1);
calendar.set(Calendar.MINUTE, 50);
calendar.set(Calendar.SECOND, 0);
String time= String.valueOf(calendar.getTime());
Log.i("Time:",time);
//repeat alarm every 24hours
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY, alarmIntent);
AlarmReceiver class
public class AlarmReceiver24 extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
reference.child("Total").setValue(0);
Toast.makeText(context, "Total Reset", Toast.LENGTH_SHORT).show();
}
}
Android Manifest
<receiver android:name=".AlarmReceiver24"/>
I want the code to run at midnight 12:00:00 once everyday but it keeps firing again and again even after using AlarmManager.INTERVAL_DAY. I don't know what I'm doing wrong.
Each time you opens MainActivity it creates a new PendingIntent
When you start MainActivity you should remove all previously scheduled alarms.
Also
calendar.set(Calendar.HOUR_OF_DAY, 1);
calendar.set(Calendar.MINUTE, 50);
calendar.set(Calendar.SECOND, 0);
is not midnight.
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
is midnight
The Alarm was getting set in past so added this condition and it was solved
if(calendar.before(Calendar.getInstance()))
calendar.add(Calendar.DATE,1);

Android notification repeats several times at event instead of one time

I want the code to execute a notification once every day at 07 am. I created a debug apk and installed it to see how it performs and noticed, that it actually sends a notification at about 07 am, but if you click on the notification and get into the app and close it afterwars, it sends a notification again. Does someone see a mistake in the code?
this is the code in the MainActivity.java (the notification part):
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent_anmeldeActivity = new Intent(this, anmeldeActivity.class);
intent_WebViewActivity = new Intent(this, WebViewActivity.class);
prefs = getSharedPreferences("prefs", Context.MODE_PRIVATE);
prefsEditor = prefs.edit();
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 07);
calendar.set(Calendar.MINUTE, 00);
calendar.set(Calendar.SECOND, 00);
intent_notification = new Intent(this, NotificationClass.class);
Intent intent1 = new Intent(MainActivity.this, NotificationClass.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) MainActivity.this.getSystemService(MainActivity.this.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
Also it sends notifications kind of randomly.
Thanks in advance!
EDIT:
public class NotificationClass extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
loadText loadText = new loadText();
loadText.startAsyncTask(context);
} }
In AsyncTask class loadText, the class NotificationBuilding is executed in onPostExecute:
public class NotificationBuilding {
Context mContext = null;
int ID = 1;
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
long when = System.currentTimeMillis();
public void startNotificationBuilding(Context con, String title, String text) {
this.mContext = con;
NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(mContext, MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mNotifyBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(
mContext)
.setSmallIcon(R.drawable.ic_stat_name)
.setColor(Color.argb(255, 234, 146, 21))
.setContentTitle(title)
.setContentText(text)
.setSound(alarmSound)
.setAutoCancel(true)
.setWhen(when)
.setContentIntent(pendingIntent)
.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000})
.setLights(Color.argb(255, 234, 146, 21), 1000, 10000)
.setStyle(new NotificationCompat.BigTextStyle().bigText(text));
notificationManager.notify(ID, mNotifyBuilder.build());
ID++;
} }
// Set the alarm to start at approximately 7:00 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 07);
// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr.**setInexactRepeating**(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
Decide how precise your alarm needs to be
As described above, choosing the alarm type is often the first step in creating an alarm. A further distinction is how precise you need your alarm to be. For most apps, setInexactRepeating() is the right choice. When you use this method, Android synchronizes multiple inexact repeating alarms and fires them at the same time. This reduces the drain on the battery.
For the rare app that has rigid time requirements—for example, the alarm needs to fire precisely at 8:30 a.m., and every hour on the hour thereafter—use setRepeating(). But you should avoid using exact alarms if possible.
With setInexactRepeating(), you can't specify a custom interval the way you can with setRepeating(). You have to use one of the interval constants, such as INTERVAL_FIFTEEN_MINUTES, INTERVAL_DAY, and so on. See AlarmManager for the complete list.

Having problems with "snoozing" alarm

Does anyone know how to do snooze function and where I am going wrong?
My default snooze time is 5 minutes. It worked fine until restart the
application and then does not work again.
If I clear the cache and data its works again.
public void onClick(View view) {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
int iSnoozeLeft = settings.getInt(PuzzleAlarm.SNOOZE_LEFT, 1);
if (iSnoozeLeft != 0) {
Intent activate = new Intent(AlarmNotification.this, AlarmReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(AlarmNotification.this, 0, activate, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
int iMinutes = Preferences.getSnooze(settings, AlarmNotification.this);
Calendar calendar = Calendar.getInstance();
calendar.roll(Calendar.MINUTE, iMinutes);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), alarmIntent);
SharedPreferences.Editor editor = settings.edit();
editor.putInt(PuzzleAlarm.SNOOZE_LEFT, iSnoozeLeft - 1); // disabling
// Commit the edits!
editor.commit();
}`
PendingIntent.getBroadcast(AlarmNotification.this, 0, activate, 0);
Make sure you aren't using "0" for your other alarm ID. In other case your "snooze" code will overwrite that previous alarm.

Code not working. Notification that should go off once a day

So I don't know why this code is not working. I wanted to make an "alarm" notification that would go off once a day. Just wanted to say im new to android. Thanks.
Edit: Changed up the code a bit. Alarm method executes and the notification does too, but I get this error message:
-248/? D/PowerManagerService﹕ releaseWakeLock flags=0x1 tag=AlarmManager W/ActivityManager﹕ Unable to start service Intent { flg=0x4 cmp=com.example.polakken.test/.lol (has extras) }: not found 06-13 00:00:00.825 231-267/? D/PowerManagerService﹕ acquireWakeLock flags=0x1 tag=AlarmManager 06-13 00:00:00.825 231-248/? D/PowerManagerService﹕ releaseWakeLock flags=0x1 tag=AlarmManager –
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = preferences.edit();
int i = preferences.getInt("numberoflaunches", 1);
if (i < 2) {
alarmMethod();
i++;
editor.putInt("numberoflaunches", i);
editor.commit();
}
if (savedInstanceState == null) {
splashMethod();
}
}
//...
private void alarmMethod() {
Intent intentbro = new Intent(this, lol.class);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, intentbro, 0);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.AM_PM, Calendar.AM);
calendar.add(Calendar.DAY_OF_MONTH, 1);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 60 * 24, pendingIntent);
Toast.makeText(MainActivity.this, "start alarm", Toast.LENGTH_LONG).show();
}
//notification class
public class lol extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
NotificationCompat.Builder b = new NotificationCompat.Builder(this);
Intent intent1 = new Intent(this.getApplicationContext(), MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 1, intent1, 0);
b.setContentText("lol");
b.setContentTitle("Default notification");
b.setSmallIcon(R.drawable.iconography_small_size);
b.setContentIntent(pIntent);
NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, b.build());
}
}
You are adding an extra day to your alarm. It should look like this:
...
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.HOUR_OF_DAY, 1);
calendar.set(Calendar.AM_PM, Calendar.AM);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
...
You are calling PendingIntent pendingIntent = PendingIntent.getService(this, 0, intentbro, 0);
However, you need to declare this Service in your AndroidManifest like this:
<service android:name=".Lol" />
Also, classes in Java should be capitalized, but your Intent calls a lower-case class:
Intent intentbro = new Intent(this, lol.class);
I suggest you run static analysis on your code to see how to improve it!

Categories