I tried to use the setRepeating of AlarmManager, and then I read that the method isn't working anymore in API 26+, so the another solution was to schedule each alarm when the previous is finish. How can I do that?
MainActivity.java
public class MainActivity extends AppCompatActivity {
calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hour.getText().toString()));
calendar.set(Calendar.MINUTE, Integer.parseInt(minute.getText().toString()));
calendar.set(Calendar.SECOND, 00);
Intent intent = new Intent(getApplicationContext(), Notification_receiver.class);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
Notification_reciever.java
public class Notification_receiver extends BroadcastReceiver {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
Intent repeating_intent = new Intent(context, MainActivity.class);
repeating_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(context, time, repeating_intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setContentIntent(pendingIntent)
.setChannelId(CHANNEL_ID)
.setSmallIcon(R.drawable.ic_baseline_notifications_active_24)
.setContentTitle("Notification Title")
.setContentText("Notification Text")
.setAutoCancel(true);
notificationManager.notify(time, builder.build());
}
How can i create another alarm manager when the previous is finish?
You will need to schedule your next alarm, at the end of BroadcastReceiver
public class AlarmBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
...
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, nextAlarmTimeInMillis(), pendingIntent);
Please note that, due to different battery saving mechanism implemented by different OEMs, AlarmManager is not guarantee to work all the time. Please refer to https://issuetracker.google.com/issues/122098785
In short, AlarmManager is the current best available mechanism, for timed notification to work, even without Internet connection. But, it is not gurantee to work all the time.
Here is example to make alarm every 2 minutes (tested on API 30)
move code to set alarm from MainActivity in own class
public class AlarmExecutor {
public static void makeAlarm(Context context, int minute) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.MINUTE, minute);
Intent intent = new Intent(context, Notification_receiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
Log.d("Testing", "make alarm at " + calendar.getTime().toString());
}
}
now you can add in
Notification_receiver.java after notificationManager.notify(time, builder.build());
MainActivity
following line
// make alarm in 2 minutes
AlarmExecutor.makeAlarm(context, 2);
that will make an alarm every 2 minutes.
And don't forget to register the receiver in Manifest
<application >
<receiver android:name=".yourReceiver" />
</application>
Related
I want set the alarm at the specified time and implement the notification at the specified time(in a day) by using BroadcastReceiver and AlaramManager.
It alarmed specified time. After when I run the app, it again alarm even though it's not the time I set.
In other words, when I set the alarm 9:21 pm and I run the app after 9:21 pm, the notification is generated.
I just want to make the alarm notification at the specified time I set and app doesn't run.
Also, when I run the app, it doesn't alarm.
How can I fix it?
This is my BroadcastReceiver Code -
public class BroadcastD extends BroadcastReceiver{
Context context;
#Override
public void onReceive(Context context, Intent intent) {
this.context = context;
showNotification();
}
public void showNotification() {
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent pendingIntent = PendingIntent
.getActivity(context, 0, new Intent(context, MainActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setSmallIcon(android.R.drawable.ic_dialog_alert)
.setTicker("Ticket")
.setContentTitle("Title")
.setContentText("Context")
.setWhen(System.currentTimeMillis())
.setAutoCancel(true)
.setContentIntent(pendingIntent);
notificationManager.notify(1, builder.build());
}
}
This is my MainActivity code :
public class MainActivity extends AppCompatActivity {
AlarmManager am ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
am = (AlarmManager) getSystemService(ALARM_SERVICE);
AlarmHATT alarmHATT = new AlarmHATT(getApplicationContext());
alarmHATT.Alarm();
}
public class AlarmHATT {
private Context context;
public AlarmHATT(Context context) {
this.context = context;
}
public void Alarm() {
Intent intent = new Intent( context.getApplicationContext(), BroadcastD.class);
PendingIntent sender = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
calendar.get(Calendar.DATE), 21, 21, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 24*60*60*1000, sender);
}
}
To avoid having the alarm fire immediately, configure your start time with the Calendar like this:
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 30);
calendar.set(Calendar.SECOND, 0);
And then if the time you are setting has already passed today, you need to set the calendar to the following day with:
calendar.add(Calendar.DATE, 1);
That will avoid having your alarm fire immediately because it was set to a time that already passed earlier in the day.
Then continue to use calendar.getTimeInMillis() as your starting time.
Try below code to set alarm on a specified time.
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
Introduction:
Through a ToggleButton I make my user to enable or disable the alarm reminder. The alarm remember my user to record their activity one hour after the last time he has entered the app also do not want the alarm to sound at night. This all works fine.
public void each_hour_alarm() {
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
int hour = cal.get(Calendar.HOUR_OF_DAY);
if(hour <= 20 && hour >= 7) {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent notificationIntent = new Intent("android.media.action.DISPLAY_NOTIFICATION");
notificationIntent.addCategory("android.intent.category.DEFAULT");
PendingIntent broadcast = getBroadcast(getApplicationContext(), 100, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.HOUR, 1);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), broadcast);
stop_alarm_9am();
}else {
stop_each_hour_alarm();
alarm_9am();
}
}
The problem begins when I call a new method: alarm_9am();
The new method raises an alarm at 9 am if the user has not entered before the app. This is where I have the problem. The alarm sounds at 9am, but also, and this is my problem, it also sounds every time I log activity between 21h and 23: 59h.
I do not understand why this happens. Any ideas??
This is de code:
public void alarm_9am() {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent notificationIntent = new Intent("android.media.buenosdias.action.DISPLAY_NOTIFICATION");
notificationIntent.addCategory("android.intent.buenosdias.category.DEFAULT");
PendingIntent broadcast = getBroadcast(getApplicationContext(), 100, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 1);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), broadcast);}
Code to stop alarm_9am();
public void stop_alarm_9am() {
Intent intentlocal = new Intent("android.media.buenosdias.action.DISPLAY_NOTIFICATION");
intentlocal.addCategory("android.intent.buenosdias.category.DEFAULT");
PendingIntent pilocal = getBroadcast(getApplicationContext(), 100, intentlocal, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.cancel(pilocal);
pilocal.cancel();
}
And my AlarmReceiver;
public class AlarmReceiver_buenos_dias extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent notificationIntent = new Intent(context, v_agua.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(v_agua.class);
stackBuilder.addNextIntent(notificationIntent);
PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
Notification notification = builder.setContentTitle("Good Morning")
.setContentText("Begin New Day")
.setTicker("Go to app")
.setSmallIcon(R.drawable.logo_launcher_a)
.setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
.setStyle(new NotificationCompat.BigTextStyle().bigText(""))
.setAutoCancel(true)
.setContentIntent(pendingIntent).build();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notification);
}}
My issue is that the alarm sounds between 21h to 23:59 every time I enter in activity and i dont know why. I need not sound the alarm every time I log in activity between 21h and 23:59, I just want alarm_9am(); sounds at 9am
Thanks!
I'm making an app which uses an AlarmManager and a Broadcast Receiver to generate a notification everyday at 8:20 AM.
One issue which I'm facing is that every time I open the app after 8:20 AM, the notification is generated.
I guess this is because I have called the receiver in the onCreate() method.
Is there a way to make sure that the receiver is registered only once?
Here is my code :
public class MainActivity extends AppCompatActivity
{
AlarmManager alarmManager;
private PendingIntent alarmIntent;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 00);
calendar.set(Calendar.MINUTE,30);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent);
}
public class AlarmReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context,"Alarm Raised",Toast.LENGTH_SHORT).show();
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent1 = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
PendingIntent pendingIntent=PendingIntent.getActivity(context,0,intent1,0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setSmallIcon(R.drawable.ic_account_circle_black_18dp);
builder.setContentTitle("Tracker");
builder.setContentText("Turn on Gps");
builder.setPriority(Notification.PRIORITY_MAX);
builder.setDefaults(Notification.DEFAULT_SOUND);
builder.setLights(0x0000FF,3000,2000);
builder.setContentIntent(pendingIntent);
notificationManager.notify(56, builder.build());
}
}
The second parameter of setInexactRepeating indicates that when should the AlarmManager start its task. So if you give it a time in past it will fire once immediately. You must check if the calendar.getTimeInMillis() is before now and add a day to it if so.
So you should simply change this part of your code
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent);
to this:
long timeToStart = calendar.getTimeInMillis();
if(System.currentTimeMillis() < timeToStart){
timeToStart += 24 * 60 * 60 * 1000; // one day
}
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, timeToStart, AlarmManager.INTERVAL_DAY, alarmIntent);
Is there a way to detect when a day was started or date or time changes (not changed by user, it is changed by system). Any BroadCastReciever to do it? I am using service to run it by every hour, But drains battery.
My requirement is to check when the day has started (when time changes to 12 AM) or time changes (hourly) I want to display the notification.
Create alarm set on a specified time say 00 hours in your case, using AlarmManager and BroadcastReceiver. And you will receive a brodcast on every new day.
private void setAlarm(Calendar targetCal){
Intent intent = new Intent(getBaseContext(), AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), RQS_1, intent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, targetCal.getTimeInMillis(), pendingIntent);
}
For further reference :
http://android-er.blogspot.in/2012/05/create-alarm-set-on-specified-time.html
or you can use ScheduledExecutorService to schedule and execute a task http://developer.android.com/reference/java/util/concurrent/ScheduledExecutorService.html
This is quite simple to do.
Step 1
Use the AlarmManager to fire up a BroadcastReceiver periodically..
private void showNotification() {
Intent alarmIntent = new Intent(this, NotificationReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 50000, pendingIntent);
}
Step 2
In the onReceive() do the checking when the time is 00 hours of the day, create a notification and show it.
public class NotificationReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Calendar now = GregorianCalendar.getInstance();
// This is where you check when you want to show the notification
if(now.get(Calendar.HOUR_OF_DAY) == 0){
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(context.getResources().getString(R.string.message_box_title))
.setContentText(context.getResources().getString(R.string.message_timesheet_not_up_to_date));
Intent resultIntent = new Intent(context, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());
}
}
}
Step 3
Do forgot to register the custom BroadcastReceiver is Manifest
<receiver
android:name="com.example.NotificationReceiver"
android:process=":remote" />
I'm new to this, so I'm a bit lost.
I have built a notification and passed it to the alarm manager as a pendingIntent, however instead of waiting the interval to trigger the alarm and showing the notification, the notification is instantly shown.
What have I done wrong, that isn't allowing the alarm to be set properly?
public class NotificationController{
Context context;
public void createNotification(Context context){
this.context = context;
Notification notification = getNotification();
//creates notification
Intent intent = new Intent(context, NotificationReceiver.class);
intent.putExtra(NotificationReceiver.NOTIFICATION_ID, 1);
intent.putExtra(NotificationReceiver.NOTIFICATION, notification);
PendingIntent pIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
//schedules notification to be fired.
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 10000 , pIntent);
}
private Notification getNotification(){
Intent intent = new Intent(context, MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(context, 0, intent, 0);
Notification.Builder builder = new Notification.Builder(context)
.setContentTitle("Reminder")
.setContentText("Car service due in 2 weeks")
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pIntent);
return builder.build();
}
}
my receiver
public class NotificationReceiver extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification-id";
public static String NOTIFICATION = "notification";
public void onReceive(Context context, Intent intent) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = intent.getParcelableExtra(NOTIFICATION);
int id = intent.getIntExtra(NOTIFICATION_ID, 0);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(id, notification);
}
}
I have also registered with <receiver android:name=".NotificationReceiver" > in the AndroidManifest.
In this line
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 10000 , pIntent);
You specify that the alarm has to fire at 10 seconds after the device has been booted (which is in the past, so the alarm fires immediately). If you would want it 10 seconds after you set the alarm, you use the number of milliseconds since the device has been booted PLUS 10 seconds:
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, System.currentTimeMillis() + 10000 , pIntent);
Try this:
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, System.currentTimeMillis()+10000 , pIntent);
For me old methods are killing after few hours . Please see my code that i am using for different OS versions. May be helpful.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(alarmTime, pendingIntent);
alarmManager.setAlarmClock(alarmClockInfo, pendingIntent);
}
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
}
else {
alarmManager.set(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
}
Thanks
Arshad
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
and
Intent notifyIntent = new Intent(this, MyReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, NotificationKeys.NOTIFICATION_ID, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar alarmStartTime = Calendar.getInstance();
alarmStartTime.set(Calendar.SECOND, 5);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, alarmStartTime.getTimeInMillis(), pendingIntent);
If you want to set is at a excat time, you should use setExact. Unfortunalety there is no setExactRepating so you have to create this yourself. Schedule a new alarm after one executes or something like that
for more refer https://stackoverflow.com/a/30812993/8370216