欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android?Notification使用教程詳解

 更新時間:2022年07月11日 10:11:37   作者:初學者-Study  
這篇文章主要介紹了Android?Notification使用,通知的使用的內(nèi)容還是比較多的,此篇文章將會盡可能詳細的介紹Notification的內(nèi)容,需要的朋友可以參考下

前言

在應用的開發(fā)中,我們必然會接觸到應用通知這個知識,而在通知是隨著Android版本進行不斷變化,為了能在高版本和低版本中使用,就需要開發(fā)者去做適配,也屬于查漏補缺。了解之前,先看一個效果圖吧。

正文

通知的使用的內(nèi)容還是比較多的,此篇文章將會盡可能詳細的介紹Notification的內(nèi)容。

一、Android中通知的變化

1. Android 4.1,API 16

  • 推出了展開式通知模板(稱為通知樣式),可以提供較大的通知內(nèi)容區(qū)域來顯示信息。
  • 用戶可以通過單指向上/向下滑動的手勢來展開通知。還支持以按鈕的形式向通知添加其他操作。
  • 允許用戶在設置中按應用關閉通知。

2. Android 4.4,API 19 和 20

  • 向 API 中添加了通知監(jiān)聽器服務。
  • API 級別 20 中新增了 Android Wear(現(xiàn)已更名為 Wear OS)支持。

3. Android 5.0,API 21

  • 推出了鎖定屏幕和提醒式通知。
  • 用戶現(xiàn)在可以將手機設為勿擾模式,并配置允許哪些通知在設備處于“僅限優(yōu)先事項”模式時打擾他們。
  • 向 API 集添加了通知是否在鎖定屏幕上顯示的方法 (setVisibility()),以及指定通知文本的“公開”版本的方法。
  • 添加了 setPriority() 方法,告知系統(tǒng)通知的“干擾性”(例如,將其設為“高”可使通知以提醒式通知的形式顯示)。
  • 向 Android Wear(現(xiàn)已更名為 Wear OS)設備添加了通知堆棧支持。使用 setGroup() 將通知放入堆棧。請注意,平板電腦和手機尚不支持通知堆棧。通知堆棧以后會稱為組或 Bundle。

4. Android 7.0,API 24

  • 重新設置了通知模板的樣式以強調(diào)主打圖片和頭像。
  • 添加了三個通知模板:一個用于短信應用,另外兩個用于借助展開式選項和其他系統(tǒng)裝飾來裝飾自定義內(nèi)容視圖。
  • 向手持設備(手機和平板電腦)添加了對通知組的支持。使用與 Android 5.0(API 級別 21)中推出的 Android Wear(現(xiàn)已更名為 Wear OS)通知堆棧相同的 API。
  • 用戶可以使用內(nèi)嵌回復功能直接在通知內(nèi)進行回復(他們輸入的文本將轉(zhuǎn)發(fā)到通知的父應用)。

5. Android 8.0,API 26

  • 必須將各個通知放入特定渠道中。
  • 用戶可以按渠道關閉通知,而非關閉來自某個應用的所有通知。
  • 包含有效通知的應用將在主屏幕/啟動器屏幕上相應應用圖標的上方顯示通知“標志”。
  • 用戶可以從抽屜式通知欄中暫停某個通知。您可以為通知設置自動超時時間。
  • 您還可以設置通知的背景顏色。
  • 部分與通知行為相關的 API 已從 Notification 移至 NotificationChannel。例如,在搭載 Android 8.0 及更高版本的設備中,使用 NotificationChannel.setImportance(),而非 NotificationCompat.Builder.setPriority()。

6. Android 12.0,API 31

  • 自定義通知,提供通知模板。
  • 更改了完全自定義通知的外觀和行為。

下面就開始我們的適配之旅吧。

二、創(chuàng)建項目

新建一個名為NotificationStudy的項目,如下圖所示:

點擊Finish完成項目創(chuàng)建,然后在app的build.gradle中的android{}閉包中開啟viewBinding,代碼如下:

	buildFeatures {
        viewBinding true
    }

項目創(chuàng)建好之后,我們首先改動一下activity_main.xml布局。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_show"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="顯示通知"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

放一個按鈕,然后再修改一下MainActivity中的代碼,如下所示:

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        //顯示通知
        binding.btnShow.setOnClickListener {
            
        }
    }
}

這里就是綁定ViewBinding,然后設置按鈕點擊監(jiān)聽,下面我們就要開始做顯示通知的操作了。

