Sometimes, it's crucial for services to run as the application starts. Also, sometimes it is important to do some cleanup work before we terminate it. In the following example, we will extend the Journaler application to listen for these broadcast messages and do some work. First thing that we will do is create two classes that extend the BroadcastReceiver class:
- BootReceiver: This is to handle the system boot event
- ShutdownReceiver: This is to handle the system shutdown event
Register them in your manifest file as follows:
<manifest ... > ... <receiver android:name=".receiver.BootReceiver" android:enabled="true" android:exported="false"> <intent-filter> <action android:name=
"android.intent.action.BOOT_COMPLETED" /> </intent-filter>
<intent-filter> <action android:name=
"android.intent.action.PACKAGE_REPLACED" /> data android:scheme="package" /> </intent-filter>
<intent-filter> <action android:name=
"android.intent.action.PACKAGE_ADDED" /> <data android:scheme="package" /> </intent-filter> </receiver> <receiver android:name=".receiver.ShutdownReceiver">
<intent-filter> <action android:name=
"android.intent.action.ACTION_SHUTDOWN" /> <action android:name=
"android.intent.action.QUICKBOOT_POWEROFF" /> </intent-filter> </receiver> ...
</manifest>
The BootReceiver class will be triggered when we boot or replace the application. Shutdown will be triggered when we turn off the device. Let's create proper implementations. Open the BootReceiver class and define it like this:
package com.journaler.receiver import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.util.Log class BootReceiver : BroadcastReceiver() { val tag = "Boot receiver" override fun onReceive(p0: Context?, p1: Intent?) { Log.i(tag, "Boot completed.") // Perform your on boot stuff here. } }
As you can see, we defined the receiver package for these two classes. For ShutdownReceiver, define the class like this:
package com.journaler.receiver import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.util.Log class ShutdownReceiver : BroadcastReceiver() { val tag = "Shutdown receiver" override fun onReceive(p0: Context?, p1: Intent?) { Log.i(tag, "Shutting down.") // Perform your on cleanup stuff here. } }
To make this work, we need to apply one more change; otherwise, the application will crash. Move by starting the main service from the Application class into the main activity onCreate() method. This is the first update Journaler class:
class Journaler : Application() { ... override fun onCreate() { // We removed start service method
execution. super.onCreate() ctx = applicationContext Log.v(tag, "[ ON CREATE ]") } // We removed startService() method implementation. ...
}
Then extend the MainActivity class by appending lines at the end of the onCreate() method:
class MainActivity : BaseActivity() { ... override fun onCreate(savedInstanceState: Bundle?) { ... val serviceIntent = Intent(this, MainService::class.java) startService(serviceIntent) } ... } }
Build your application and run it. First, shut down your phone and then power it on. Filter your Logcat so it displays only logs for your application. You should have this output:
... I/Shutdown receiver: Shutting down.
... I/Boot receiver: Boot completed.