1

I am trying to generate an alarm after 10 minutes of application startup. According to my requirement, this alarm should work whether the user close the application, turn off and turn on again, or even after a restart. Below is my code.

MainActivity.java

import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    private Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.context=this;

        startService(new Intent(getBaseContext(), MyService.class));

    }

    public void startService(View view) {
      //  startService(new Intent(getBaseContext(), MyService.class));
    }

    // Method to stop the service
    public void stopService(View view) {
      //  stopService(new Intent(getBaseContext(), MyService.class));
    }

}

MyService.java - This is the service class.

import android.app.AlarmManager;
import android.app.IntentService;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.IBinder;
import android.os.SystemClock;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Calendar;
import java.util.GregorianCalendar;

/**
 * Created by Nirodha Mihiran on 6/8/2016.
 */
public class MyService extends Service {

    public static boolean doneCreted = false;

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // Let it continue running until it is stopped.

        Toast.makeText(this, "Service Started Second", Toast.LENGTH_LONG).show();

        Calendar calendar = new GregorianCalendar();
        calendar.setTimeInMillis(System.currentTimeMillis() + 10 * 60 * 1000);

        intent = new Intent(MyService.this, AlarmReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(MyService.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager am = (AlarmManager) MyService.this.getSystemService(MyService.this.ALARM_SERVICE);
        // am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 5, pendingIntent);
        // am.setWindow(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(), 1000 * 60 * 5 , pendingIntent);
        am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
    }

}

AlarmReciever.java

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.GregorianCalendar;

/**
 * Created by thisararanawaka on 6/2/16.
 */
public class AlarmReceiver extends BroadcastReceiver {
    private int MID = 0;

    public static boolean isCreated;

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub

        long when = System.currentTimeMillis();

        Calendar calendar = new GregorianCalendar();
        calendar.setTimeInMillis(System.currentTimeMillis()+5*60*1000);

        NotificationManager notificationManager = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);

        Intent notificationIntent = new Intent(context, MainActivity.class);
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
                notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

        NotificationCompat.Builder mNotifyBuilder = new NotificationCompat.Builder(
                context).setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("Alaram Fired")
                .setContentText("Events To be Performed").setSound(alarmSound)
                .setAutoCancel(true)
                .setContentIntent(pendingIntent)

                .setVibrate(new long[]{1000, 1000, 1000, 1000, 1000});
        notificationManager.notify(MID, mNotifyBuilder.build());
        MID++;

        Toast.makeText(context, "Notification Created .", Toast.LENGTH_LONG).show();
    }
}

I have no problem in getting the alarm on time if I did not turn off and turn off the phone or restart the phone. I get the alarm on time.

However if I turn off and turn on the phone or if I restart the phone, I get the alarm and notification right after phone turn on/restart - maybe after a one minute. In this case even if the alarm is scheduled to tomorrow it doesn't matter, I get it as soon as phone is turned on/restarted.

What have I done wrong?

David Wasser
  • 93,459
  • 16
  • 209
  • 274
Terance Wijesuriya
  • 1,928
  • 9
  • 31
  • 61
  • Alarm Manager resets while phone is restarted. See solution for this at http://stackoverflow.com/a/38093353/2435238 – Sujay Jun 30 '16 at 05:16
  • @sJy:That solution has issues,it do not work when the phone is turned off and turned on. Alarm after restart also not guaranteed. – Terance Wijesuriya Jun 30 '16 at 05:19
  • That solution shows how to catch the Boot complete event from our app. Then for setting the alarm we need to add the code in onReceive() – Sujay Jun 30 '16 at 05:21
  • @sJy: Looking at my code, you suggest Alarm creation should move into `AlarmReciever` class's `onRecieve` method? – Terance Wijesuriya Jun 30 '16 at 05:26
  • Exisiting Alarm creation should remain in Service class itself. But for the BootCompleteReceiver class's onReceive(), you should again set the Alarm so that when phone is switched on again, Alarm will be created. – Sujay Jun 30 '16 at 05:32
  • @sJy: Thanks. Unfortunatly now the alarm comes in "after" 5 minutes of phone restart. For an example, if I open the app now my expectation is to fire the alarm in 5 mins, after 2 mins I restart the phone (which means alarm should be fired after 3 minutes) but the alarm fires after 5 minutes of restart. – Terance Wijesuriya Jun 30 '16 at 07:19
  • 1
    Alarms are not preserved across reboots. Are you handling the `BOOT_COMPLETED` event? Please post the manifest and the code for your `BOOT_COMPLETED` receiver. – David Wasser Jul 05 '16 at 10:54

1 Answers1

3

By looking into your code, this could be a reason

In your onStartCommand(), you are setting the time as calendar.setTimeInMillis(System.currentTimeMillis() + 10 * 60 * 1000);

which sets the calendar time + 10 mins, and then you are setting the same time in the below line am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);

Try like this,

long myAlarmTime = System.currentTimeMillis() + 10 * 60 * 1000; am.set(AlarmManager.RTC_WAKEUP, myAlarmTime, pendingIntent);

Reason for why are facing this issue when restarted

There are two reasons that a service can be run by the system. If someone calls Context.startService() then the system will retrieve the service (creating it and calling its onCreate() method if needed) and then call its onStartCommand(Intent, int, int) method with the arguments supplied by the client. The service will at this point continue running until Context.stopService() or stopSelf() is called. https://developer.android.com/reference/android/app/Service.html

Clement Amarnath
  • 5,301
  • 1
  • 21
  • 34