三、顯示通知

常規(guī)的通知由三個內(nèi)容構成:標題、內(nèi)容和圖標。在8.0中還有一個通知渠道,所以我們需要先創(chuàng)建一個通知渠道。

① 創(chuàng)建通知渠道

創(chuàng)建通知渠道需要三個參數(shù),渠道ID、渠道名稱和渠道重要性。

首先在MainActivity中增加幾個變量。

	//渠道Id
    private val channelId = "test"
    //渠道名
    private val channelName = "測試通知"
    //渠道重要級
    private val importance = NotificationManagerCompat.IMPORTANCE_HIGH
    //通知管理者
    private lateinit var notificationManager: NotificationManager
    //通知
    private lateinit var notification: Notification
    //通知Id
    private val notificationId = 1

發(fā)送通知首先要通過通知服務得到通知管理者,在onCreate方法中增加如下代碼:

	override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        //獲取系統(tǒng)通知服務
        notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        
        ...
        }
    }

然后是創(chuàng)建通知渠道,在MainActivity中新增如下函數(shù)。

	/**
     * 創(chuàng)建通知渠道
     */
    @RequiresApi(Build.VERSION_CODES.O)
    private fun createNotificationChannel(channelId: String, channelName: String, importance: Int) =
        notificationManager.createNotificationChannel(NotificationChannel(channelId, channelName, importance))

因為通知渠道是Android8.0才有的,因此我們添加一個注解,然后將數(shù)據(jù)構建通知渠道的參數(shù)傳入進來,注意我們通過notificationManager的createNotificationChannel()函數(shù)去創(chuàng)建渠道的,如果notificationManager沒有初始化的話,毫無疑問你的這一行代碼會報錯。

② 初始化通知

通知渠道創(chuàng)建好了,下面我們?nèi)コ跏蓟ㄖ瑯釉贛ainActivity中新增一個initNotification()函數(shù),代碼如下:

	/**
     * 初始化通知
     */
    private fun initNotification() {
        notification = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //創(chuàng)建通知渠道
            createNotificationChannel(channelId,channelName,importance)
            NotificationCompat.Builder(this, channelId)
        } else {
            NotificationCompat.Builder(this)
        }.apply {
            setSmallIcon(R.mipmap.ic_launcher)//小圖標(顯示在狀態(tài)欄)
            setLargeIcon(BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher))//大圖標(顯示在通知上)
            setContentTitle("打工人")//標題
            setContentText("我要搞錢?。?!")//內(nèi)容
        }.build()
    }

這里首先通過版本判斷檢查是否需要創(chuàng)建通知渠道,然后會得到一個通知的Builder,通過Builder去配置通知所需要的基本參數(shù),這里我設置了圖標,標題,內(nèi)容,配置完之后調(diào)用build(),完成通知的構建,最后返回一個notification,現(xiàn)在我們的通知就構建好了。

③ 顯示通知

然后我們再修改一下onCreate中的代碼,如下所示

	override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        //獲取系統(tǒng)通知服務
        notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        //初始化通知
        initNotification()
        //顯示通知
        binding.btnShow.setOnClickListener {
            notificationManager.notify(notificationId, notification)
        }
    }

這里我們調(diào)用了initNotification()函數(shù),然后在點擊按鈕時發(fā)送通知。

	binding.btnShow.setOnClickListener {
		notificationManager.notify(notificationId, notification)
	}

運行一下,效果如下圖所示:

四、通知點擊

在上面的gif中,我們成功顯示了通知,其中我們嘗試去做了點擊通知的動作,但是沒有什么反應,因為這方面的功能還沒有寫,下面我們就來寫。

首先要想一下點擊之后要干嘛?通常來說都是跳轉(zhuǎn)到指定的Activity,我們當前只有一個MainActivity,因此我們需要創(chuàng)建一個。

① 創(chuàng)建目的Activity

我們在com.llw.notification下創(chuàng)建DetailsActivity,對應activity_details.xml布局文件,修改一下布局文件,代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".DetailsActivity">

    <TextView
        android:id="@+id/tv_notification_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

這里增加一個TextView,然后回到DetailsActivity中,修改代碼如下:

class DetailsActivity : AppCompatActivity() {
    private lateinit var binding: ActivityDetailsBinding
    @SuppressLint("SetTextI18n")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityDetailsBinding.inflate(layoutInflater)
        setContentView(binding.root)

