I have an app that needs to reset its text fields and other views everyday. Its like a daily tasks that remain constant but the progress has to be reset everyday or at 12am
That a really easy task to implement using AlarmManager.
Following this guide it should be easy for you.
Example:
//define your intent
AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
PedingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
// Set the alarm to start at approximately 00:00 h(24h format).
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 00);
//repeteat alarm every 24hours
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
Now create a BroadcastReceiver called "AlarmReceiver" and inside it, do whatever you want to.
public class AlarmReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
//do whatever you want.
}
}
Maybe you should use a WakefulBroadcastReceiver depending of your task.
Related
I want a task to do which require internet connection and it's must scheduled once in a day. I achieve above task partially using alarm manager like below.
Calendar c = Calendar.getInstance(); //gives u calendar with current time
c.add(Calendar.SECOND, 30);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intent, 0);
if (alarmManager != null) {
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
}
// my broadcast receiver
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//my task will be here
// for now I planned to check internet here and if it has i'll continue the task
}
}
//in manifest
<receiver android:name=".broadcast_receiver.AlarmReceiver" />
Is there any way to postpone above task in same day whenever got internet connection?
Can AlarmManager be used to achieve above requirement?
You can achieve that with WorkManager. Check out the official docs for more info.
I am trying to set an alarm within the Fragment.
AlarmManager manager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(getActivity(), AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getService(getActivity(), 0, alarmIntent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 19);
calendar.set(Calendar.MINUTE, 23);
manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 3600, pendingIntent);
And my AlarmReceiver class is:
public class AlarmReceiver extends BroadcastReceiver {
private static final String TAG = "MainFragment";
#Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "onReceive");
Toast.makeText(context, "I'm running", Toast.LENGTH_LONG).show();
}
}
This log and toast are never shown.
In my AndroidManifest i have put
<receiver android:name=".AlarmReceiver"
android:enabled="true"
android:exported="true"></receiver>
Am I missing something? This is my first project in Android so its probably some rookie mistake.
Here is example which is working TESTED:
AlarmManager manager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(this.getApplicationContext(), AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 30);
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 3600, pendingIntent);
If it doesn't work I can send you the working project I made.
You're using PendingIntent.getService(...), rather than the BroadcastReceiver equivalent, PendingIntent.getBroadcast(...). Which is likely the issue.
Make sure that if you set the alarm once (like on App first launch) and while waiting you make some changes in the code and install the App again your pending intent not active anymore, so you need to set the alarm again.
I have a code in which alarm manager starts a service. I have to cancel it with the specified time using a second alarm. Not a single solution that I've looked at works. My code is as follows:
void startAtInterval(int fromTime, int fromTimeMinute, int toTime, int toTimeMinute, int id1, int id2) {
// start alarm
AlarmManager alarmMgr = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
PendingIntent alarmIntent = PendingIntent.getService(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, fromTime);
calendar.set(Calendar.MINUTE, fromTimeMinute);
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
// stop alarm
AlarmManager alarmMgr1 = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
PendingIntent alarmIntent1 = PendingIntent.getService(getApplicationContext(), 1, intent, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar calendar1 = Calendar.getInstance();
calendar1.setTimeInMillis(System.currentTimeMillis());
calendar1.set(Calendar.HOUR_OF_DAY, toTime);
calendar1.set(Calendar.MINUTE, toTimeMinute);
alarmMgr1.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar1.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent1);
stopService(intent);
alarmMgr1.cancel(alarmIntent1);
}
I used FLAG_UPDATE_CURRENT and FLAG_CANCEL_CURRENT. I also tried to stopservice as I show in my code. I'm passing time from a configuration screen. I know it works because first alarm is always fired.
You should have the second alarm which cancels the service fire a BroadcastReceiver which then stops the service. This will ensure that the alarm will successfully stop the service under any circumstances, such as the app being closed.
AlarmManager alarmMgr1 = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
Intent intentCancelService= new Intent(getApplicationContext(), StopServiceReceiver.class);
PendingIntent alarmIntent1 = PendingIntent.getBroadcast(getApplicationContext(), StopServiceReceiver.REQUEST_CODE, intentCancelService, PendingIntent.GoTestAlarmReceiver);
Calendar calendar1 = Calendar.getInstance();
calendar1.setTimeInMillis(System.currentTimeMillis());
calendar1.set(Calendar.HOUR_OF_DAY, toTime);
calendar1.set(Calendar.MINUTE, toTimeMinute);
alarmMgr1.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar1.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent1);
Then make your BroadcastReceiver:
public class GoTestAlarmReceiver extends BroadcastReceiver {
public static final int REQUEST_CODE = 123123; //whatever code just unique
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, YourServiceClassHere.class);
context.stopService(i);
}
}
Make sure to declare the receiver in your manifest:
<receiver
android:name=".StopServiceReceiver"
android:enabled="true"
android:process=":remote" />
To stop any alarm manager you have to use this:
Intent intentS = new Intent(ctx,YourService.class);
intentS.addCategory("SOMESTRING_AS_TAG");
PendingIntent senderS = PendingIntent.getService(ctx, NDX, intentS, PendingIntent.FLAG_CANCEL_CURRENT);
am.cancel(senderS);
senderS.cancel();
//and this
PendingIntent senderSNew = PendingIntent.getService(ctx, NDX, intentS, 0);
am.cancel(senderSNew);
senderSNew.cancel();
where NDX is the same as started. That is 0 in your case. Or, much better, change your NDX to a some random contant number.
to stop:
Intent intent = new Intent(ctx,YourService.class);
intent.addCategory("SOMESTRING_AS_TAG");
ctx.stopService(intent);
Alarm manager in my app does not work. I do everything like described here
https://developer.android.com/training/scheduling/alarms.html
but the alarm does not work.
Here is my code:
manifest
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
Reciever (Reciever registered in the Manifest)
#Override
public void onReceive(Context context, Intent intent) {
Intent alarmIntent = new Intent(Constants.ALARM_INTENT);
alarmIntent.setClass(context, NotificationActivity.class);
alarmIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(alarmIntent);
}
Activity
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 1);
calendar.set(Calendar.MINUTE, 30);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
I do not know how to make it work. Please, help me to fix it.
First, remove the SET_ALARM permission, as it is not relevant here.
Second, you need to ensure that your Calendar object is in the future. Most of the time, yours will be in the past, because you are using calendar.set(Calendar.HOUR_OF_DAY, 1) and set(Calendar.MINUTE, 30). If you execute this code after 01:30, it will be in the past. In that case, you need to add() one day to make it be tomorrow at 01:30.
Third, use adb shell dumpsys alarm to see if your alarm is scheduled, once you make the above fixes.
Fourth, use LogCat to see if there are any warnings or errors coming from your code, such as perhaps AlarmReceiver or NotificationActivity not being registered in the manifest.
You're asking for an alarm based on the system's elapsed realtime clock here:
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
But you're passing it a time based on a normal calendar clock. If you want an alarm to happen using a calendar-based clock, say this instead:
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
Note the differnce in javadoc between ELAPSED_REALTIME_WAKEUP and RTC_WAKEUP.
I followed the instructions in this thread to create a daily alarm that starts a service at 12:30 each day which shows a notification. The problem I'm having is that setting the alarm also triggers the service (=> and the notification) every time the app starts.
Since I figured that the alarm will run only at the specified time (12:30) then I have no problem setting it when the app starts.
I realize that setting the alarm from scratch every time the app is launched is a bit ineffective since it only needs to be set once (I made it set on device boot as well), but it seemed like the easiest way.
So what's the best way to fix this? is there a way to set the alarm for the specified time without running the intent when setting?
Here's the code if you are interested (this function is called every time when launching the app):
public static void setAlarm(Context context)
{
Intent intent = new Intent(context, AlarmReceiver.class);
intent.setAction("com.Rani.app.SET_NOTIFICATION_ALARM");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar dailyCheckTime = Calendar.getInstance();
dailyCheckTime.setTimeZone(TimeZone.getTimeZone("GMT"));
dailyCheckTime.set(Calendar.HOUR_OF_DAY, 12);
dailyCheckTime.set(Calendar.MINUTE, 30);
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pendingIntent);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, dailyCheckTime.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
}
thanks in advance.
After trying several things, I used the information in this thread to preform a check if an alarm already exists, and setting one only if there isn't one already.
code:
public static void setAlarm(Context context)
{
Intent intent = new Intent(context, AlarmReceiver.class);
intent.setAction("com.Rani.app.SET_NOTIFICATION_ALARM");
boolean alarmUp = (PendingIntent.getBroadcast(context,
0, intent, PendingIntent.FLAG_NO_CREATE) != null);
// check if an alarm already exists
if (alarmUp == false)
{
// set an alarm in case there isnt one already set
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar dailyCheckTime = Calendar.getInstance();
dailyCheckTime.set(Calendar.HOUR_OF_DAY, 12);
dailyCheckTime.set(Calendar.MINUTE, 30);
if (dailyCheckTime.getTimeInMillis() < Calendar.getInstance()
.getTimeInMillis()) {
dailyCheckTime.set(Calendar.DATE,
dailyCheckTime.get(Calendar.DATE) + 1);
}
AlarmManager alarm = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pendingIntent);
alarm.setRepeating(AlarmManager.RTC_WAKEUP,
dailyCheckTime.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
}
}