1. 程式人生 > 其它 >學習Android之通知

學習Android之通知

建立通知渠道

  為了能讓使用者自主選擇關注應用的哪些通知,Android 8.0系統引入了通知渠道。每條通知對應一個渠道,使用者就可自由選擇開啟哪些通知。通知渠道一旦建立之後就不能再修改了。

  首先需要一個NotificationManager對通知進行管理,通過呼叫Context的getSystemService()方法獲取,此方法接受一個字串引數,傳入Context.NOTIFICATION_SERVICE就可以獲得NotificationManager的例項了。如下:

        val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

  然後需要使用NotificationChannel類來構建通知渠道,並呼叫NotificationManager的createNotificationChannel()方法完成建立。而這個類和這個方法都是Android 8.0系統新增的,所以需要進行版本判斷:

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel("1", "tongzhi", NotificationManager.IMPORTANCE_DEFAULT)
            manager.createNotificationChannel(channel)
        }

 

  建立一個通知渠道至少需要三個引數,如上三個引數分別是渠道ID、渠道名稱、重要等級。渠道ID需保證全域性唯一,渠道名稱是給使用者看到,重要等級主要有IMPORTANCE_HIGH、IMPORTANCE_DEFAULT、IMPORTANCE_LOW、IMPORTANCE_MIN這幾種。

  設定最高等級彈出的通知就會是橫幅,類似於QQ好友發來訊息通知

通知的基本用法

  通知可以在Acitivity、BroadcastReceiver、Service裡建立,但是在Activity裡面用的比較少,畢竟只有當應用進入後臺是才需要用到通知。但是用法是一樣的。

  首先需要一個Builder構造器來建立Notification物件,為了能讓程式能在Android系統各種版本上都能執行,可以使用AndroidX庫中提供的NotificationCompat類來建立Notification物件,如下:

        val notification = NotificationCompat.Builder(this, "1")
            .setContentTitle("title")
            .setContentText("text")
            .setSmallIcon(R.drawable.ic_launcher_background)
            .setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.ic_launcher_background))
            .build()

  Builder的建構函式中接收兩個引數,第一個是context,第二個是渠道ID。然後連綴一系列的設定方法豐富我們的通知。setSmallIcon()方法用於設定通知的小圖示,注意,只能使用純alpha圖層的圖片進行設定。

  現在只需要呼叫NotificationManager的notify()方法就可以讓通知顯示出來了。

        manager.notify(1,notification)

  第一個引數是id,為每個通知指定的id都是不用的。

  現在執行程式後就可以去應用資訊的通知管理裡面看到剛才建立的通知了。

PendingIntent

  通知有了,但是目前還缺少點選事件,這個時候就涉及到了PendingIntent,它和Intent類似,不過它更傾向於在某個合適的時機執行某個動作。

  使用它也很簡單,主要提供了幾個靜態方法用於獲取PendingIntent的例項——getActivity()方法、getBroadcast()方法,getService()方法。這幾個方法接收的引數是一樣,第一個是context,第二個是一般傳入0,第三個是一個Intent物件,可以通過這個物件構建出PendingIntnet的意圖,第四個是確定PendingIntent的行為,有FLAG_ONE_SHOT、FLAG_NO_CREATE、FLAG_CANCEL_CURRENT和FLAG_UPDATE_CURRENT這4種值可選,通常傳入0。

  比如現在來實現點選通知進入另一個Activity,程式碼如下:

        val intent = Intent(this, SecondActivity::class.java)
        val pi = PendingIntent.getActivity(this, 0, intent, 0)

        val notification = NotificationCompat.Builder(this, "1")
            .setContentTitle("title")
            .setContentText("text")
            .setSmallIcon(R.drawable.ic_launcher_background)
            .setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.ic_launcher_background))
            .setContentIntent(pi)
            .build()
        manager.notify(1,notification)

 

  先用Intent表達意圖,再將Intent物件傳入PendingIntent的getActivity()方法中,最後在通知中使用setContentIntent()方法傳入引數即可。

取消通知圖示

  不過目前點選通知後,系統欄上的通知圖示還沒有消失,有兩種方式:

  第一種是在NotificationCompat.Builder中連綴一個setAutoCancel()方法:

        val notification = NotificationCompat.Builder(this, "1")
            ...
            .setAutoCancel(true)
            .build()

 

  第二種是顯式地呼叫NotificationManager的cancel()方法將它取消,前往SecondActivity:

class SecondActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)
        
        val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        manager.cancel(1)

    }
}

  這裡傳入的1就是之前那個通知的id。

 

通知的進階技巧

  NotificationCompat.Builder中提供了非常豐富的API,其中setStyle()方法允許我們構建出富文字的通知內容,它接收一個NotificationCompat.Style引數,這個引數就是用來構建具體的富文字資訊的,如長文字、圖片等。

  一般情況下,如果通知文字內容很長是會被省略號給忽略掉的。如果想要通知中顯示長文字,就通過setStyle()方法,如下:

        val notification = NotificationCompat.Builder(this, "1")
            .setContentTitle("title")
            .setStyle(NotificationCompat.BigTextStyle().bigText("content"))
            ...
            .build()

  這裡需要用setStyle()代替setContentText()方法。BigTextStyle是封裝長文字資訊的,用bigText方法傳入文字即可。

  如果是在通知裡面顯示一張大圖:

        val notification = NotificationCompat.Builder(this, "1")
            .setContentTitle("title")
            .setStyle(NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(resources,
                androidx.loader.R.drawable.notification_icon_background)))
            ...
            .build()

 

  通過BitmapFactory的decodeResource()方法將圖片解析成Bitmap物件,再傳入bigPicture()方法中就可以了。