the notifications of my app open without a logical sense than the code that I wrote. I should receive a notification every day at the same time but if I open the app I get the same notification. This is the code in MainActivity:
public void setRepeatingAlarm() {
Intent intent = new Intent(this, MyAlarmService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 13);
calendar.set(Calendar.MINUTE, 00);
calendar.set(Calendar.SECOND, 00);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),24*60*60*1000,pendingIntent);
}
And this is MyAlarmService:
public class MyAlarmService extends BroadcastReceiver {
NotificationManager nm;
#Override
public void onReceive(Context context, Intent intent) {
nm = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
CharSequence from = "Locali Torino";
CharSequence message = "Visita le serate!";
Intent action = new Intent(context, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
action, 0);
Notification notif = new Notification(R.drawable.disco,
"Visita le serate!", System.currentTimeMillis());
notif.setLatestEventInfo(context, from, message, contentIntent);
notif.flags |= Notification.FLAG_AUTO_CANCEL;
nm.notify(0, notif);
}
}
Why I get notifications when I open the app or at least not only at the set time?
EDIT
MyAlarmService:
public class MyAlarmService extends BroadcastReceiver {
NotificationManager nm;
#Override
public void onReceive(Context context, Intent intent) {
nm = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
CharSequence from = "Locali Torino";
CharSequence message = "Visita le serate!";
Intent action = new Intent(context, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
action, 0);
Notification notif = new Notification(R.drawable.disco,
"Visita le serate!", System.currentTimeMillis());
notif.setLatestEventInfo(context, from, message, contentIntent);
notif.flags |= Notification.FLAG_AUTO_CANCEL;
nm.notify(0, notif);
SharedPreferences mPref = context.getSharedPreferences("pref_name", Context.MODE_PRIVATE);
SharedPreferences.Editor mEditor = mPref.edit();
long time = System.currentTimeMillis();
mEditor.putLong("UPDATE_TIME", time);
mEditor.commit();
}And this is MainActivity:
public void setRepeatingAlarm() {
Intent intent = new Intent(this, MyAlarmService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
long startAt;
long period;
SharedPreferences mPref = context.getSharedPreferences("pref_name", Context.MODE_PRIVATE);
long dif = System.currentTimeMillis() - mPref.getLong("UPDATE_TIME", 0);
if (dif >= UPDATE_PERIOD) {
startAt = 0;
period = UPDATE_PERIOD;
} else {
startAt = dif;
period = dif;
}
am.setRepeating(AlarmManager.RTC_WAKEUP, startAt, period,pendingIntent);
}
The service runs when you register it, so what you need to do is pass a boolean value with the intent when registering the service to prevent it from running when the application runs, but to run periodically thereafter.
In your activity add:
intent.putExtra("run", false);
Then in MyAlarmService:
private boolean run = true;
// ...
action.getBooleanExtra("run", run);
if(run) {
// notifications code
} else {
run = true;
}
Actually it works exactly as code is written. The cause of that behavior is your startAt parameter in setRepeating method.
am.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),
24*60*60*1000,
pendingIntent);
calendar.getTimeInMillis() time in milliseconds that the alarm should first go off, using the appropriate clock (depending on the alarm type).
For example :
//send first alarm after 1 second and repeat it every 24 hours
am.setRepeating(AlarmManager.RTC_WAKEUP,
1000,
24*60*60*1000,
pendingIntent);
//send first alarm after 10 second and repeat it every 24 hours
am.setRepeating(AlarmManager.RTC_WAKEUP,
10000,
24*60*60*1000,
pendingIntent);
UPDATE :
You need to save your last update time :
public class MyAlarmService extends BroadcastReceiver {
NotificationManager nm;
#Override
public void onReceive(Context context, Intent intent) {
//send alarm here
//...
SharedPreferences mPref = context.getSharedPreferences("pref_name", Context.MODE_PRIVATE);
SharedPreferences.Editor mEditor = mPref.edit();
mEditor.putLong("UPDATE_TIME", time);
mEditor.commit();
}
}
Then you can make your setRepeatingAlarm method like this :
public void setRepeatingAlarm() {
Intent intent = new Intent(this, MyAlarmService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
long startAt;
long period;
SharedPreferences mPref = context.getSharedPreferences("pref_name", Context.MODE_PRIVATE);
long dif = System.currentTimeMillis() - mPref.getLong("UPDATE_TIME", 0);
if (dif >= UPDATE_PERIOD) {
startAt = 0;
period = UPDATE_PERIOD;
} else {
startAt = dif;
period = dif;
}
am.setRepeating(
AlarmManager.RTC_WAKEUP,
startAt,
period,
pendingIntent);
}
Related
in my program i set notifications with a string and its clock to get a notification with that string at its clock.(I mean user wants to get a notification with a string at demanding time, and user gave me a lot of strings and their clocks.) And if the user want to cancel that notification i don't know how to do it.
I tried alarmManager.cancel(pendingIntent) but I want to cancel the only one notification not all of them. Also, it doesn't cancel any notification too.
here is the code in the main
public void gecikmeliGoster(String plan, int yil, int ay, int gun, String saat){
NotificationCompat.Builder builder;
NotificationManager bildirimYoneticisi = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent ıntent = new Intent(HatirlaticiKur.this, AlarmReciever.class);
PendingIntent gidilecekIntent = PendingIntent.getActivity(this, 1, ıntent, PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String kanalId = "kanalId";
String kanalAd = "kanalAd";
String kanalTanım = "kanalTanım";
int kanalOnceligi = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel kanal = bildirimYoneticisi.getNotificationChannel(kanalId);
if (kanal == null) {
kanal = new NotificationChannel(kanalId, kanalAd, kanalOnceligi);
kanal.setDescription(kanalTanım);
bildirimYoneticisi.createNotificationChannel(kanal);
}
builder = new NotificationCompat.Builder(this, kanalId);
builder.setContentTitle("Hatırlatıcı")
.setContentText(plan)
.setSmallIcon(R.drawable.hatirlatici)
.setAutoCancel(true)
.setContentIntent(gidilecekIntent);
} else {
builder = new NotificationCompat.Builder(this);
builder.setContentTitle("Hatırlatıcı")
.setContentText(plan)
.setSmallIcon(R.drawable.hatirlatici)
.setContentIntent(gidilecekIntent)
.setAutoCancel(true)
.setPriority(Notification.PRIORITY_HIGH);
}
Intent broadcastIntent = new Intent(HatirlaticiKur.this, AlarmReciever.class);
broadcastIntent.putExtra("nesne", builder.build());
PendingIntent gidilecekBroadcast = PendingIntent.getBroadcast(this, 0, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//long gecikme = SystemClock.elapsedRealtime() + 5000; //bu 5 saniyede bir bildirim gelmesi için falan
String[] noktasiz = saat.split(":");
int akrep = Integer.parseInt(noktasiz[0]);
int yelkovan = Integer.parseInt(noktasiz[1]);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.YEAR, yil);
calendar.set(Calendar.MONTH, ay);
calendar.set(Calendar.DATE, gun);
calendar.set(Calendar.HOUR_OF_DAY, akrep);
calendar.set(Calendar.MINUTE, yelkovan);
calendar.set(Calendar.SECOND, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 0, gidilecekBroadcast);
}
and here is the code in AlarmReceiver
public class AlarmReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationManager bildirimYoneticisi = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification bildirim = intent.getParcelableExtra("nesne");
bildirimYoneticisi.notify(1,bildirim);
}
}
I want to cancel demanding notifications, i will appreciate your help
use used 0 id for setting alarm
PendingIntent gidilecekBroadcast = PendingIntent.getBroadcast(this, 0, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
You need uniqueid for all notification set using alarmmanager
then based on uniqueid you can cancel alarm
PendingIntent gidilecekBroadcast =
PendingIntent.getBroadcast(getApplicationContext(), uniqueid , broadcastIntent,
PendingIntent.FLAG_UPDATE_CURRENT)
alarmManager.cancel(gidilecekBroadcast);
I am trying to send a notification at a specific time after registering an item on a database (6 hours or 12 hours). The notification works fine when I only register one item, however if I register 2 items in a close period of time the first notification is overwritten by the second.
I know that I have to add ID's to the pending intents and maybe an id to the actual notification however I am not very familiar with the alarmManager class and I do not know where I should be adding the IDs.
How do I make these two notifications independent of one another?
NotificationHelper Class:
public static class NotificationHelper extends ContextWrapper {
public static final String channel1ID = "channel1ID";
public static final String channel1Name = "USER1";
private NotificationManager mManager;
public NotificationHelper(Context base) {
super(base);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createChannels();
}
}
#RequiresApi(api = Build.VERSION_CODES.O)
private void createChannels() {
NotificationChannel channel1 = new NotificationChannel(channel1ID, channel1Name, NotificationManager.IMPORTANCE_HIGH);
channel1.enableLights(true);
channel1.enableVibration(true);
channel1.shouldVibrate();
channel1.setShowBadge(true);
channel1.setLightColor(R.color.colorPrimary);
channel1.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
Uri uri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
.setUsage(USAGE_NOTIFICATION)
.build();
channel1.setSound(uri, audioAttributes);
getManager().createNotificationChannel(channel1);
}
public NotificationManager getManager() {
if (mManager == null) {
mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
return mManager;
}
public NotificationCompat.Builder getChannel1Notification() {
return new NotificationCompat.Builder(getApplicationContext(), channel1ID)
.setContentTitle("Dressing")
.setContentText("Please scan the dressing on your: " + (et_DressingPos.getText().toString().trim()))
.setSmallIcon(R.drawable.ic_cnoticiation_scan);
}
}
AlarmReceiver Class:
#Override
public void onReceive(Context context, Intent intent) {
Camera2Register.NotificationHelper notificationHelper = new Camera2Register.NotificationHelper(context);
NotificationCompat.Builder nb = notificationHelper.getChannel1Notification();
Intent intent2 = new Intent(context, Camera2.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent2, 0);
nb.setContentIntent(pendingIntent);
notificationHelper.getManager().notify(1, nb.build());
}
}
startAlarmScan and startALarmChange Methods:
private void startAlarmScan() {
int requestCode = ("someString" + System.currentTimeMillis()).hashCode();
Long time = System.currentTimeMillis();
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
intent.putExtra("randomRequestCode", requestCode);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, requestCode, intent, 0);
long milliseconds = 5000;
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, (time + milliseconds), pendingIntent);
//}
}
private void startAlarmChange() {
int requestCode = ("someString" + System.currentTimeMillis()).hashCode();
Long time = System.currentTimeMillis();
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
intent.putExtra("randomRequestCode", requestCode);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, requestCode, intent, 0);
long milliseconds = 30000;
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, (time + milliseconds), pendingIntent2);
//}
}
I have set the time delay for the two different notifications to 5 and 30 seconds. If register and class the two startAlarmScan and startAlarmChange methods within 30 seconds of each other. the first scheduled notification will be overwritten by the second.
I am beginning to think the problem may lie in the structuring of my notification system, is a Receiver class necessary? There is no mention of it in the notification documentation on Android.
You are using a constant value "1" for your notification id here: notificationHelper.getManager().notify(1, nb.build());
from the docs: Here "If a notification with the same id has already been posted by your application and has not yet been canceled, it will be replaced by the updated information"
Change this 1 to a unique number for each notification and you should see them all come through.
Edit
You also do the same thing on the line:
PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent2, 0);
That request code "1" is used to compare pending intents using filterEquals(Intent intent) This question talks about it.
This application allows me to start a service to remind me drinking. If i click the notification i want to see if the service is running or not, but i don't get any output with the Intent.putExtra method.
My MainActivity class:
Boolean isServiceRunning = false;
AlarmManager alarmManager;
PendingIntent pendingIntent;
TextView mainText;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainText = findViewById(R.id.mainTextView);
Bundle extras = getIntent().getExtras();
if (extras == null) {
mainText.setText("Service is paused");
} else {
mainText.setText("Service is running");
}
}
public void sendNotification(View view) {
if (!isServiceRunning) {
isServiceRunning = true;
Toast.makeText(this, "Reminder service started.", Toast.LENGTH_SHORT).show();
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
mainText.setText("Service is running.");
Intent i = new Intent(this, reciever.class);
i.putExtra("isServiceRunning", isServiceRunning.booleanValue());
pendingIntent = PendingIntent.getBroadcast(this, 100, i, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 10, pendingIntent);
} else {
isServiceRunning = false;
Toast.makeText(this, "Reminder service ended.", Toast.LENGTH_SHORT).show();
mainText.setText("Service paused.");
alarmManager.cancel(pendingIntent);
}
}
I think its possible to solve this problem with sharedpreferences, but this shouldn't be a good resolution.
EDIT:
My broadcast reciever class:
public class reciever BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent notificationIntent = new Intent(context, drinkReminder.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(drinkReminder.class);
stackBuilder.addNextIntent(notificationIntent);
PendingIntent pendingIntent = stackBuilder.getPendingIntent(100, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
Notification notification = new NotificationCompat.Builder(context, CHANNEL_1_ID)
.setContentTitle("Title")
.setContentText("description")
.setSmallIcon(R.drawable.icon_waterdrop)
.setTimeoutAfter(30000)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build();
notificationManager.notify(0, notification);
}
}
You are adding the "extra" to the Intent that you pass to AlarmManager. This "extra" will be in the Intent that gets delivered to your BroadcastReceiver in onReceive(), but you don't do anything with it there.
When you click on the Notification, it will launch drinkReminder, which I hope is an Activity.
You also said in a comment:
Could you tell me please one more thing. Sometimes if i press the
button to start the service, a notification appers after about 10
seconds, after this it shows all 10 minutes like it should. How can i
fix this?
Here is your code for setting the alarm:
Calendar calendar = Calendar.getInstance();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), 1000 * 60 * 10, pendingIntent);
When you call setRepeating(), the 2nd parameter specifies the first time the alarm should go off, and the 3rd parameter specifies the repeat interval. You've told alarm manager that you want the first alarm to trigger immediately and then every 10 minutes after that.
If you want the first alarm to trigger 10 minutes after you press the button, you need to adjust the second parameter so it represents a time that is 10 minutes in the future, like this:
Calendar calendar = Calendar.getInstance();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis() + (1000 * 60 * 10), 1000 * 60 * 10, pendingIntent);
Instead of the code in onCreate() and putExtra() ,you can create two pending intents in each case and each intent uses a different broadcast receiver. In that broadcast receiver you can print the separate toast messages.
MyBroadcastRecieverStart.java
public class MyBroadcastReceiverStart extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(this, "Reminder service started.", Toast.LENGTH_SHORT).show();
}
}
MyBroadcastReceiverStop.java
public class MyBroadcastReceiverStop extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(this, "Reminder service ended.", Toast.LENGTH_SHORT).show();
}
}
SendNotification method -
public void sendNotification(View view) {
if (!isServiceRunning) {
isServiceRunning = true;
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
mainText.setText("Service is running.");
Intent i = new Intent(this, MyBroadcastReceiverStart.class);
pendingIntent = PendingIntent.getBroadcast(this, 100, i, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 10, pendingIntent);
} else {
isServiceRunning = false;
mainText.setText("Service paused.");
Intent i = new Intent(this, MyBroadcastReceiverStop.class);
pendingIntent = PendingIntent.getBroadcast(this, 100, i, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 10, pendingIntent);
alarmManager.cancel(pendingIntent);
}
}
If you write alarmManager.cancel(pendingIntent) in else block , it is cancelling an intent which does not exist as you have created the intent in if block and it does not get created if else gets executed , so I have created the intent in else block also.
I try to have a notification repeated daily (For debugging I set it to every 10s). However, it is firing the notification only the first time, then nothing happens.
Here is the code where the alarm is set:
Intent myIntent = new Intent(ctx , NotifyService.class);
AlarmManager alarmManager =(AlarmManager)ctx.getSystemService(ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getService(ctx, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(), 1000 * 10, pendingIntent);
and here is the service:
public class NotifyService extends Service {
public NotifyService() {
}
#Override
public void onCreate(){
//Create and Emit the notification.
}
I have tried different flags in getService(ctx, int, Intent, flags), to use setInexactRepeating and to set a new alarm after every call to the NotifyService.
Use the method below to repeating the alarm once in a day and you have to register broadcast receiver instead of service with AlarmManager so that you can start your service from the receiver and that is recommended.
Find the official doc.
private final static String ACTION = "ACTION_ALARM";
public static void setWakeUpAction(Context context, String hourSet, String minuteSet, String periodSet, int requestCode, String currentAction) {
try {
String mHour = hourSet;
String mMin = minuteSet;
String[] parsedFormat = null;
Calendar calendar = Calendar.getInstance();
SimpleDateFormat displayFormat = new SimpleDateFormat("HH:mm");
SimpleDateFormat parseFormat = new SimpleDateFormat("hh:mm a");
Date date = parseFormat.parse(mHour + ":" + mMin + " " + periodSet);
parsedFormat = displayFormat.format(date).split(":");
mHour = parsedFormat[0];
mMin = parsedFormat[1];
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(mHour));
calendar.set(Calendar.MINUTE, Integer.parseInt(mMin));
calendar.set(Calendar.SECOND, 00);
Intent myIntent = new Intent(context, MyReceiver.class);
myIntent.putExtra(ACTION, currentAction);
myIntent.putExtra("Time", new String[]{mHour, mMin, periodSet});
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, requestCode, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
} catch (ParseException e) {
e.printStackTrace();
}
}
BroadCastReceiver
public class MyReceiver extends BroadcastReceiver {
private final String ACTION = "ACTION_ALARM";
private String ACTION_ONE = "ALARM_REPEAT";
#Override
public void onReceive(Context context, Intent intent) {
try {
String action = intent.getStringExtra(ACTION);
new ShowToast(context, action);
if (action.length() > 1) {
if (action.equals(ACTION_ONE) ) {
String time[] = intent.getStringArrayExtra("Time");
startService(context, action);
}
}
} catch (Exception e) {
}
}
public void startService(Context context, String action) {
Intent service1 = new Intent(context, NotifyService.class);
service1.putExtra(ACTION, action);
context.startService(service1);
}
}
Manifest
<service
android:name=".NotifyService"
android:enabled="true" />
<receiver android:name=".MyReceiver" />
Usage
setWakeUpAction(context, "11", "00","AM","0", "ALARM_REPEAT");
Use a PendingIntent for a BroadcastReceiver rather than a Service, that is the recommended (and documented) practice. Plus, if you are using "wakeup" alarms, you'll need to use a BroadcastReceiver otherwise the system will not guarantee that it stays awake long enough for your Service to actually execute and receive the Intent. See this article for more details: http://po.st/7UpipA
Try this,
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
// setRepeating() lets you specify a precise custom interval--in this case,
// 10 seconds.
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000 * 10, alarmIntent);
Refer : http://developer.android.com/training/scheduling/alarms.html
I have this code:
set alarm:
public void setAlarm()
{
Calendar Calendar_Object = Calendar.getInstance();
Calendar_Object.add (Calendar.DAY_OF_YEAR, 1);
Calendar_Object.set(Calendar.HOUR_OF_DAY, 0);
Calendar_Object.set(Calendar.MINUTE, 0);
Calendar_Object.set(Calendar.SECOND, 1);
Intent myIntent = new Intent(Main.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(Main.this,
0, myIntent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC, Calendar_Object.getTimeInMillis(),1000*60*60*24, pendingIntent);
}
Broadcast receiver:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent myIntent = new Intent(context, NotificationService.class);
context.startService(myIntent);
}
}
the service:
public class NotificationService extends Service {
private NotificationManager mManager;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#SuppressWarnings("deprecation")
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
mManager = (NotificationManager) this.getApplicationContext()
.getSystemService( this.getApplicationContext().NOTIFICATION_SERVICE);
Intent intent1 = new Intent(this.getApplicationContext(), ABC.class);
Notification notification = new Notification(R.drawable.ic_launcher,
"xxx", System.currentTimeMillis());
intent1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(
this.getApplicationContext(), 0, intent1,
PendingIntent.FLAG_UPDATE_CURRENT);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(this.getApplicationContext(),
"abc", "xyz",
pendingNotificationIntent);
mManager.notify(0, notification);
}
}
after setting the alarm at 00:00:01 everything is perfect but the next time the problem is happening. the PendingIntent triggers like 6 to 8 times between the 24 hours interval. I don't remember if the time is the same for each trigger but I want it one time each day. What is wrong with the code?
This will create an alarm that will go off every day at 00:05, the important part is the AlarmManager.INTERVAL_DAY
Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 5);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.add(Calendar.HOUR, 24);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
mgr.cancel(pi);
mgr.setRepeating(AlarmManager.RTC, cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
Also, don't forget to always cancel previous similar alarms, when re-setting a new one, or else they'll all go off, old set alarms, and the new one, see above mgr.cancel(pi);