        intent?.let {
            binding.tvNotificationContent.text =
                "${it.getStringExtra("title")}\n" + "${it.getStringExtra("content")}"
        }
    }
}

這里的代碼也很簡單,就是獲取傳遞過來的intent中攜帶的參數(shù)顯示在TextView上,假設我們在MainActivity中點擊時傳遞title和content。

② PendingIntent使用

我們經(jīng)常使用Intent,但是接觸PendingIntent是比較少的,PendingIntent可以看作是對Intent的一個封裝,但它不是立刻執(zhí)行某個行為,而是滿足某些條件或觸發(fā)某些事件后才執(zhí)行指定的行為。

PendingIntent獲取有三種方式:Activity、Service和BroadcastReceiver獲取。PendingIntent有一個比較簡單的使用方式,例如我們現(xiàn)在要在Activity中使用,修改initNotification()函數(shù)中的代碼:

	private fun initNotification() {
        val title = "打工人"
        val content = "我要搞錢?。?!"
        // 為DetailsActivity 創(chuàng)建顯式 Intent
        val intent = Intent(this, DetailsActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
            putExtra("title", title).putExtra("content", content)
        }
        val pendingIntent = PendingIntent.getActivity(this, 0, intent, 0)

        notification = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //創(chuàng)建通知渠道
            createNotificationChannel(channelId, channelName, importance)
            NotificationCompat.Builder(this, channelId)
        } else {
            NotificationCompat.Builder(this)
        }.apply {
            setSmallIcon(R.mipmap.ic_launcher)//小圖標(顯示在狀態(tài)欄)
            setLargeIcon(BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher))//大圖標(顯示在通知上)
            setContentTitle(title)//標題
            setContentText(content)//內(nèi)容
            setContentIntent(pendingIntent)//設置內(nèi)容意圖
        }.build()
    }

這里的代碼解釋一下,首先將title、content抽離出來,然后創(chuàng)建intent,再創(chuàng)建pendingIntent 。最后在配置build中設置setContentIntent(pendingIntent),下面我們運行一下。


這里已經(jīng)完成了點擊通知并傳遞的操作,這里還有一個細節(jié)就是常規(guī)來說我們點擊了這個通知表示我們已經(jīng)看到了,或者已經(jīng)知曉了內(nèi)容,因此通知就會消失,而這里通知并沒有消息。

只需要一個配置就可以做到。

setAutoCancel(true)//設置自動取消

添加位置如下圖所示:

運行測試一下就行,我就不用gif說明了。

五、折疊通知

有時候我們設置通知的內(nèi)容可能一行放不下,這個時候就需要收縮和展開通知,讓用戶看到完整的信息。

① 長文本

現(xiàn)在我將content的內(nèi)容修改一下:

val content = "我要搞錢?。?!富強、明主、文明、和諧、自由、平等、公正、法治、愛國、敬業(yè)、誠信、友善"

然后我們什么都不做去運行看看。

這里并沒有顯示多行,同時也沒有那個向下展開的按鈕,內(nèi)容文字做了省略,因此這說明那個展開需要我們?nèi)ピO置。

一行代碼搞定:

setStyle(NotificationCompat.BigTextStyle().bigText(content))

通過設置通知的風格樣式,這里使用的是長文本信息樣式,將content傳遞進去。添加位置如下圖所示:

運行一下看看

② 顯示圖片

有時候我們會在通知中展開時看到圖片,實際上就是使用了另一個樣式,也是一行代碼解決。

setStyle(NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(resources,R.drawable.logo)))//設置樣式

這行代碼的位置和替換掉剛才哪一行,通知只能設置一個樣式,后面設置的樣式會覆蓋掉前面的樣式,這里我們使用大圖片樣式,傳進入一個logo.jpg圖片,你在寫的時候隨便用什么都行,然后我們再運行一下。

六、回復通知

有時候我們的手機收到短信消息,是可以直接回復的。當然了這個功能是需要手動去寫的。流程就是點擊按鈕出現(xiàn)一個通知,通知中回復消息,廣播或服務收到消息后更新通知,然后關閉通知。

① 創(chuàng)建廣播

這里我們先來寫這個接收回復消息的處理,這里用廣播來處理,首先我們需要創(chuàng)建一個廣播,在com.llw.notification下新建一個ReplyMessageReceiver類,里面的代碼如下:

class ReplyMessageReceiver : BroadcastReceiver() {

