AlarmManager not repeating correctly - java

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

Related

Notification doesnt work

I've created a notification and it's just doesnt show up.
My code in the main activity: `boolean alarm = (PendingIntent.getBroadcast(this, 0, new Intent("ALARM"), PendingIntent.FLAG_NO_CREATE) == null);
if(alarm){
Intent itAlarm = new Intent("ALARM");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this,0,itAlarm,0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 3);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
AlarmManager alarme = (AlarmManager) getSystemService(ALARM_SERVICE);
alarme.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),60000, pendingIntent);
}
my code in the Broadcast Reciver:
public class BroadcastManager extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
try {
String yourDate = "04/05/2016";
String yourHour = "13:07:00";
Date d = new Date();
DateFormat date = new SimpleDateFormat("dd/MM/yyyy");
DateFormat hour = new SimpleDateFormat("HH:mm:ss");
if (date.equals(yourDate) && hour.equals(yourHour)){
Intent it = new Intent(context, MainActivity.class);
createNotification(context, it, "new mensage", "body!", "this is a mensage");
}
}catch (Exception e){
Log.i("date","error == "+e.getMessage());
}
}
public void createNotification(Context context, Intent intent, CharSequence ticker, CharSequence title, CharSequence descricao){
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent p = PendingIntent.getActivity(context, 0, intent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setTicker(ticker);
builder.setContentTitle(title);
builder.setContentText(descricao);
builder.setSmallIcon(R.drawable.web_hi_res_512);
builder.setContentIntent(p);
Notification n = builder.build();
//create the notification
n.vibrate = new long[]{150, 300, 150, 400};
n.flags = Notification.FLAG_AUTO_CANCEL;
nm.notify(R.drawable.web_hi_res_512, n);
//create a vibration
try{
Uri som = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone toque = RingtoneManager.getRingtone(context, som);
toque.play();
}
catch(Exception e){}
}
}
Above code will start alarm service on every 3 seconds and repeat on every 1 minute. If you want to generate notification on specific time then, You have to add,
calendar.add(Calendar.HOUR, 13);
calendar.add(Calendar.MINUTES, 07);
calendar.add(Calendar.SECONDS, 00);
and remove this line,
calendar.add(Calendar.SECOND, 3);
I hope it may work for you.

android: Alarmmannager force stop the application

I'm using alarmmanager class to schedule notification for the user to lunch every day in a certain time but when th time comes it force stop the application
this is the setAlarm() method that i call onCreate of the main activity
public void setAlarm() {
// TODO Auto-generated method stub
AlarmManager alarmMgr;
PendingIntent alarmIntent;
alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
// Set the alarm to start at approximately 8:00 p.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 10);
calendar.set(Calendar.MINUTE, 17);
// 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);
}
and that's the the BroadcastReceiver Class
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent arg1) {
creatNotification(context, "Times Up", "5 Seconds Passed", "Alert");
}
private void creatNotification(Context context, String MSG, String MSgText, String MSGAlert) {
PendingIntent NotifIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0);
NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(context);
notifBuilder.setContentTitle("title").setContentText("Content")
.setTicker("Ticker").setSmallIcon(R.drawable.ic_launcher);
notifBuilder.setContentIntent(NotifIntent);
notifBuilder.setDefaults(NotificationCompat.DEFAULT_SOUND);
notifBuilder.setAutoCancel(true);
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, notifBuilder.build());
}
any Ideas ??
Did you define your Broadcast receiver on Manifest file?

Restoring alarms makes app crash

What I'm trying to do; the user picks a date he wants to be notified at with DatePicker, and then I add the name, the id, the release date and the alertTime (The time in milliseconds converted from the user's chosen time) as an entry in the alarms database called myAlarmsDB, which is simple SQL. And when it gets called by the OnReceive() method I delete the entry from the database, all is good except when I close my device; the alarms don't get restored and makes my app crash with no stack-trace. Any idea what might be the problem?
public class AlertReceiver extends BroadcastReceiver {
String name = "";
int id = 0;
String releaseDate = "";
// Called when a broadcast is made targeting this class
#Override
public void onReceive(Context context, Intent intent) {
Intent intActivity = new Intent(context, MainActivity.class);
intActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intActivity);
if("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Toast.makeText(context, "BOOT" , Toast.LENGTH_LONG).show();
// Set the alarm here.
Intent alertIntent = new Intent(context, AlertReceiver.class);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
for (Alarm alarm : MyApp.myAlarmsDB.getAllData()) {
alertIntent.putExtra("id", Integer.parseInt(alarm.get_id()));
alertIntent.putExtra("name", alarm.get_name());
alertIntent.putExtra("releaseDate", alarm.get_releaseDate());
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, Integer.parseInt(alarm.get_id()), alertIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.RTC_WAKEUP, Long.valueOf(Integer.parseInt(alarm.get_alertTime())), pendingIntent);
}
}
id = intent.getIntExtra("id", -1);
name = intent.getStringExtra("name");
releaseDate = intent.getStringExtra("releaseDate");
//delete from database
MyApp.myAlarmsDB.deleteFromId(String.valueOf(id));
}
}
How I set the alarms
public void setAlarm(View view) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, yearDate);
cal.set(Calendar.MONTH, monthDate);
cal.set(Calendar.DAY_OF_MONTH, dayDate);
long alertTime = cal.getTimeInMillis();
Intent alertIntent = new Intent(this, AlertReceiver.class);
// store id
alertIntent.putExtra("id", mainId);
alertIntent.putExtra("name", name);
alertIntent.putExtra("releaseDate", releaseDate);
Alarm alarm = new Alarm(String.valueOf(mainId), name, releaseDate, String.valueOf(alertTime));
MyApp.myAlarmsDB.addAlarm(alarm);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, mainId, alertIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.RTC_WAKEUP, alertTime, pendingIntent);
}
Permissions:
<receiver android:name=".AlertReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>

Notifications that open by themselves

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

AlarmManager triggers PendingIntent too soon for the second time

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

Categories