Simple use of Android notification Notification

In the development of Android applications, the development needs of notifications will inevitably be encountered. This article mainly talks about the simple and basic use of notifications in Android, mainly including creating notification channels, initializing notifications, displaying notifications, displaying picture notifications, notification clicks, and Cooperate with WorkManager to send delay notifications.

Demo download

Create a notification channel

First, create several constants and variables, among which the channel name is the name of the notification channel that will be displayed in the mobile phone settings-notification corresponding to the app, and is generally named based on the notification function.

    companion object {
        //渠道Id
        private const val CHANNEL_ID = "渠道Id"

        //渠道名
        private const val CHANNEL_NAME = "渠道名-简单通知"

        //渠道重要级
        private const val CHANNEL_IMPORTANCE = NotificationManager.IMPORTANCE_DEFAULT
    }

    private lateinit var context: Context

    //Notification的ID
    private var notifyId = 100
    private lateinit var manager: NotificationManager
    private lateinit var builder: NotificationCompat.Builder

Then obtain the system notification service and create a notification channel. Since the notification channel is only available in Android 8.0, a version judgment is added:

        //获取系统通知服务
        manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        //创建通知渠道,Android8.0及以上需要
        createChannel()
    private fun createChannel() {
        //创建通知渠道,Android8.0及以上需要
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            return
        }
        val notificationChannel = NotificationChannel(
            CHANNEL_ID,
            CHANNEL_NAME,
            CHANNEL_IMPORTANCE
        )
        manager.createNotificationChannel(notificationChannel)
    }

initialization notification

First generate NotificationCompat.Builder, and then initialize the general configuration of Notification Builder:

        builder = NotificationCompat.Builder(context.applicationContext, CHANNEL_ID)
        initNotificationBuilder()
    /**
     * 初始化通知Builder的通用配置
     */
    private fun initNotificationBuilder() {
        builder
            .setAutoCancel(true) //设置这个标志当用户单击面板就可以让通知自动取消
            .setSmallIcon(R.drawable.ic_reminder) //通知的图标
            .setWhen(System.currentTimeMillis()) //通知产生的时间,会在通知信息里显示
            .setDefaults(Notification.DEFAULT_ALL)
    }

In addition, the builder also has methods such as setVibrate, setSound, and setStyle, which can be configured as needed.

show notification

Set the title and content that need to be notified to the builder, and then generate a notification notification through builder.build(), and the manager.notify() method will send the notification.

    fun configNotificationAndSend(title: String, content: String){
        builder.setContentTitle(title)
            .setContentText(content)
        val notification = builder.build()
        //发送通知
        manager.notify(notifyId, notification)
        //id自增
        notifyId++
    }

The simplest notification is displayed so far the above three steps are completed.
The effect is as follows:
image.png

Show image notification

When there are too many lines to display the notification content, you can set

builder.setStyle(NotificationCompat.BigTextStyle().bigText(content)) //设置可以显示多行文本

This allows the notification to shrink and expand to display multiple lines of text.
In addition, setStyle can also set notifications in the form of pictures:

setStyle(NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(resources,R.drawable.logo)))//设置图片样式

The effect is as follows:
image.png

notification click

The notification so far is only displayed, because builder.setAutoCancel(true) is set, the notification will disappear automatically after clicking the notification, and there is no other operation.
Set setContentIntent(PendingIntent) to the builder to notify other operations after clicking. PendingIntent can be regarded as an encapsulation of Intent, but it does not execute a certain behavior immediately, but executes the specified behavior after certain conditions are met or certain events are triggered. There are three ways to obtain PendingIntent: Activity, Service and BroadcastReceiver. It can be obtained through the corresponding methods PendingIntent.getActivity, PendingIntent.getBroadcast, and PendingIntent.getService.
Here is an example of PendingIntent.getBroadcast and PendingIntent.getActivity

PendingIntent.getBroadcast

First create a BroadcastReceiver:

class NotificationHandleReceiver : BroadcastReceiver() {
    companion object {
        const val NOTIFICATION_HANDLE_ACTION = "notification_handle_action"
        const val NOTIFICATION_LINK = "notificationLink"
        const val TAG = "NotificationReceiver"
    }

    override fun onReceive(context: Context, intent: Intent?) {
        if (intent?.action == NOTIFICATION_HANDLE_ACTION) {
            val link = intent.getStringExtra(NOTIFICATION_LINK)
        }
    }
}