    private val TAG = ReplyMessageReceiver::class.java.simpleName

    override fun onReceive(context: Context, intent: Intent) {
        //獲取回復消息的內(nèi)容
        val inputContent =
            RemoteInput.getResultsFromIntent(intent)?.getCharSequence("key_text_reply")?.toString()
        Log.d(TAG, "onReceive: $inputContent")
  
        if (inputContent == null) {
            Log.e(TAG, "onReceive: 沒有回復消息!")
            return
        }
        //構建回復消息通知
        val repliedNotification = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationCompat.Builder(context, "reply")
        } else {
            NotificationCompat.Builder(context)
        }.apply {
            setSmallIcon(R.mipmap.ic_launcher)//小圖標(顯示在狀態(tài)欄)
            setContentTitle("1008666")//標題
            setContentText("消息發(fā)送成功!")//內(nèi)容
        }.build()

        val notificationManager =
            context.getSystemService(AppCompatActivity.NOTIFICATION_SERVICE) as NotificationManager
        //發(fā)送通知
        notificationManager.notify(2, repliedNotification)
        //1秒后取消通知
        Timer().schedule(1000){
            notificationManager.cancel(2)
        }
    }
}

這里說明一下:首先是RemoteInput表示遠程輸入,也就是通知欄上輸入框,這里就是獲取輸入框的內(nèi)容,注意"key_text_reply"這個值,我們在構建RemoteInput時使用的值要與這個一致,不一致你在廣播中就拿不到輸入的值。

然后是構建通知了,這里的設置都是常規(guī)操作,渠道id我是寫死的,因此在Activity中創(chuàng)建通知時渠道Id也要一致。最后就是在發(fā)送通知之后加了一個1秒的延時去取消通知,表示收到回復的處理。

廣播是需要在AndroidManifest.xml注冊的,代碼如下:

<receiver android:name=".ReplyMessageReceiver"/>

位置如下:

下面就是要構建回復通知了。因為要區(qū)別于之前的普通通知,所以這里我需要更改一下activity_main.xml中的布局代碼

	<Button
        android:id="@+id/btn_show_reply"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="顯示回復通知"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_show" />

增加一個按鈕,點擊事件后面再寫。

② RemoteInput

為了區(qū)分普通通知和回復通知,在MainActivity中定義一下。

	//回復通知Id
    private val replyNotificationId = 2
    //回復通知
    private lateinit var replyNotification: Notification

下面我們新建一個initReplyNotification()函數(shù),在里面對RemoteInput進行構建。

	private fun initReplyNotification() {
        //遠程輸入
        val remoteInput = RemoteInput.Builder("key_text_reply").setLabel("快速回復").build()
    }

這里RemoteInput的構建也很簡單,最關鍵的就是"key_text_reply",剛才在適配器中已經(jīng)說了,而Label就是一個輸入框的提示文本。

③ PendingIntent

現(xiàn)在我們要通過BroadcastReceiver獲取PendingIntent,在initReplyNotification()函數(shù)中新增代碼:

	private fun initReplyNotification() {
        ...
        //構建回復pendingIntent
        val replyIntent = Intent(this, ReplyMessageReceiver::class.java)
        val pendingIntent = PendingIntent.getBroadcast(this, 0, replyIntent, PendingIntent.FLAG_ONE_SHOT)
    }

④ NotificationCompat.Action

通知動作,我們在輸入框?qū)懭胄畔ⅲ枰粋€按鈕發(fā)送這個按鈕,這個Action就是用來做這個事情的,在initReplyNotification()函數(shù)中新增代碼:

	private fun initReplyNotification() {
        ...
        //構建回復pendingIntent
        val replyIntent = Intent(this, ReplyMessageReceiver::class.java)
        val pendingIntent = PendingIntent.getBroadcast(this, 0, replyIntent, PendingIntent.FLAG_ONE_SHOT)
    }

⑤ 構建通知

下面就是構建通知,在initReplyNotification()函數(shù)中新增代碼:

	private fun initReplyNotification() {
        ...
        //構建通知
        replyNotification = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createNotificationChannel("reply", "回復消息", importance)
            NotificationCompat.Builder(this, "reply")
        } else {
            NotificationCompat.Builder(this)
        }.apply {
            setSmallIcon(R.mipmap.ic_launcher)//小圖標(顯示在狀態(tài)欄)
            setLargeIcon(BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher))//大圖標(顯示在通知上)
            setContentTitle("1008666")//標題
            setContentText("你的賬號已欠費2000元!")//內(nèi)容
            addAction(action)
        }.build()
    }

