📜  如何使用Firebase Cloud Messaging在Android中推送通知?

📅  最后修改于: 2021-05-13 13:58:50             🧑  作者: Mango

Firebase Cloud Messaging是一种实时解决方案,无需任何费用即可将通知发送到客户端应用程序。 FCM可以可靠地传输高达4Kb负载的通知。在本文中,开发了一个示例应用程序,显示了如何使用此服务。尽管FCM还允许使用应用服务器发送通知,但此处使用Firebase admin SDK。请按照整篇文章实施FCM示例。
推送通知

方法

第1步:将Firebase添加到项目中并获得所需的权限

要将Firebase添加到项目中,请参阅将Firebase添加到Android App。以下是将FCM添加到应用程序的要点。转到工具-> Firebase->云消息传递->设置Firebase Cloud Messaging

  1. 将您的应用程序连接到Firebase:完成创建Firebase项目的三个步骤。
  2. 将FCM添加到应用程序。

由于接收FCM通知需要使用Internet,因此请在标记之间的任何位置向AndroidManifest.xml文件添加以下权限。

步骤2:添加所有必需的可绘制资源

在这里,以下图标已用作可绘制资源。将所有可绘制资源添加到可绘制资源文件夹中。
gfg图标

步骤3:自定义activity_main.xml

在此,应用程序的主屏幕仅包含一个TextView,但是,可以根据要求自定义应用程序。

activity_main.xml


  
    
  


notification.xml


  
    
    
  
        
        
    
  
    
    
  
        
        
  
        
        
  
    
  


AndroidManifest.xml

            
                
            


AndroidManifest.xml


  
    
  
    
        
            
                
  
                
            
        
          
        
            
                
            
        
          
    
  


FirebaseMessageReceiver.java
package com.example.fcmnotfication_gfg;
  
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.widget.RemoteViews;
  
import androidx.core.app.NotificationCompat;
  
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
  
public class FirebaseMessageReceiver
        extends FirebaseMessagingService {
  
    // Override onMessageReceived() method to extract the
    // title and
    // body from the message passed in FCM
    @Override
    public void
    onMessageReceived(RemoteMessage remoteMessage) {
        // First case when notifications are received via
        // data event
        // Here, 'title' and 'message' are the assumed names
        // of JSON
        // attributes. Since here we do not have any data
        // payload, This section is commented out. It is
        // here only for reference purposes.
        /*if(remoteMessage.getData().size()>0){
            showNotification(remoteMessage.getData().get("title"),
                          remoteMessage.getData().get("message"));
        }*/
  
        // Second case when notification payload is
        // received.
        if (remoteMessage.getNotification() != null) {
            // Since the notification is received directly from
            // FCM, the title and the body can be fetched
            // directly as below.
            showNotification(
                    remoteMessage.getNotification().getTitle(),
                    remoteMessage.getNotification().getBody());
        }
    }
  
    // Method to get the custom Design for the display of
    // notification.
    private RemoteViews getCustomDesign(String title,
                                        String message) {
        RemoteViews remoteViews = new RemoteViews(
                getApplicationContext().getPackageName(),
                R.layout.notification);
        remoteViews.setTextViewText(R.id.title, title);
        remoteViews.setTextViewText(R.id.message, message);
        remoteViews.setImageViewResource(R.id.icon,
                R.drawable.gfg);
        return remoteViews;
    }
  
    // Method to display the notifications
    public void showNotification(String title,
                                 String message) {
        // Pass the intent to switch to the MainActivity
        Intent intent
                = new Intent(this, MainActivity.class);
        // Assign channel ID
        String channel_id = "notification_channel";
        // Here FLAG_ACTIVITY_CLEAR_TOP flag is set to clear
        // the activities present in the activity stack,
        // on the top of the Activity that is to be launched
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        // Pass the intent to PendingIntent to start the
        // next Activity
        PendingIntent pendingIntent
                = PendingIntent.getActivity(
                this, 0, intent,
                PendingIntent.FLAG_ONE_SHOT);
  
        // Create a Builder object using NotificationCompat
        // class. This will allow control over all the flags
        NotificationCompat.Builder builder
                = new NotificationCompat
                .Builder(getApplicationContext(),
                channel_id)
                .setSmallIcon(R.drawable.gfg)
                .setAutoCancel(true)
                .setVibrate(new long[]{1000, 1000, 1000,
                        1000, 1000})
                .setOnlyAlertOnce(true)
                .setContentIntent(pendingIntent);
  
        // A customized design for the notification can be
        // set only for Android versions 4.1 and above. Thus
        // condition for the same is checked here.
        if (Build.VERSION.SDK_INT
                >= Build.VERSION_CODES.JELLY_BEAN) {
            builder = builder.setContent(
                    getCustomDesign(title, message));
        } // If Android Version is lower than Jelly Beans,
        // customized layout cannot be used and thus the
        // layout is set as follows
        else {
            builder = builder.setContentTitle(title)
                    .setContentText(message)
                    .setSmallIcon(R.drawable.gfg);
        }
        // Create an object of NotificationManager class to
        // notify the
        // user of events that happen in the background.
        NotificationManager notificationManager
                = (NotificationManager) getSystemService(
                Context.NOTIFICATION_SERVICE);
        // Check if the Android Version is greater than Oreo
        if (Build.VERSION.SDK_INT
                >= Build.VERSION_CODES.O) {
            NotificationChannel notificationChannel
                    = new NotificationChannel(
                    channel_id, "web_app",
                    NotificationManager.IMPORTANCE_HIGH);
            notificationManager.createNotificationChannel(
                    notificationChannel);
        }
  
        notificationManager.notify(0, builder.build());
    }
}


