1

In my app a timepicker is used by the user to set an alarm to notify them on when to use the app. When they set the reminder it will notify the user every 24 hours. I have used AlarmManager and Service to solve the problem. When I set the time I get notification every 24 hours, but sometimes I keep getting notifications randomly again and again. This is an error I can't debug and I don't know where the problem is.

This is how I have done:

To set an Reminder and cancel it here is my code: I use AlarmManager to set the Time.

private void setReminder(){
    Calendar calendar = Calendar.getInstance();
    Calendar currentCalendar = Calendar.getInstance();
    calendar.set(Calendar.HOUR_OF_DAY, timePicker.getCurrentHour());
    calendar.set(Calendar.MINUTE, timePicker.getCurrentMinute());

    SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMAT, Locale.US);
    String time = sdf.format(calendar.getTime());
    SavingData.setReminder(time, true);

    long intendedTime = calendar.getTimeInMillis();
    long currentTime = currentCalendar.getTimeInMillis();

    alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
    Intent intent = new Intent(this, MyReceiver.class);
    pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);

    if((intendedTime >= currentTime) == false){
        // This will set the alarm for the next day, if time is below intentedTime
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        intendedTime = calendar.getTimeInMillis();
    }

    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, intendedTime, AlarmManager.INTERVAL_DAY, pendingIntent);

    Toast.makeText(this, "Alarm Scheduled!", Toast.LENGTH_LONG).show();
}

private void cancelId() {
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.HOUR_OF_DAY, timePicker.getCurrentHour());
    calendar.set(Calendar.MINUTE, timePicker.getCurrentMinute());

    // Time format to String
    SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMAT, Locale.US);
    String time = sdf.format(calendar.getTime());
    SavingData.setReminder(time, false);

    alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE); 
    Intent intent = new Intent(this, MyReceiver.class);
    pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);

    // If the alarm has been set, cancel it.
    if (alarmManager!= null) {
        alarmManager.cancel(pendingIntent);
        Toast.makeText(this, "Cancel Alarm!", Toast.LENGTH_SHORT).show();
    }
}

I use BroadCastReceiver:

public class MyReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    Toast.makeText(context, "MyReceiver!", Toast.LENGTH_SHORT).show();
    Intent service = new Intent(context, MyService.class);
    context.startService(service);
}

}

Below is my Service class. In my service class I create the notification information using notification manager.

 public class MyService extends Service {
private static final int notificationID = 0;

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public void onCreate() {
    // TODO Auto-generated method stub
    super.onCreate();
}

@Override
@Deprecated
public void onStart(Intent intent, int startId) {
    // TODO Auto-generated method stub
    super.onStart(intent, startId);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);

    Intent notificationIntent = new Intent(this, MainActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

    int icon = R.drawable.icon;
    String tickerText = "HELLO";
    long when = System.currentTimeMillis();
    String contentTitle = "How Are You";
    String contentText = "Time to use the App";
    // Define sound URI, the sound to be played when there's a notification
    Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

    Notification notification = new NotificationCompat.Builder(this)
    .setContentTitle(contentTitle)
    .setContentText(contentText)
    .setSmallIcon(icon)
    .setTicker(tickerText)
    .setWhen(when)
    .setContentIntent(pendingIntent)
    .setSound(soundUri)
    .build();

    notificationManager.notify(notificationID, notification);
    return super.onStartCommand(intent, flags, startId);
}

@Override
public void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
}

}

user3730218
  • 49
  • 1
  • 7
  • 1
    It might help you to debug if you use adb to look at your alarm(s). http://stackoverflow.com/questions/6522792/get-list-of-active-pendingintents-in-alarmmanager – Steven Trigg Jul 02 '14 at 23:20
  • Beyond the problem Jim outlined, you are using `RTC_WAKEUP` without `WakefulBroadcastReceiver` (or my `WakefulIntentService`), and that is unreliable. Also, you are leaking the service -- please stop the service when there is no more work to be done. – CommonsWare Jul 02 '14 at 23:30

1 Answers1

1

Your service is getting Android system restart "null" intents when it dies or at other times and you are not accounting for those. You send a notification any time it receives an intent. From the docs:

intent The Intent supplied to startService(Intent), as given. This may be null if the service is being restarted after its process has gone away, and it had previously returned anything except START_STICKY_COMPATIBILITY.

If you check for null intents or other content specific to your alarm intent your problem should go away.

Jim
  • 10,172
  • 1
  • 27
  • 36