這里的關鍵就在于這個addAction(action),下面我們運行一下:


然后我們看看日志:

七、橫幅通知

橫幅通知我相信你一定見過,例如收到短信、QQ、微信、釘釘?shù)南?,都會有出現(xiàn)在屏幕頂部,主要是用于提醒用戶的。

首先我們修改布局,在activity_main.xml中新增一個按鈕,代碼如下:

	<Button
        android:id="@+id/btn_show_banner"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="顯示橫幅通知"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_show_reply" />

① 檢查橫幅通知是否打開

首先在MainActivity中定義幾個變量

	//橫幅通知
    private lateinit var bannerNotification: Notification
    //橫幅通知Id
    private val bannerNotificationId = 3
    //開啟橫幅通知返回
    private val bannerLauncher =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
            if (it.resultCode == RESULT_OK) {
                Log.d("TAG", "返回結(jié)果")
            }
        }

然后新增一個openBannerNotification()函數(shù),代碼如下:

	private fun openBannerNotification() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val bannerImportance = notificationManager.getNotificationChannel("banner").importance
        if (bannerImportance == NotificationManager.IMPORTANCE_DEFAULT) {
            val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
                .putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
                .putExtra(Settings.EXTRA_CHANNEL_ID, "banner")
            bannerLauncher.launch(intent); false
        } else true
    } else true

這里通過檢查通知遇到的重要級判斷是否開啟橫幅通知。

② 構建橫幅通知渠道

在MainActivity中新增createBannerNotificationChannel()函數(shù),代碼如下:

	@RequiresApi(Build.VERSION_CODES.O)
    private fun createBannerNotificationChannel(channelId: String, channelName: String, importance: Int) =
        notificationManager.createNotificationChannel(
            NotificationChannel(channelId, channelName, importance).apply {
                description = "提醒式通知"http://渠道描述
                enableLights(true)//開啟閃光燈
                lightColor = Color.BLUE//設置閃光燈顏色
                enableVibration(true)//開啟震動
                vibrationPattern = longArrayOf(0, 1000, 500, 1000)//震動模式
                setSound(null, null)//沒有提示音
            }
        )

這里的內(nèi)容相對于之前來說就多一些,有注釋也好理解。

③ 構建橫幅通知

在MainActivity中新增initBannerNotification()函數(shù),代碼如下:

	private fun initBannerNotification() {
        //構建通知
        bannerNotification = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createBannerNotificationChannel("banner", "提醒消息", importance)
            NotificationCompat.Builder(this, "banner")
        } else {
            NotificationCompat.Builder(this)
        }.apply {
            setSmallIcon(R.mipmap.ic_launcher)//小圖標(顯示在狀態(tài)欄)
            setLargeIcon(BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher))//大圖標(顯示在通知上)
            setContentTitle("落魄Android在線炒粉")//標題
            setContentText("不要9塊9,不要6塊9,只要3塊9。")//內(nèi)容
            setWhen(System.currentTimeMillis())//通知顯示時間
            setAutoCancel(true)//設置自動取消
        }.build()
    }

這里也就是一些常規(guī)的設置。

④ 顯示橫幅通知

最后我們在onCreate()函數(shù)中,新增如下代碼:

		//顯示橫幅通知
        binding.btnShowBanner.setOnClickListener {
            //檢查是否授予訪問權限
            if (openBannerNotification()) {
                notificationManager.notify(bannerNotificationId, bannerNotification)
            }
        }

下面我們運行一下:

OK,這樣就可以了。

八、常駐通知

我們知道有一些通知,當程序運行的時候就會出現(xiàn),例如我們最常見的音樂類App,而且這個通知并不是馬上出現(xiàn)的,在此之前還有很多內(nèi)容要初始化,一切就緒之后出現(xiàn)這個通知,就可以通過通知去控制音樂了。

我們并不需要這種復雜的操作,只有有一個通知能在App啟動的時候顯示出來,并且App進入后臺時,通知也還在。

在MainActivity創(chuàng)建變量。

	//常駐通知
    private lateinit var permanentNotification: 
    //常駐通知Id
    private val permanentNotificationId = 4Notification

然后在MainActivity中新增一個showPermanentNotification()函數(shù),代碼如下:

	private fun showPermanentNotification() {
        //構建回復pendingIntent
        val permanentIntent = Intent(this, MainActivity::class.java)
        val pendingIntent =
            PendingIntent.getActivity(this, 0, permanentIntent, PendingIntent.FLAG_UPDATE_CURRENT)
        //構建通知
        permanentNotification = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createNotificationChannel("permanent", "我一直存在", importance)
            NotificationCompat.Builder(this, "permanent")
        } else {
            NotificationCompat.Builder(this)
        }.apply {
            setSmallIcon(R.mipmap.ic_launcher)//小圖標(顯示在狀態(tài)欄)
            setLargeIcon(BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher))//大圖標(顯示在通知上)
            setContentTitle("你在努力些什么?")//標題
            setContentText("搞錢!搞錢!還是搞錢!")//內(nèi)容
            setWhen(System.currentTimeMillis())//通知顯示時間
            setContentIntent(pendingIntent)
        }.build()
        permanentNotification.flags = Notification.FLAG_ONGOING_EVENT
        notificationManager.notify(permanentNotificationId, permanentNotification)
    }

這里就很簡單了,主要就是去掉通知取消設置,同時設置FLAG_ONGOING_EVENT,另外在點擊通知的時候進入主頁面。在onCreate()函數(shù)中調(diào)用。

運行一下:

可以看到這里我用別的通知顯示出來之后,清理一下,其他通知就沒有了,而常駐通知還在,然后我程序進入后臺,點擊常駐通知,又會啟動到前臺。

九、自定義樣式通知

現(xiàn)在我們使用的都是常規(guī)的樣式通知,實際上我們可以自定義的,就是自定義通知布局,我們先來設計自定義布局的樣式,就做一個音樂通知欄吧,首先是三個圖標。

① 自定義通知布局

在drawable文件夾下新建ic_previous.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="36dp"
    android:height="36dp"
    android:tint="@color/white"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">
    <path
        android:fillColor="@android:color/white"
        android:pathData="M7,6c0.55,0 1,0.45 1,1v10c0,0.55 -0.45,1 -1,1s-1,-0.45 -1,-1L6,7c0,-0.55 0.45,-1 1,-1zM10.66,12.82l5.77,4.07c0.66,0.47 1.58,-0.01 1.58,-0.82L18.01,7.93c0,-0.81 -0.91,-1.28 -1.58,-0.82l-5.77,4.07c-0.57,0.4 -0.57,1.24 0,1.64z" />
</vector>

ic_play.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="36dp"
    android:height="36dp"
    android:tint="@color/white"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">
    <path
        android:fillColor="@android:color/white"
        android:pathData="M8,6.82v10.36c0,0.79 0.87,1.27 1.54,0.84l8.14,-5.18c0.62,-0.39 0.62,-1.29 0,-1.69L9.54,5.98C8.87,5.55 8,6.03 8,6.82z" />
</vector>

ic_next.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="36dp"
    android:height="36dp"
    android:tint="@color/white"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">
    <path
        android:fillColor="@android:color/white"
        android:pathData="M7.58,16.89l5.77,-4.07c0.56,-0.4 0.56,-1.24 0,-1.63L7.58,7.11C6.91,6.65 6,7.12 6,7.93v8.14c0,0.81 0.91,1.28 1.58,0.82zM16,7v10c0,0.55 0.45,1 1,1s1,-0.45 1,-1V7c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1z" />
</vector>

然后在layout下新建一個layout_custom_notification.xml,代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/black"
    android:gravity="center_vertical">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_song_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:text="雨下一整晚"
            android:textColor="@color/white"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/tv_singer"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginTop="4dp"
            android:text="周杰倫"
            android:textColor="@color/white"
            android:textSize="12sp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center">

        <ImageButton
            android:id="@+id/iv_previous"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@null"
            android:src="@drawable/ic_previous" />

        <ImageButton
            android:id="@+id/iv_play"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginEnd="16dp"
            android:background="@null"
            android:src="@drawable/ic_play" />

        <ImageButton
            android:id="@+id/iv_next"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@null"
            android:src="@drawable/ic_next" />
    </LinearLayout>

    <ImageView
        android:id="@+id/iv_avatar"
        android:layout_width="72dp"
        android:layout_height="72dp"
        android:src="@drawable/jay" />
</LinearLayout>

