6

I have a Service "GroupsTaskAlarmChecker" that is called every 20 seconds by AlarmManager in onCreate of Groups.class activity this way:

int seconds = 20;

           Intent myIntent = new Intent(Groups.this, GroupsTaskAlarmChecker.class);
           pendingIntent = PendingIntent.getService(Groups.this, 0, myIntent, 0);

           AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);

           Calendar calendar = Calendar.getInstance();
           calendar.setTimeInMillis(System.currentTimeMillis());
           calendar.add(Calendar.SECOND, 10);
           alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), seconds * 1000, pendingIntent);

This works perfectly. But I need to do that when device boot. Then I know I have to make AndroidManifest like this:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
 <receiver android:name=".ReceiverBoot">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED">
            <category android:name="android.intent.category.HOME">
        </category></action></intent-filter>
    </receiver>

and then mi broadcastReceiver like this:

 public class ReceiverBoot extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    int seconds = 20;

        Intent myIntent = new Intent(context, GroupsTaskAlarmChecker.class);
        pendingIntent = PendingIntent.getService(context, 0, myIntent, 0);

        AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);

        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.add(Calendar.SECOND, 10);
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), seconds * 1000, pendingIntent);

    }
}

but inside this onReceive I dont know how can I do the same that I did before (with intent and alarmManager to start the service each 20 seconds). Error in this line:

 AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);

Is possible that I can't make an AlarmManager inside BroadcastReceiver?

I thank you all, I am an Android begginer and I need your help. Sorry for my english ;)

carlosdiazp
  • 195
  • 1
  • 2
  • 17
  • I forgot to write this line in this question but not in code @Jacob . and init that receive broadcast works (before I test init activity and its ok), I just want to know about write the first code I wrote into a method onReceive. Is this possible? – carlosdiazp Mar 05 '13 at 10:31

4 Answers4

4

To summarize the answers and comments above: the onReceive handler receives a context which can be used to access getSystemService and ALARM_SERVICE. Sample code:

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        // Start periodic service.
        Calendar cal = Calendar.getInstance();
        Intent srvIntent = new Intent(context, MyService.class);
        PendingIntent pIntent = PendingIntent.getService(context, 0, srvIntent, 0);
        // Use context argument to access service
        AlarmManager alarm = 
                        (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);

        // Repeat every 5 seconds
        alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
                                5000, pIntent);
        }
    }
}

Create a new class with this code and of course change MyReceiver and MyService to the names in your implementation.

pmont
  • 2,083
  • 22
  • 43
2

ALARM_SERVICE is neither defined in the class ReceiverBoot nor in BroadcastReceiver.

You should reference Context.ALARM_SERVICE as the argument for getSystemService(String).

pakopa
  • 633
  • 5
  • 8
2

Here is a little contribution, which I believe that can add a more complete vision about achieving the goal of this question.

First: configure a "receiver" inside of the AndroidManifest from your app.

<receiver
    android:name=".AlarmBroadcastReceiver"
    android:enabled="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

Second: with a Class that EXTENDS the Abstract Class BroadcastReceiver, you should determine if the Intent Action was "BOOT_COMPLETED". If the condition is satisfied, you can call a method from your class which has all the construction to your Alarm.

See the following snippet bellow.

public class AlarmBroadcastReceiver extends BroadcastReceiver {

    String TAG   = "ALARMS";
    String CLASS = this.getClass().getSimpleName() + ": ";

    Context alarmContext;

    @Override
    public void onReceive(final Context context, Intent intent) {

        Log.d(TAG, CLASS + "[START] onReceive()... ");

        alarmContext = context;

        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
            Log.d(TAG, CLASS + "BOOT_COMPLETED action has been received.");
            setAlarmOnBoot();
        }

            Log.d(TAG, CLASS + "[END] onReceive()... ");

    }

    public void setAlarmOnBoot() {

        Log.d(TAG, CLASS + "[START] - setAlarmOnBoot()");

        final long beginAt  = SystemClock.elapsedRealtime() + 60 * 1000;
        final long interval = 300000; // 5 minutes

        try {
            AlarmManager alarm    = (AlarmManager)  alarmContext.getSystemService(Context.ALARM_SERVICE);
            Intent intent         = new Intent(alarmContext, AlarmBroadcastReceiver.class);
            PendingIntent pIntent = PendingIntent.getService(alarmContext, 0, intent, 0);
            alarm.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, beginAt, interval, pIntent);
            Log.d(TAG, CLASS + "the Alarm has been configured successfully (5 minutes) of interval.");
        } catch (Exception e) {
            Log.d(TAG, CLASS + "an exception has ocurred while setting the Alarm...");
            e.printStackTrace();
        }  

        Log.d(TAG, CLASS + "[END] - setAlarmOnBoot()");

    }

}
ivanleoncz
  • 9,070
  • 7
  • 57
  • 49
  • 1
    amazing solution, and thanks for the complete code which is easy to understand for beginners like me – Sasa May 31 '17 at 05:18
  • 1
    You're welcome, pal! I believe that this code is not that difficult and can improve the solutions that we have here for this answer. Regards :). – ivanleoncz May 31 '17 at 05:24
0

in your onReceive:

if ("android.intent.action.BOOT_COMPLETED".equals (intent.getAction())){

   //start it again here

}
MariusBudin
  • 1,277
  • 1
  • 10
  • 21
  • but my problem is making the code: I have to make the instance and AlarmManager inside the broadcastReceive. And I dont know how to do it :/ – carlosdiazp Mar 05 '13 at 11:02
  • (if I change contexts)no warnings and errors but yes in this line: AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE); Problem with this method and variable inside broadcast receiver... Can be I can´t make an AlarmManager inside broadcastReceiver?? – carlosdiazp Mar 05 '13 at 11:17
  • 1
    I think you need an object [Context](http://developer.android.com/reference/android/content/Context.html) to invoke getSystemService over. – pakopa Mar 05 '13 at 11:33
  • 1
    try getting the SystemService from the context passed by param in the onReceive method – MariusBudin Mar 05 '13 at 11:40
  • I don't know what to do, with this line continue error "ALARM_SERVICE cannot be resolved to a variable": AlarmManager alarmManager= (AlarmManager)context.getSystemService(ALARM_SERVICE ); – carlosdiazp Mar 05 '13 at 12:23
  • get it from context too Context.ALARM_SERVICE – MariusBudin Mar 05 '13 at 13:47
  • Thats it. (Context.ALARM_SERVICE) is the answer . Thank You very much @Ics ;) – carlosdiazp Mar 05 '13 at 15:20