MainActivity.java
package com.example.fcmnotfication_gfg;
  
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
  
public class MainActivity extends AppCompatActivity {
  
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}


步骤4:创建通知布局

创建一个新的notification.xml文件,以设计Notification的布局。之所以说此步骤为可选步骤,是因为也可以直接设置内容和标题,而无需自定义通知的外观,但是,此处的通知具有以下布局。此处的通知包括:

  1. ImageView
  2. 标题的TextView
  3. 消息的TextView。

notification.xml



  
    
    
  
        
        
    
  
    
    
  
        
        
  
        
        
  
    
  

步骤5:创建消息接收类

创建一个FirebaseMessageReceiver。 Java类。此类扩展了FirebaseMessagingService。将以下代码添加到标签之间的AndroidManifest.xml文件中,以将FirebaseMessagingService识别为应用程序中的服务。

AndroidManifest.xml


            
                
            

在这里,为属性“ android:name”分配了扩展FirebaseMessagingService的Java文件的名称,因此请传递类名FirebaseMessageReceiver 。客户端应用程序在后台运行时,除了接收通知之外,此服务还需要执行任何类型的消息处理。它还可用于在前台应用程序中接收通知等。完整的AndroidManifest.xml文件在下面给出。

AndroidManifest.xml



  
    
  
    
        
            
                
  
                
            
        
          
        
            
                
            
        
          
    
  

第6步:使用FirebaseMessageReceiver。 Java类

FirebaseMessageReceiver。 Java类重写onMessageReceived()方法来处理2个事件:

  1. 如果Notification包含任何数据有效负载,即从应用服务器接收到的数据有效负载。
  2. 如果Notification包含任何通知有效负载,即通过Firebase Admin SDK发送。

此方法将RemoteMessage作为参数。 RemoteMessage是扩展对象类并实现Parcelable接口的类。它不过是使用FCM传递的消息的对象。然后,上述方法调用用户定义的方法showNotification() ,该方法又接受两个参数。通过代码本身的注释提供了详细的说明。大于Oreo的Android版本中的通知需要一个通知渠道。

在此示例中,由于设计了自定义通知,因此定义并调用了方法getCustomDesign()来相应地设置资源。此方法设置用于显示接收到的通知的自定义布局。假设仅从通知中接收到标题和正文,它将根据ID适当地映射TextView ,并设置通知的图像资源。该文件的完整代码如下。

FirebaseMessageReceiver。Java

package com.example.fcmnotfication_gfg;
  
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.widget.RemoteViews;
  
import androidx.core.app.NotificationCompat;
  
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
  
public class FirebaseMessageReceiver
        extends FirebaseMessagingService {
  
    // Override onMessageReceived() method to extract the
    // title and
    // body from the message passed in FCM
    @Override
    public void
    onMessageReceived(RemoteMessage remoteMessage) {
        // First case when notifications are received via
        // data event
        // Here, 'title' and 'message' are the assumed names
        // of JSON
        // attributes. Since here we do not have any data
        // payload, This section is commented out. It is
        // here only for reference purposes.
        /*if(remoteMessage.getData().size()>0){
            showNotification(remoteMessage.getData().get("title"),
                          remoteMessage.getData().get("message"));
        }*/
  
        // Second case when notification payload is
        // received.
        if (remoteMessage.getNotification() != null) {
            // Since the notification is received directly from
            // FCM, the title and the body can be fetched
            // directly as below.
            showNotification(
                    remoteMessage.getNotification().getTitle(),
                    remoteMessage.getNotification().getBody());
        }
    }
  
    // Method to get the custom Design for the display of
    // notification.
    private RemoteViews getCustomDesign(String title,
                                        String message) {
        RemoteViews remoteViews = new RemoteViews(
                getApplicationContext().getPackageName(),
                R.layout.notification);
        remoteViews.setTextViewText(R.id.title, title);
        remoteViews.setTextViewText(R.id.message, message);
        remoteViews.setImageViewResource(R.id.icon,
                R.drawable.gfg);
        return remoteViews;
    }
  
    // Method to display the notifications
    public void showNotification(String title,
                                 String message) {
        // Pass the intent to switch to the MainActivity
        Intent intent
                = new Intent(this, MainActivity.class);
        // Assign channel ID
        String channel_id = "notification_channel";
        // Here FLAG_ACTIVITY_CLEAR_TOP flag is set to clear
        // the activities present in the activity stack,
        // on the top of the Activity that is to be launched
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        // Pass the intent to PendingIntent to start the
        // next Activity
        PendingIntent pendingIntent
                = PendingIntent.getActivity(
                this, 0, intent,
                PendingIntent.FLAG_ONE_SHOT);
  
        // Create a Builder object using NotificationCompat
        // class. This will allow control over all the flags
        NotificationCompat.Builder builder
                = new NotificationCompat
                .Builder(getApplicationContext(),
                channel_id)
                .setSmallIcon(R.drawable.gfg)
                .setAutoCancel(true)
                .setVibrate(new long[]{1000, 1000, 1000,
                        1000, 1000})
                .setOnlyAlertOnce(true)
                .setContentIntent(pendingIntent);
  
        // A customized design for the notification can be
        // set only for Android versions 4.1 and above. Thus
        // condition for the same is checked here.
        if (Build.VERSION.SDK_INT
                >= Build.VERSION_CODES.JELLY_BEAN) {
            builder = builder.setContent(
                    getCustomDesign(title, message));
        } // If Android Version is lower than Jelly Beans,
        // customized layout cannot be used and thus the
        // layout is set as follows
        else {
            builder = builder.setContentTitle(title)
                    .setContentText(message)
                    .setSmallIcon(R.drawable.gfg);
        }
        // Create an object of NotificationManager class to
        // notify the
        // user of events that happen in the background.
        NotificationManager notificationManager
                = (NotificationManager) getSystemService(
                Context.NOTIFICATION_SERVICE);
        // Check if the Android Version is greater than Oreo
        if (Build.VERSION.SDK_INT
                >= Build.VERSION_CODES.O) {
            NotificationChannel notificationChannel
                    = new NotificationChannel(
                    channel_id, "web_app",
                    NotificationManager.IMPORTANCE_HIGH);
            notificationManager.createNotificationChannel(
                    notificationChannel);
        }
  
        notificationManager.notify(0, builder.build());
    }
}

步骤7:完成MainActivity。 Java文件

由于在这里activity_main.xml中没有提供太多内容,因此MainActivity文件不需要任何其他代码。

主要活动。Java

package com.example.fcmnotfication_gfg;
  
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
  
public class MainActivity extends AppCompatActivity {
  
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

现在,在您的模拟器或移动设备上运行该应用程序。

步骤8:使用FCM发送通知

  • 转到Firebase控制台,然后选择适当的项目。
  • 选择“云消息传递”
    流式细胞仪
  • 选择发送您的第一条消息。弹出以下窗口。填写详细信息。文本字段是强制性的,其余全部是可选的。您也可以使用链接添加图片或上传图片,但是上传图片会产生额外的存储费用。
    流式细胞仪
  • 在目标部分中,选择应用程序域。
    流式细胞仪
  • 可以立即发送通知,也可以安排将来的某个时间。
    流式细胞仪
  • 其余所有其他字段均为可选,可以保留为空。单击“查看” ,然后单击发布”

输出:在模拟器上运行

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