這里要注意一點自定義通知的界面布局只支持LinearLayout、RelativeLayout、FrameLayout,目前不支持ConstraintLayout通知布局里有ConstraintLayout的話,彈通知不會顯示。

jpg圖標用自己的,或者用我源碼里面都可以,然后就很簡單了,回到MainActivity。

② 顯示自定義通知

	//自定義通知
    private lateinit var customNotification: Notification
    //自定義通知Id
    private val customNotificationId = 5

然后創(chuàng)建initCustomNotification()函數(shù),代碼如下:

	@SuppressLint("RemoteViewLayout")
    private fun initCustomNotification() {
        //RemoteView
        val remoteViews = RemoteViews(packageName, R.layout.layout_custom_notification)
        customNotification = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createNotificationChannel("custom", "自定義通知", importance)
            NotificationCompat.Builder(this, "custom")
        } else {
            NotificationCompat.Builder(this)
        }.apply {
            setSmallIcon(R.mipmap.ic_launcher)//小圖標(顯示在狀態(tài)欄)
            setCustomContentView(remoteViews)//設置自定義內(nèi)容視圖
            setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
            setOnlyAlertOnce(true)
            setOngoing(true)
        }.build()
    }

在onCreate中調(diào)用

c

然后我們在activity_main.xml中新增一個按鈕:

	<Button
        android:id="@+id/btn_show_custom"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="顯示自定義通知"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_show_banner" />

最后在MainActivity中的onCreate()函數(shù)中新增按鈕點擊事件,同時點擊調(diào)用通知顯示:

		//顯示自定義通知
        binding.btnShowCustom.setOnClickListener {
            notificationManager.notify(customNotificationId, customNotification)
        }

運行一下:

③ 自定義通知大小

通知布局視圖布局的高度上限為 64 dp,展開后的視圖布局的高度上限為 256 dp,剛才我們只設置了小的通知,那么如果要展開一個大一點的通知,最好是能夠滑動通知的時候有大小變化。

其實很簡單,首先我們同樣要定義一個大一點同通知布局,在layout下新建一個layout_custom_notification_big.xml,代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/black"
    android:gravity="center_vertical">

    <TextView
        android:id="@+id/tv_song_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:text="雨下一整晚"
        android:textColor="@color/white"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tv_singer"
        android:layout_below="@+id/tv_song_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="6dp"
        android:text="周杰倫"
        android:textColor="@color/white"
        android:textSize="16sp" />

    <LinearLayout
        android:layout_marginTop="16dp"
        android:layout_below="@+id/tv_singer"
        android:layout_alignParentStart="true"
        android:layout_toStartOf="@+id/iv_avatar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center">

        <ImageButton
            android:id="@+id/iv_previous"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@null"
            android:src="@drawable/ic_previous" />

        <ImageButton
            android:id="@+id/iv_play"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginEnd="16dp"
            android:background="@null"
            android:src="@drawable/ic_play" />

        <ImageButton
            android:id="@+id/iv_next"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@null"
            android:src="@drawable/ic_next" />
    </LinearLayout>

    <ImageView
        android:layout_alignParentEnd="true"
        android:id="@+id/iv_avatar"
        android:layout_width="144dp"
        android:layout_height="144dp"
        android:src="@drawable/jay" />
</RelativeLayout>

然后我們修改initCustomNotification()函數(shù)中的代碼:

	@SuppressLint("RemoteViewLayout")
    private fun initCustomNotification() {
        //RemoteView
        val remoteViews = RemoteViews(packageName, R.layout.layout_custom_notification)
        val bigRemoteViews = RemoteViews(packageName, R.layout.layout_custom_notification_big)
        customNotification = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createNotificationChannel("custom", "自定義通知", importance)
            NotificationCompat.Builder(this, "custom")
        } else {
            NotificationCompat.Builder(this)
        }.apply {
            setSmallIcon(R.mipmap.ic_launcher)//小圖標(顯示在狀態(tài)欄)
            setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
            setCustomContentView(remoteViews)
            setCustomBigContentView(bigRemoteViews)
            setOnlyAlertOnce(true)
            setOngoing(true)
        }.build()
    }

我們再創(chuàng)建一個RemoteView,然后通過setCustomBigContentView設置一下就可以了,下面運行一下,看看效果。

十、源碼

如果你覺得代碼對你有幫助的話,不妨Fork或者Star一下~
GitHub:NotificationStudy

到此這篇關于Android Notification使用的文章就介紹到這了,更多相關Android Notification使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論