Don't forget that you also need to statically register BroadcastReceiver in the manifest file:

    <receiver
        android:name=".NotificationHandleReceiver"
        android:exported="false">
        <intent-filter>
            <action android:name="notification_handle_action" />
        </intent-filter>
    </receiver>

Then create an Intent of the BroadcastReceiver above, and the operations that need to be recognized after the corresponding click notification is passed in by intent.putExtra:

   fun generateDefaultBroadcastPendingIntent(linkParams: (() -> String)?): PendingIntent {
        val intent = Intent(NotificationHandleReceiver.NOTIFICATION_HANDLE_ACTION)
        intent.setPackage(context.packageName)
        linkParams?.let {
            val params = it.invoke()
            intent.putExtra(NotificationHandleReceiver.NOTIFICATION_LINK, params)
        }
        return PendingIntent.getBroadcast(
            context,
            notifyId,
            intent,
            PendingIntent.FLAG_IMMUTABLE
        )
    }

The PendingIntent generated in this way is then builder.setContentIntent(pendingIntent). After we click on the notification, the onReceive of NotificationHandleReceiver will receive the information, and follow-up operations can be processed according to the information.

PendingIntent. getActivity

Activity's PendingIntent is used to jump to the specified activity, create an Intent for jumping to the activity (same as the Intent for ordinary page jumping), and it is also the same operation that needs to be recognized after the corresponding click notification is passed in intent.putExtra above:

        val intent = Intent(this, XXXX::class.java).apply {
            putExtra("title", title).putExtra("content", content)
        }
        return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)

The PendingIntent generated in this way is then builder.setContentIntent(pendingIntent). After we click on the notification, it will jump to the corresponding activity page, and then the information will be received in the intent, and follow-up operations can be processed according to the information.

PendingIntent feature of Android12

Behavior change: Apps targeting Android 12
Check out the above features about Android 12
There are two features about PendingIntent on the Android 12 platform:

  • One is the variability of the pending intent, which must  be specifiedPendingIntent for each  object created by the application . This is why the flag needs to be set to PendingIntent.FLAG_IMMUTABLE when creating the PendingIntent above.
  • The second is the notification trampoline limitation. Apps targeting Android 12 or higher cannot start activities from services or broadcast receivers used as notification trampolines. In other words, your app cannot call within a service or broadcast receiver when  the user taps the notification or an action buttonstartActivity() in the notification . So when you need to click on the notification to achieve activity jump, you need to use PendingIntent.getActivity instead of PendingIntent.getBroadcast, and then implement activity jump in BroadcastReceiver. The latter method will be used in applications with Android 12 or later as the target platform Is limited.

Cooperate with WorkManager to send delay notification

Cooperating with WorkManager, you can send delay notifications, mainly through the delay feature of OneTimeWorkRequest.
Create a delayed OneTimeWorkRequest and add it to the WorkManager queue:

    fun sendWorkRequest(
        context: Context,
        reminderId: Int,
        title: String,
        content: String,
        link: String,
        triggerTime: Long
    ): OneTimeWorkRequest {
        val duration = triggerTime - System.currentTimeMillis()
        val data =
            Data.Builder().putInt(REMINDER_WORKER_DATA_ID, reminderId).putString(REMINDER_WORKER_DATA_TITLE, title)
                .putString(REMINDER_WORKER_DATA_CONTENT, content).putString(REMINDER_WORKER_DATA_LINK, link)
                .build()
        val uniqueWorkName =
            "reminderData_${reminderId}"
        val request = OneTimeWorkRequest.Builder(ReminderWorker::class.java)
            .setInitialDelay(duration, TimeUnit.MILLISECONDS)
            .setInputData(data)
            .build()
        WorkManager.getInstance(context)
            .enqueueUniqueWork(uniqueWorkName, ExistingWorkPolicy.REPLACE, request)
        return request
    }

Then get the data in the doWork method and send and display the notification above. The specific use of OneTimeWorkRequest will not be explained in detail in this article. When it is necessary to send delayed notifications, it can be realized by cooperating with WorkManager.

Android13 notification permission

On the latest Android 13 (API level 33), permission restrictions have been added to notifications. For details, see the official description:
Notification runtime permissions

Guess you like

Origin blog.csdn.net/yuantian_shenhai/article/details/126451477