In the this tutorial we will explain how to send a notification using Notification.Builder class. And how to schedule it after a certain interval. Here we show how to schedule the notification after 5 seconds.
Scheduling of the notification is achieved by using AlarmManager
. By registering a BroadcastReceiver called AlarmReceiver
we can subscribe the broadcast of a particular time.
Notification is created using Notification.Builder class in IntentService class NotificationService
which is started by BroadcastReceiver’s onReceive()
method.
STEP 1. Create BroadcastReceiver
The onReceive()
will get called when scheduled time for the notification is reached.
package samples.notification.devdeeds.com import android.content.BroadcastReceiver import android.content.Context import android.content.Intent class AlarmReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val service = Intent(context, NotificationService::class.java) service.putExtra("reason", intent.getStringExtra("reason")) service.putExtra("timestamp", intent.getLongExtra("timestamp", 0)) context.startService(service) } }
STEP 2. Create IntentService That Will Create And Show Notification
Notification is created and notified in this service class and it is started by the BroadcastReceiver’s onReceive()
method as explained above. We create and notifiy the notification in onHandleIntent()
method of this IntentService. We are mainly doing 3 functionalities they are as follows,
- Create notification channel if OS version >= Orieo
- Create notification using Notification.Builder class.
- Notify the created notification.
package samples.notification.devdeeds.com import android.annotation.SuppressLint import android.app.* import android.content.Context import android.content.Intent import android.graphics.BitmapFactory import android.graphics.Color import android.media.RingtoneManager import android.os.Build import java.util.* import android.app.NotificationChannel class NotificationService : IntentService("NotificationService") { private lateinit var mNotification: Notification private val mNotificationId: Int = 1000 @SuppressLint("NewApi") private fun createChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // Create the NotificationChannel, but only on API 26+ because // the NotificationChannel class is new and not in the support library val context = this.applicationContext val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager val importance = NotificationManager.IMPORTANCE_HIGH val notificationChannel = NotificationChannel(CHANNEL_ID, CHANNEL_NAME, importance) notificationChannel.enableVibration(true) notificationChannel.setShowBadge(true) notificationChannel.enableLights(true) notificationChannel.lightColor = Color.parseColor("#e8334a") notificationChannel.description = getString(R.string.notification_channel_description) notificationChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC notificationManager.createNotificationChannel(notificationChannel) } } companion object { const val CHANNEL_ID = "samples.notification.devdeeds.com.CHANNEL_ID" const val CHANNEL_NAME = "Sample Notification" } override fun onHandleIntent(intent: Intent?) { //Create Channel createChannel() var timestamp: Long = 0 if (intent != null && intent.extras != null) { timestamp = intent.extras!!.getLong("timestamp") } if (timestamp > 0) { val context = this.applicationContext var notificationManager: NotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager val notifyIntent = Intent(this, ResultActivity::class.java) val title = "Sample Notification" val message = "You have received a sample notification. This notification will take you to the details page." notifyIntent.putExtra("title", title) notifyIntent.putExtra("message", message) notifyIntent.putExtra("notification", true) notifyIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK val calendar = Calendar.getInstance() calendar.timeInMillis = timestamp val pendingIntent = PendingIntent.getActivity(context, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT) val res = this.resources val uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { mNotification = Notification.Builder(this, CHANNEL_ID) // Set the intent that will fire when the user taps the notification .setContentIntent(pendingIntent) .setSmallIcon(R.drawable.ic_stat_name) .setLargeIcon(BitmapFactory.decodeResource(res, R.mipmap.ic_launcher)) .setAutoCancel(true) .setContentTitle(title) .setStyle(Notification.BigTextStyle() .bigText(message)) .setContentText(message).build() } else { mNotification = Notification.Builder(this) // Set the intent that will fire when the user taps the notification .setContentIntent(pendingIntent) .setSmallIcon(R.drawable.ic_stat_name) .setLargeIcon(BitmapFactory.decodeResource(res, R.mipmap.ic_launcher)) .setAutoCancel(true) .setPriority(Notification.PRIORITY_MAX) .setContentTitle(title) .setStyle(Notification.BigTextStyle() .bigText(message)) .setSound(uri) .setContentText(message).build() } notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager // mNotificationId is a unique int for each notification that you must define notificationManager.notify(mNotificationId, mNotification) } } }
STEP 3. Create A Utility Class called NotificationUtils
This utility class will helps us to send notification by calling setNotification()
package samples.notification.devdeeds.com import android.app.Activity import android.app.AlarmManager import android.app.PendingIntent import android.content.Intent import java.util.* /** * Created by devdeeds.com on 5/12/17. */ class NotificationUtils { fun setNotification(timeInMilliSeconds: Long, activity: Activity) { //------------ alarm settings start -----------------// if (timeInMilliSeconds > 0) { val alarmManager = activity.getSystemService(Activity.ALARM_SERVICE) as AlarmManager val alarmIntent = Intent(activity.applicationContext, AlarmReceiver::class.java) // AlarmReceiver1 = broadcast receiver alarmIntent.putExtra("reason", "notification") alarmIntent.putExtra("timestamp", timeInMilliSeconds) val calendar = Calendar.getInstance() calendar.timeInMillis = timeInMilliSeconds val pendingIntent = PendingIntent.getBroadcast(activity, 0, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT) alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.timeInMillis, pendingIntent) } //------------ end of alarm settings -----------------// } }
STEP 4. Create Your Main Activity
The notification is created and sent after 5 seconds through NotificationUtils()
utils class when Main Activity is created. Here we add 5000 milliseconds to current timestamp.
package samples.notification.devdeeds.com import android.support.v7.app.AppCompatActivity import android.os.Bundle import java.util.* class MainActivity : AppCompatActivity() { private val mNotificationTime = Calendar.getInstance().timeInMillis + 5000 //Set after 5 seconds from the current time. private var mNotified = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) if (!mNotified) { NotificationUtils().setNotification(mNotificationTime, this@MainActivity) } } }
STEP 5. In the Result Activity
Here we have created a separate activity for the notification result. This activity will open when user clicks on the notification with the values passed into it through the PendingIntent.
package samples.notification.devdeeds.com import android.support.v7.app.AppCompatActivity import android.os.Bundle import kotlinx.android.synthetic.main.activity_result.* class ResultActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_result) if (intent.getBooleanExtra("notification", false)) { //Just for confirmation txtTitleView.text = intent.getStringExtra("title") txtMsgView.text = intent.getStringExtra("message") } } }
AndroidManifest.xml File
Here we have added
and service
to the manifest file. It is required to add them in the manifest file otherwise BroadcastReciver will not receive callbacks in onReceive()
meth.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="samples.notification.devdeeds.com"> <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"> <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=".AlarmReceiver" android:enabled="true" /> <service android:name=".NotificationService" android:enabled="true" /> <activity android:name=".ResultActivity" android:excludeFromRecents="true" android:label="@string/notification" android:launchMode="singleTask" android:taskAffinity="" /> </application> </manifest>