📜  如何在Android中推送通知?

📅  最后修改于: 2021-05-10 17:29:28             🧑  作者: Mango

通知是一条出现在我们应用程序普通用户界面之外的消息。通知可以以不同的格式和位置显示,例如状态栏中的图标,通知抽屉中的更详细的条目等。通过通知,我们可以通知用户有关任何重要更新,应用程序事件的信息。通过单击通知,用户可以打开我们的应用程序的任何活动,或者可以执行某些操作,例如打开任何网页等。

通知的外观如何?

让我们看一下出现在导航抽屉中的通知模板的基本设计。

通知的外观

Part of a Notification 

Method for defining contents 

Type of argument needs to pass into the method

Small Icon setSmallIcon() need to pass a drawable file as an ID that is an Int type.
App Name By default, App Name is provided by the System and we can’t override it.
Time Stamp By default, timeStamp is provided by the System but we can override it by setWhen() method. A Long type of data should be passed.
Title setContentTitle() A String type of data should be passed.
Text setContentText() A String type of data should be passed.
Large Icon setLargeIcon() A Bitmap! type image file data should be passed. 

了解推送通知的一些重要概念

我们将逐步讨论下面提到的所有概念,

  1. 创建基本通知
  2. 建立通知频道
  3. 添加大图标
  4. 使通知可扩展
  5. 使通知可点击
  6. 在我们的通知中添加一个操作按钮

1.创建基本通知

首先创建一个基本通知,我们需要构建一个通知。现在要构建通知,我们必须使用NotificationCompat.Builder()类,在创建类的实例时,我们需要在其中传递活动上下文和通道ID作为参数。请注意,这里我们没有使用Notification.Builder()。 NotificationCompat提供与较高版本(Android 8.0及更高版本)和较低版本(Android 8.0以下)的兼容性。

Kotlin
val nBuilder = NotificationCompat.Builder(this,CHANNEL_ID)
                    .setContentTitle(et1.text.toString())
                    .setContentText(et2.text.toString())
                    .setSmallIcon(R.drawable.spp_notification_foreground)
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                    .build()


Kotlin
val nManager = NotificationManagerCompat.from(this)
// Here we need to set an unique id for each
// notification and the notification Builder
            nManager.notify(1, nBuilder)


Kotlin
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT).apply {
                description = CHANNEL_DESCRIPTION
            }
            val nManager: NotificationManager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            nManager.createNotificationChannel(channel)
        }


Kotlin
// converting a jpeg file to Bitmap file and making an instance of Bitmap!
val imgBitmap=BitmapFactory.decodeResource(resources,R.drawable.gfg_green)
  
// Building notification
val nBuilder= NotificationCompat.Builder(this,CHANNEL_ID)
                    .setContentTitle(et1.text.toString())
                    .setContentText(et2.text.toString())
                    .setSmallIcon(R.drawable.spp_notification_foreground)
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                    // passing the Bitmap object as an argument 
                    .setLargeIcon(imgBitmap)
                    .build()


Kotlin
val imgBitmap = BitmapFactory.decodeResource(resources,R.drawable.gfg_green)
val nBuilder = NotificationCompat.Builder(this,CHANNEL_ID)
                    .setContentTitle(et1.text.toString())
                    .setContentText(et2.text.toString())
                    .setSmallIcon(R.drawable.spp_notification_foreground)
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                    .setLargeIcon(imgBitmap)
                    // Expandable notification
                    .setStyle(NotificationCompat.BigPictureStyle()
                            .bigPicture(imgBitmap)
                            // as we pass null in bigLargeIcon() so the large icon 
                            // will goes away when the notification will be expanded.
                            .bigLargeIcon(null))
                    .build()


Kotlin
// Creating the Implicit Intent to 
// open the home page of GFG   
val intent1= Intent()
        intent1.action=Intent.ACTION_VIEW
        intent1.data=Uri.parse("https://www.geeksforgeeks.org/")


Kotlin
val pendingIntent1=PendingIntent.getActivity(this, 5, intent1, PendingIntent.FLAG_UPDATE_CURRENT)
  
// Here the four parameters are context of activity,
// requestCode,Intent and flag of the pendingIntent respectively
// The request code is used to trigger a
// particular action in application activity
val nBuilder = NotificationCompat.Builder(this,CHANNEL_ID)
                    .setContentTitle(et1.text.toString())
                    .setContentText(et2.text.toString())
                    .setSmallIcon(R.drawable.notifications)
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                    .setLargeIcon(imgBitmap)
                    .setStyle(NotificationCompat.BigPictureStyle()
                            .bigPicture(imgBitmap)
                            .bigLargeIcon(null))
                    // here we are passing the pending intent 
                    .setContentIntent(pendingIntent1)
                    // as we set auto cancel true, the notification 
                    // will disappear after afret clicking it
                    .setAutoCancel(true)
                    .build()


Kotlin
// Creating the Implicit Intent 
// to open the GFG contribution page   
val intent2 = Intent()
        intent2.action = Intent.ACTION_VIEW
        intent2.data = Uri.parse("https://www.geeksforgeeks.org/contribute/")
  
val nBuilder = NotificationCompat.Builder(this,CHANNEL_ID)
                    .setContentTitle(et1.text.toString())
                    .setContentText(et2.text.toString())
                    .setSmallIcon(R.drawable.notifications)
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                    .setLargeIcon(imgBitmap)
                    .setStyle(NotificationCompat.BigPictureStyle()
                            .bigPicture(imgBitmap)
                            .bigLargeIcon(null))
                    .setContentIntent(pendingIntent1)
                    .setAutoCancel(true)
                    // Here we need to pass 3 arguments which are 
                    // icon id, title, pendingIntent respectively
                    // Here we pass 0 as icon id which means no icon
                    .addAction(0,"LET CONTRIBUTE",pendingIntent2)
                    .build()


XML


  
    
  
    
    
  
    
    
  
    
    


Kotlin
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
  
class MainActivity : AppCompatActivity() {
    val CHANNEL_ID = "GFG"
    val CHANNEL_NAME = "GFG ContentWriting"
    val CHANNEL_DESCRIPTION = "GFG NOTIFICATION"
  
    // the String form of link for 
    // opening the GFG home-page
    val link1 = "https://www.geeksforgeeks.org/"
  
    // the String form of link for opening
    // the GFG contribution-page
    val link2 = "https://www.geeksforgeeks.org/contribute/"
    lateinit var et1: EditText
    lateinit var et2: EditText
    lateinit var btn1: Button
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
         
        // Binding Views by their IDs
        et1 = findViewById(R.id.et1)
        et2 = findViewById(R.id.et2)
        btn1 = findViewById(R.id.btn1)
        btn1.setOnClickListener {
              
            // Converting the .png Image file to a Bitmap!
            val imgBitmap = BitmapFactory.decodeResource(resources, R.drawable.gfg_green)
              
            // Making intent1 to open the GFG home page
            val intent1 = gfgOpenerIntent(link1)
              
            // Making intent2 to open The GFG contribution page
            val intent2 = gfgOpenerIntent(link2)
              
            // Making pendingIntent1 to open the GFG home 
            // page after clicking the Notification
            val pendingIntent1 = PendingIntent.getActivity(this, 5, intent1, PendingIntent.FLAG_UPDATE_CURRENT)
              
            // Making pendingIntent2 to open the GFG contribution 
            // page after clicking the actionButton of the notification
            val pendingIntent2 = PendingIntent.getActivity(this, 6, intent2, PendingIntent.FLAG_UPDATE_CURRENT)
              
            // By invoking the notificationChannel() function we 
            // are registering our channel to the System
            notificationChannel()
              
            // Building the notification
            val nBuilder = NotificationCompat.Builder(this, CHANNEL_ID)
                      
                    // adding notification Title
                    .setContentTitle(et1.text.toString())
                      
                    // adding notification Text
                    .setContentText(et2.text.toString())
                      
                    // adding notification SmallIcon
                    .setSmallIcon(R.drawable.ic_android_black_24dp)
                      
                    // adding notification Priority
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                      
                    // making the notification clickable
                    .setContentIntent(pendingIntent1)
                    .setAutoCancel(true)
                      
                    // adding action button
                    .addAction(0, "LET CONTRIBUTE", pendingIntent2)
                      
                    // adding largeIcon
                    .setLargeIcon(imgBitmap)
                      
                    // making notification Expandable
                    .setStyle(NotificationCompat.BigPictureStyle()
                            .bigPicture(imgBitmap)
                            .bigLargeIcon(null))
                    .build()
            // finally notifying the notification
            val nManager = NotificationManagerCompat.from(this)
            nManager.notify(1, nBuilder)
        }
    }
  
    // Creating the notification channel
    private fun notificationChannel() {
        // check if the version is equal or greater
        // than android oreo version
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // creating notification channel and setting 
            // the description of the channel
            val channel = NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT).apply {
                description = CHANNEL_DESCRIPTION
            }
            // registering the channel to the System
            val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }
  
    // The function gfgOpenerIntent() returns 
    // an Implicit Intent to open a webpage
    private fun gfgOpenerIntent(link: String): Intent {
        val intent = Intent()
        intent.action = Intent.ACTION_VIEW
        intent.data = Uri.parse(link)
        return intent
    }
}


现在要传递通知,我们需要一个NotificationManagerCompat类的对象,然后通知它。

科特林

val nManager = NotificationManagerCompat.from(this)
// Here we need to set an unique id for each
// notification and the notification Builder
            nManager.notify(1, nBuilder)

2.创建一个通知渠道

现在要在android 8.0及更高版本上传递通知,我们需要创建一个通知通道。这个通知频道概念来自android 8.0。在这里,每个应用程序可能具有用于不同类型的通知的多个通道,并且每个通道都具有某种类型的通知。在Android 8.0及更高版本上传递通知之前,必须通过将NotificationChannel实例传递给createNotificationChannel()在系统中注册应用的通知通道。

科特林

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT).apply {
                description = CHANNEL_DESCRIPTION
            }
            val nManager: NotificationManager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            nManager.createNotificationChannel(channel)
        }

3.添加大图标

要设置大图标,我们使用setLargeIcon()方法,该方法应用于NotificationCompat.Builder()类的实例。在这种方法中,我们需要传递图像的位图形式。现在要将可绘制文件夹的图像文件(例如jpg,jpeg,png等)转换为位图,我们在Kotlin中使用以下代码

科特林

// converting a jpeg file to Bitmap file and making an instance of Bitmap!
val imgBitmap=BitmapFactory.decodeResource(resources,R.drawable.gfg_green)
  
// Building notification
val nBuilder= NotificationCompat.Builder(this,CHANNEL_ID)
                    .setContentTitle(et1.text.toString())
                    .setContentText(et2.text.toString())
                    .setSmallIcon(R.drawable.spp_notification_foreground)
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                    // passing the Bitmap object as an argument 
                    .setLargeIcon(imgBitmap)
                    .build()

4.使通知可扩展

在通知的简短模板中,无法显示大量信息。因此,我们需要像这样使通知可扩展:

使通知可扩展

为了发出这样的可扩展通知,我们在通知生成器(nBuilder)对象上使用setStyle()方法。在这个扩展的区域中,我们可以显示图像,任何文本,不同的消息等。在我们的应用程序中,我们通过将NotificationCompat.BigPictureStyle类的实例传递给setStyle()方法来添加图像。

科特林

val imgBitmap = BitmapFactory.decodeResource(resources,R.drawable.gfg_green)
val nBuilder = NotificationCompat.Builder(this,CHANNEL_ID)
                    .setContentTitle(et1.text.toString())
                    .setContentText(et2.text.toString())
                    .setSmallIcon(R.drawable.spp_notification_foreground)
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                    .setLargeIcon(imgBitmap)
                    // Expandable notification
                    .setStyle(NotificationCompat.BigPictureStyle()
                            .bigPicture(imgBitmap)
                            // as we pass null in bigLargeIcon() so the large icon 
                            // will goes away when the notification will be expanded.
                            .bigLargeIcon(null))
                    .build()

5.使通知可点击

我们需要使我们的通知可单击以通过单击通知来执行某些操作,例如打开活动或系统设置或任何网页等。现在要执行此类操作,需要有意图(例如,显式或隐式意图)。在我们的应用程序中,我们暗示要打开GFG官方主页。

科特林

// Creating the Implicit Intent to 
// open the home page of GFG   
val intent1= Intent()
        intent1.action=Intent.ACTION_VIEW
        intent1.data=Uri.parse("https://www.geeksforgeeks.org/")

现在没有必要在通知出现时用户立即单击它,用户可以在他/她想要的任何时候单击它,因此我们还需要创建一个PendingIntent实例,该实例基本上使intent操作待定以备将来之用。

科特林

val pendingIntent1=PendingIntent.getActivity(this, 5, intent1, PendingIntent.FLAG_UPDATE_CURRENT)
  
// Here the four parameters are context of activity,
// requestCode,Intent and flag of the pendingIntent respectively
// The request code is used to trigger a
// particular action in application activity
val nBuilder = NotificationCompat.Builder(this,CHANNEL_ID)
                    .setContentTitle(et1.text.toString())
                    .setContentText(et2.text.toString())
                    .setSmallIcon(R.drawable.notifications)
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                    .setLargeIcon(imgBitmap)
                    .setStyle(NotificationCompat.BigPictureStyle()
                            .bigPicture(imgBitmap)
                            .bigLargeIcon(null))
                    // here we are passing the pending intent 
                    .setContentIntent(pendingIntent1)
                    // as we set auto cancel true, the notification 
                    // will disappear after afret clicking it
                    .setAutoCancel(true)
                    .build()

6.在我们的通知中添加一个操作按钮

有时,我们的通知模板上会存在一些操作按钮,用于执行某些操作。

在我们的通知中添加一个操作按钮

在这里,我们还需要一个Intent和一个PendingIntent 。然后,我们需要在构建通知时将PendingIntent的实例传递给addAction()方法。

科特林

// Creating the Implicit Intent 
// to open the GFG contribution page   
val intent2 = Intent()
        intent2.action = Intent.ACTION_VIEW
        intent2.data = Uri.parse("https://www.geeksforgeeks.org/contribute/")
  
val nBuilder = NotificationCompat.Builder(this,CHANNEL_ID)
                    .setContentTitle(et1.text.toString())
                    .setContentText(et2.text.toString())
                    .setSmallIcon(R.drawable.notifications)
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                    .setLargeIcon(imgBitmap)
                    .setStyle(NotificationCompat.BigPictureStyle()
                            .bigPicture(imgBitmap)
                            .bigLargeIcon(null))
                    .setContentIntent(pendingIntent1)
                    .setAutoCancel(true)
                    // Here we need to pass 3 arguments which are 
                    // icon id, title, pendingIntent respectively
                    // Here we pass 0 as icon id which means no icon
                    .addAction(0,"LET CONTRIBUTE",pendingIntent2)
                    .build()

例子

让我们通过创建一个名为GFG_PushNotification的应用程序来讨论所有概念。下面给出了一个示例GIF,以使我们对本文中要做的事情有一个了解。请注意,我们将使用Kotlin语言实施此项目。

Android中的推送通知

分步实施

步骤1:创建一个新项目

要在Android Studio中创建新项目,请参阅如何在Android Studio中创建/启动新项目。请注意,选择Kotlin作为编程语言。根据您的选择选择API级别(这里我们选择了API级别26)。

步骤2:使用activity_main.xml文件

转到activity_main.xml文件,并参考以下代码。以下是activity_main.xml文件的代码。

XML格式



  
    
  
    
    
  
    
    
  
    
    

应用程序UI设计

步骤3:将向量资产插入res目录中的drawable文件夹中

右键单击可绘制的文件夹→新建矢量资产→选择适当的剪贴画→提供适当的名称相应地调整大小→下一步,然后单击完成按钮,如下图所示。

步骤4:使用MainActivity.kt文件

转到MainActivity.kt文件,并参考以下代码。下面是MainActivity.kt文件的代码。在代码内部添加了注释,以更详细地了解代码。

科特林

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
  
class MainActivity : AppCompatActivity() {
    val CHANNEL_ID = "GFG"
    val CHANNEL_NAME = "GFG ContentWriting"
    val CHANNEL_DESCRIPTION = "GFG NOTIFICATION"
  
    // the String form of link for 
    // opening the GFG home-page
    val link1 = "https://www.geeksforgeeks.org/"
  
    // the String form of link for opening
    // the GFG contribution-page
    val link2 = "https://www.geeksforgeeks.org/contribute/"
    lateinit var et1: EditText
    lateinit var et2: EditText
    lateinit var btn1: Button
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
         
        // Binding Views by their IDs
        et1 = findViewById(R.id.et1)
        et2 = findViewById(R.id.et2)
        btn1 = findViewById(R.id.btn1)
        btn1.setOnClickListener {
              
            // Converting the .png Image file to a Bitmap!
            val imgBitmap = BitmapFactory.decodeResource(resources, R.drawable.gfg_green)
              
            // Making intent1 to open the GFG home page
            val intent1 = gfgOpenerIntent(link1)
              
            // Making intent2 to open The GFG contribution page
            val intent2 = gfgOpenerIntent(link2)
              
            // Making pendingIntent1 to open the GFG home 
            // page after clicking the Notification
            val pendingIntent1 = PendingIntent.getActivity(this, 5, intent1, PendingIntent.FLAG_UPDATE_CURRENT)
              
            // Making pendingIntent2 to open the GFG contribution 
            // page after clicking the actionButton of the notification
            val pendingIntent2 = PendingIntent.getActivity(this, 6, intent2, PendingIntent.FLAG_UPDATE_CURRENT)
              
            // By invoking the notificationChannel() function we 
            // are registering our channel to the System
            notificationChannel()
              
            // Building the notification
            val nBuilder = NotificationCompat.Builder(this, CHANNEL_ID)
                      
                    // adding notification Title
                    .setContentTitle(et1.text.toString())
                      
                    // adding notification Text
                    .setContentText(et2.text.toString())
                      
                    // adding notification SmallIcon
                    .setSmallIcon(R.drawable.ic_android_black_24dp)
                      
                    // adding notification Priority
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                      
                    // making the notification clickable
                    .setContentIntent(pendingIntent1)
                    .setAutoCancel(true)
                      
                    // adding action button
                    .addAction(0, "LET CONTRIBUTE", pendingIntent2)
                      
                    // adding largeIcon
                    .setLargeIcon(imgBitmap)
                      
                    // making notification Expandable
                    .setStyle(NotificationCompat.BigPictureStyle()
                            .bigPicture(imgBitmap)
                            .bigLargeIcon(null))
                    .build()
            // finally notifying the notification
            val nManager = NotificationManagerCompat.from(this)
            nManager.notify(1, nBuilder)
        }
    }
  
    // Creating the notification channel
    private fun notificationChannel() {
        // check if the version is equal or greater
        // than android oreo version
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // creating notification channel and setting 
            // the description of the channel
            val channel = NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT).apply {
                description = CHANNEL_DESCRIPTION
            }
            // registering the channel to the System
            val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }
  
    // The function gfgOpenerIntent() returns 
    // an Implicit Intent to open a webpage
    private fun gfgOpenerIntent(link: String): Intent {
        val intent = Intent()
        intent.action = Intent.ACTION_VIEW
        intent.data = Uri.parse(link)
        return intent
    }
}

输出

想要一个节奏更快,更具竞争性的环境来学习Android的基础知识吗?
单击此处前往由我们的专家精心策划的指南,以使您立即做好行业准备!