In this tutorial, we’ll be discussing AlarmManager and Broadcast Receiver and see how to trigger a Background Service using them in our Android Application.
AlarmManager Broadcast Receiver Service
An AlarmManager is used to trigger some code at a specific time. It uses the Android SDK’s alarm service and runs independently of the application’s lifecycle.
To start an Alarm Manager you need to first get the instance from the System. Then pass the PendingIntent which would get executed at a future time that you specify.
1 2 3 4 5 6 7 |
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Intent alarmIntent = new Intent(context, MyAlarmReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0); int interval = 8000; manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent); |
There are different types of Alarm Manager that can be invoked:
setInExactAndRepeating
– This doesn’t trigger the alarm at the exact time.setExact
– Setting an alarm manager using this ensures that the OS triggers the alarm at almost the exact time.setExactAndAllowWhileIdle
– This method came up with Android M. These types of alarms are allowed to get executed even in low power modes.
You need to be careful while using the Alarm Manager since they can consume battery if not handled properly.
Normally, an alarm manager cannot repeat before a minute. Also in low power mode, the duration can increase to up to 15 minutes.
Broadcast Receivers listen to system-wide and application events.
In order to trigger a Broadcast Receiver when the system is rebooted, you need to call ACTION_BOOT_COMPLETED
.
In the following section, we’ll be showing how to use an Alarm Manager to trigger a Broadcast Receiver which ultimately calls a background service.
Project Structure
Android Alarm Broadcast Service Project
Code
You need to register your Broadcast Receiver and Service in the AndroidManifest.xml
as shown below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="https://schemas.android.com/apk/res/android" xmlns:tools="https://schemas.android.com/tools" package="com.journaldev.androidalarmbroadcastservice"> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" tools:ignore="GoogleAppIndexingWarning"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".MyBroadCastReceiver" android:directBootAware="true" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" /> </intent-filter> </receiver> <service android:name="com.journaldev.androidalarmbroadcastservice.MyService" android:enabled="true" android:exported="false" android:process=":remote" /> </application> </manifest> |
In order to ensure that the Broadcast Receiver gets triggered properly on reboot in Android N and above, you need to set the directBootAware
to be true and LOCKED_BOOT_COMPLETED
The code for the activity_main.xml layout is given below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android" xmlns:app="https://schemas.android.com/apk/res-auto" xmlns:tools="https://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:id="@+id/btnStartAlarm" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Start Alarm" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/btnCancelAlarm" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Cancel Alarm" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@+id/btnStartAlarm" /> </android.support.constraint.ConstraintLayout> |
The code for the MainActivity.java is given below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
package com.journaldev.androidalarmbroadcastservice; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.os.Build; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast; public class MainActivity extends AppCompatActivity { Button btnStartAlarm, btnCancelAlarm; AlarmManager alarmManager; PendingIntent pendingIntent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnStartAlarm = findViewById(R.id.btnStartAlarm); btnCancelAlarm = findViewById(R.id.btnCancelAlarm); alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Intent alarmIntent = new Intent(this, MyBroadCastReceiver.class); pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0); btnStartAlarm.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startAlarm(); } }); btnCancelAlarm.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { cancelAlarm(); } }); } private void startAlarm() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, 0, pendingIntent); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { alarmManager.setExact(AlarmManager.RTC_WAKEUP, 0, pendingIntent); } else { alarmManager.set(AlarmManager.RTC_WAKEUP, 0, pendingIntent); } } private void cancelAlarm() { alarmManager.cancel(pendingIntent); Toast.makeText(getApplicationContext(), "Alarm Cancelled", Toast.LENGTH_LONG).show(); } } |
The code for the MyBroadcastReceiver.java
file is given below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package com.journaldev.androidalarmbroadcastservice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; public class MyBroadCastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) { Intent serviceIntent = new Intent(context, MyService.class); context.startService(serviceIntent); } else { Toast.makeText(context.getApplicationContext(), "Alarm Manager just ran", Toast.LENGTH_LONG).show(); } } } |
We trigger the Service when the phone is rebooted. Inside the Service, we start a repeating alarm.
The code for the MyService.java
class is given below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
package com.journaldev.androidalarmbroadcastservice; import android.app.AlarmManager; import android.app.IntentService; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.support.annotation.Nullable; public class MyService extends IntentService { public MyService() { super("MyService"); } @Override protected void onHandleIntent(@Nullable Intent intent) { AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Intent alarmIntent = new Intent(this, MyBroadCastReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0); alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, 0, 10000, pendingIntent); } } |
The output of the above application in action is given below:
Android Alarm Broadcast Service Output
That brings an end to this tutorial. You can download the project from the link below: