Android usa la función de encapsulación de la barra de notificaciones de notificaciones

En el desarrollo de aplicaciones de Android, a menudo usamos la función de la barra de notificaciones. Hay muchos tipos de estilos para la barra de notificaciones de Android, incluidos tipos básicos, tipos con barras de progreso, tipos de iconos grandes y tipos de texto grande. En Android 8.0 (Nivel de API 26) ejemplo de código usando la barra de notificación:

        // Create an explicit intent for an Activity in your app
        val intent = Intent(this, AlertDetails::class.java)
        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
        val pendingIntent = PendingIntent.getActivity(this, 0, intent, 0)

        val builder: NotificationCompat.Builder = NotificationCompat.Builder(this, CHANNEL_ID)
                .setSmallIcon(R.drawable.notification_icon)
                .setContentTitle("My notification")
                .setContentText("Hello World!")
                .setPriority(NotificationCompat.PRIORITY_DEFAULT) // Set the intent that will fire when the user taps the notification
                .setContentIntent(pendingIntent)
                .setAutoCancel(true)

        val notificationManager = NotificationManagerCompat.from(this)
        
        // notificationId is a unique int for each notification that you must define
        notificationManager.notify(notificationId, builder.build())
 

Lo siguiente hará un paquete simple para el uso de la notificación, y la lógica funcional específica se puede expandir

Primero mira el uso específico:

package com.let.myapplication

import android.app.PendingIntent
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity(), View.OnClickListener {
    private val TAG = MainActivity::class.java.simpleName
    var tvImMsg: TextView? = null
    var tvSysMsg: TextView? = null
    private val userArray = arrayOf("Cyra", "Morgen", "Iris", "Mia")
    private val messageArray = arrayOf("我发表了新的美食文章", "我更新了我的相册", "我在FaceBook申请了账号", "我做了一个好看的小视频")
    private val sysMessageArray = arrayOf("有新的系统版本可以升级", "收到新的资讯内容", "为你推荐周边美食、娱乐活动", "最新最火爆的游戏")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        tvImMsg = findViewById(R.id.textview_im_msg)
        tvSysMsg = findViewById(R.id.textview_sys_msg)
        tvImMsg!!.setOnClickListener(this)
        tvSysMsg!!.setOnClickListener(this)
    }

    override fun onClick(v: View) {
        when (v.id) {
            R.id.textview_im_msg -> notifyImMessage()
            R.id.textview_sys_msg -> notifySysMessage()
            else -> {}
        }
    }

    private fun notifyImMessage() {
        val uIndex = (Math.random() * userArray.size).toInt()
        val mIndex = (Math.random() * messageArray.size).toInt()
        val userName = userArray[uIndex]
        val content = messageArray[mIndex]
        val key = "ImMessage#$userName"
        val requestCode = NotifyManager.getInstance(this@MainActivity).initNotifyId(key)
        Log.d(TAG, "method:notifyReceivedMessage#key=$key, requestCode=$requestCode")
        val intent = Intent(this@MainActivity, NotificationMsgActivity::class.java)
        intent.putExtra("msgContent", "$userName:\n\n$content")
        val pendingIntent = PendingIntent.getActivity(this@MainActivity, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT)
        val defaultNotifyBuilder = DefaultNotifyBuilder(userName, content)
                .setChannelId(resources.getString(R.string.channel_001))
                .setContentIntent(pendingIntent)
        NotifyManager.getInstance(this@MainActivity).showDefaultNotification(key, defaultNotifyBuilder)
    }

    private fun notifySysMessage() {
        val key = "SysMessage#系统消息"
        val mIndex = (Math.random() * sysMessageArray.size).toInt()
        val content = sysMessageArray[mIndex]
        val requestCode = NotifyManager.getInstance(this@MainActivity).initNotifyId(key)
        Log.d(TAG, "method:notifyReceivedMessage#key=$key, requestCode=$requestCode")
        val intent = Intent(this@MainActivity, NotificationMsgActivity::class.java)
        intent.putExtra("msgContent", "系统消息:\n\n$content")
        val pendingIntent = PendingIntent.getActivity(this@MainActivity, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT)
        val defaultNotifyBuilder = DefaultNotifyBuilder("系统消息", content)
                .setChannelId(resources.getString(R.string.channel_002))
                .setContentIntent(pendingIntent)
        NotifyManager.getInstance(this@MainActivity).showDefaultNotification(key, defaultNotifyBuilder)
    }
}

Algunos parámetros en DefaultNotifyBuilder tendrán valores predeterminados:

package com.let.myapplication

import android.app.PendingIntent
import androidx.core.app.NotificationCompat

/**
 * @author let
 */
class DefaultNotifyBuilder {
    @JvmField
    var channelId: String? = null
    @JvmField
    var smallIcon = R.drawable.ic_launcher_foreground
    @JvmField
    var contentTitle: CharSequence = "小蜗牛Tech"
    @JvmField
    var contentText: CharSequence
    @JvmField
    var ticker: CharSequence? = null
    var flag = NotificationCompat.FLAG_AUTO_CANCEL
    @JvmField
    var priority = NotificationCompat.PRIORITY_HIGH
    @JvmField
    var `when` = System.currentTimeMillis()
    @JvmField
    var contentIntent: PendingIntent? = null
    @JvmField
    var autoCancel = true
    @JvmField
    var sound = false
    @JvmField
    var vibrate = false
    @JvmField
    var lights = false

    constructor(contentText: CharSequence) {
        this.contentText = contentText
    }

    constructor(contentTitle: CharSequence, contentText: CharSequence) {
        this.contentTitle = contentTitle
        this.contentText = contentText
    }

    constructor(smallIcon: Int, contentTitle: CharSequence, contentText: CharSequence) {
        this.smallIcon = smallIcon
        this.contentTitle = contentTitle
        this.contentText = contentText
    }

    fun setChannelId(channelId: String?): DefaultNotifyBuilder {
        this.channelId = channelId
        return this
    }

    fun setTicker(ticker: CharSequence?): DefaultNotifyBuilder {
        this.ticker = ticker
        return this
    }

    fun setFlag(flag: Int): DefaultNotifyBuilder {
        this.flag = flag
        return this
    }

    fun setPriority(priority: Int): DefaultNotifyBuilder {
        this.priority = priority
        return this
    }

    fun setWhen(`when`: Long): DefaultNotifyBuilder {
        this.`when` = `when`
        return this
    }

    fun setContentIntent(contentIntent: PendingIntent?): DefaultNotifyBuilder {
        this.contentIntent = contentIntent
        return this
    }

    fun setAutoCancel(autoCancel: Boolean): DefaultNotifyBuilder {
        this.autoCancel = autoCancel
        return this
    }

    fun setSound(sound: Boolean): DefaultNotifyBuilder {
        this.sound = sound
        return this
    }

    fun setVibrate(vibrate: Boolean): DefaultNotifyBuilder {
        this.vibrate = vibrate
        return this
    }

    fun setLights(lights: Boolean): DefaultNotifyBuilder {
        this.lights = lights
        return this
    }
}

BaseNotifyBuilder ensamblará los parámetros básicos:

package com.let.myapplication

import android.app.Notification
import android.content.Context
import android.os.Build
import android.text.TextUtils
import android.util.Log
import androidx.core.app.NotificationCompat
import com.let.myapplication.BaseNotifyBuilder

/**
 * @author let
 */
open class BaseNotifyBuilder(protected var defaultBuilder: DefaultNotifyBuilder) {
    @JvmField
    protected var notifyBuilder: NotificationCompat.Builder? = null
    open fun build(context: Context?): Notification? {
        notifyBuilder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationCompat.Builder(context!!, defaultBuilder.channelId!!)
        } else {
            NotificationCompat.Builder(context!!)
        }
        Log.d(TAG, "method:build#defaultBuilder=$defaultBuilder")
        // 设置顶部状态栏的小图标
        notifyBuilder!!.setSmallIcon(defaultBuilder.smallIcon)
        // 设置通知中心的标题
        notifyBuilder!!.setContentTitle(defaultBuilder.contentTitle)
        // 设置通知中心中的内容
        val contentText = defaultBuilder.contentText
        if (!TextUtils.isEmpty(contentText)) {
            notifyBuilder!!.setContentText(defaultBuilder.contentText)
        }
        val contentIntent = defaultBuilder.contentIntent
        if (contentIntent != null) {
            notifyBuilder!!.setContentIntent(contentIntent)
        }
        var defaults = 0
        val sound = defaultBuilder.sound
        val vibrate = defaultBuilder.vibrate
        val lights = defaultBuilder.lights
        if (sound) {
            defaults = defaults or Notification.DEFAULT_SOUND
        }
        if (vibrate) {
            defaults = defaults or Notification.DEFAULT_VIBRATE
        }
        if (lights) {
            defaults = defaults or Notification.DEFAULT_LIGHTS
        }
        if (defaults != 0) {
            notifyBuilder!!.setDefaults(defaults)
        }
        val ticker = defaultBuilder.ticker
        if (!TextUtils.isEmpty(ticker)) {
            notifyBuilder!!.setTicker(defaultBuilder.ticker)
        }
        notifyBuilder!!.setAutoCancel(defaultBuilder.autoCancel)
        notifyBuilder!!.setWhen(defaultBuilder.`when`)
        notifyBuilder!!.priority = defaultBuilder.priority
        return notifyBuilder!!.build()
    }

    companion object {
        private val TAG = BaseNotifyBuilder::class.java.simpleName
    }
}

MyNotificationManager usa un patrón singleton

A partir de Android 8.0 (API nivel 26), todas las notificaciones deben tener asignado un canal, de lo contrario, la notificación no se mostrará. Al agrupar las notificaciones en diferentes canales, los usuarios pueden deshabilitar canales de notificación específicos para su aplicación (en lugar de deshabilitar todas sus notificaciones), así como también controlar las opciones visuales y audibles para cada canal, todo dentro del sistema Android. La configuración está completa. Los usuarios también pueden mantener presionada una notificación para cambiar el comportamiento del canal asociado.

package com.let.myapplication

import android.app.NotificationChannel
import android.app.NotificationChannelGroup
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import android.util.Log
import com.let.myapplication.NotifyManager
import java.util.concurrent.atomic.AtomicInteger

/**
 * @author let
 *
 *
 * 封装通知栏实现,对于某些相关属性的处理逻辑,可根据具体的需求调整完善
 */
class NotifyManager private constructor() {
    /**
     * 通知栏的消息对象的自增Id
     */
    private val mInitialNotifyId: AtomicInteger? = AtomicInteger(0)

    /**
     * 全局通知栏的Id,不同消息对象,对应自身唯一的全局Id
     */
    @Volatile
    private var mGlobalNotifyIdMap: MutableMap<Any, Int>? = null
    val initialNotifyId: Int
        get() = mInitialNotifyId?.toInt() ?: 0
    val globalNotifyIdMap: Map<Any, Int>?
        get() = mGlobalNotifyIdMap

    /**
     * IM消息的key的形式:key = "ImMessage"
     *
     * @param key
     * @return 返回对应的id
     */
    fun initNotifyId(key: Any): Int {
        Log.d(TAG, "method:initNotifyId#key=$key")
        if (mGlobalNotifyIdMap == null) {
            mGlobalNotifyIdMap = HashMap()
        }
        val notifyId = mGlobalNotifyIdMap!![key]
        Log.d(TAG, "method:initNotifyId#mGlobalNotifyIdMap=$mGlobalNotifyIdMap")
        Log.d(TAG, "method:initNotifyId#notifyId=$notifyId")
        return notifyId ?: putNotifyId(key)
    }

    /**
     * 保证每次往集合[.mGlobalNotifyIdMap]中put新值时,ID都是自增的
     *
     *
     * IM消息的key的形式:key = "ImMessage"
     *
     * @param key
     * @return
     */
    private fun putNotifyId(key: Any): Int {
        Log.d(TAG, "method:putNotifyId#key=$key")
        if (mGlobalNotifyIdMap != null) {
            val value = mInitialNotifyId!!.incrementAndGet()
            Log.d(TAG, "method:putNotifyId#mInitialNotifyId.incrementAndGet#value=$value")
            mGlobalNotifyIdMap!![key] = value
            Log.d(TAG, "method:putNotifyId#mGlobalNotifyIdMap=$mGlobalNotifyIdMap")
            return value
        }
        return 0
    }

    private fun notify(key: Any, builder: BaseNotifyBuilder) {
        val notifyId = initNotifyId(key)
        notificationManager!!.notify(notifyId, builder.build(mContext))
    }

    val channelGroupList: List<NotificationChannelGroup>?
        get() = mChannelGroupList

    fun showDefaultNotification(key: Any, defaultBuilder: DefaultNotifyBuilder?) {
        val builder = BaseNotifyBuilder(defaultBuilder!!)
        notify(key, builder)
    }

    fun showProgressNotification(key: Any, progress: Int, max: Int, interminate: Boolean, defaultBuilder: DefaultNotifyBuilder?) {
        val builder = ProgressNotifyBuilder(defaultBuilder)
        notify(key, builder)
    }

    fun showLargeIconNotification(key: Any, largeIconId: Int, defaultBuilder: DefaultNotifyBuilder?) {
        val builder: LargeIconNotifyBuilder = LargeIconNotifyBuilder(defaultBuilder).setLargeIcon(largeIconId)
        notify(key, builder)
    }

    fun showBigTextNotification(key: Any, bigText: String?, defaultBuilder: DefaultNotifyBuilder?) {
        val builder = BigTextNotifyBuilder(defaultBuilder).setBigText(bigText)
        notify(key, builder)
    } // ……………… 根据需要完善其它通知栏样式 ………………

    companion object {
        private val TAG = NotifyManager::class.java.simpleName
        private var sInstance: NotifyManager? = null
        var notificationManager: NotificationManager? = null
            get() = Companion.field
            private set
        private var mChannelGroupList: MutableList<NotificationChannelGroup>? = null
        private var mContext: Context? = null
        fun getInstance(context: Context): NotifyManager? {
            if (sInstance == null) {
                synchronized(NotifyManager::class.java) {
                    if (sInstance == null) {
                        sInstance = NotifyManager()
                        mContext = context.applicationContext
                        if (notificationManager == null) {
                            notificationManager = mContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
                            initNotifyChannel()
                        }
                    }
                }
            }
            return sInstance
        }

        private fun initNotifyChannel() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                if (mChannelGroupList == null) {
                    mChannelGroupList = ArrayList()
                }
                mChannelGroupList!!.add(NotificationChannelGroup(mContext!!.resources.getString(R.string.groupId_001), "系统消息"))
                mChannelGroupList!!.add(NotificationChannelGroup(mContext!!.resources.getString(R.string.groupId_002), "IM消息"))
                notificationManager!!.createNotificationChannelGroups(mChannelGroupList!!)
                val channel1 = NotificationChannel(mContext!!.resources.getString(R.string.channel_001), "系统消息", NotificationManager.IMPORTANCE_HIGH)
                val channel2 = NotificationChannel(mContext!!.resources.getString(R.string.channel_002), "IM消息", NotificationManager.IMPORTANCE_HIGH)
                channel1.group = mContext!!.resources.getString(R.string.groupId_001)
                channel2.group = mContext!!.resources.getString(R.string.groupId_002)
                notificationManager!!.createNotificationChannel(channel1)
                notificationManager!!.createNotificationChannel(channel2)
            }
        }
    }
}

Lógica de procesamiento de otros constructores de estilo, como BigTextNotifyBuilder:

package com.let.myapplication

import android.app.Notification
import android.content.Context
import androidx.core.app.NotificationCompat

/**
 * @author let
 */
class BigTextNotifyBuilder(defaultBuilder: DefaultNotifyBuilder?) : BaseNotifyBuilder(defaultBuilder!!) {
    var mBigText: String? = null
    var mBigTextStyle: NotificationCompat.BigTextStyle? = null
    fun setBigText(bigText: String?): BigTextNotifyBuilder {
        mBigText = bigText
        mBigTextStyle = NotificationCompat.BigTextStyle()
                .bigText(bigText)
        return this
    }

    override fun build(context: Context?): Notification? {
        super.build(context)
        notifyBuilder!!.setStyle(mBigTextStyle)
        return notifyBuilder!!.build()
    }
}

Supongo que te gusta

Origin blog.csdn.net/qq_36162336/article/details/128683839
Recomendado
Clasificación