【问题标题】:Firebase console: How to specify click_action for notificationsFirebase 控制台:如何为通知指定 click_action
【发布时间】:2016-11-01 20:30:37
【问题描述】:

我实现了 Firebase 并测试了 Firebase 通知。 当应用程序在前台时我没有问题,我实现了一个扩展 FirebaseMessagingService 的服务并处理 onMessageReceived

中的消息和数据

当应用程序处于后台时我遇到问题,我想发送一个通知以打开特定活动并执行我计划执行的操作,而不仅仅是打开应用程序。

我按照 Firebase 指南中的说明进行操作,但无法启动特定活动。

这里是清单:

<activity android:name=".BasicNotificationActivity">
            <intent-filter>
                <action android:name="OPEN_ACTIVITY_1" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

这里是 Firebase 控制台。我必须在这些字段中写什么才能打开我的“BasicNotificationActivity”?

【问题讨论】:

标签: android firebase firebase-cloud-messaging firebase-notifications


【解决方案1】:

这是这个问题的重复:Firebase FCM notifications click_action payload

但是这个问题的作者接受的答案只是表明 Firebase 控制台不可能,但它是 - 有一个简单的解决方法。 This answer by diidu 对同一个问题解释了我将使用的解决方法。

更新:
详细说明他的答案:

添加一个辅助类(或以某种方式实现startActivity() 方法):

public class ClickActionHelper {
    public static void startActivity(String className, Bundle extras, Context context){
        Class cls;
        try {
            cls = Class.forName(className);
        }catch(ClassNotFoundException e){
            //means you made a wrong input in firebase console
        }
        Intent i = new Intent(context, cls);
        i.putExtras(extras);
        context.startActivity(i);
    }
}

在您应用的启动器活动中,调用一个方法来检查onCreate()onNewIntent() 中的任何新意图(如果使用单顶标志启动活动,则仅调用onNewIntent() 而不是onCreate()) :

@Override
protected void onCreate(Bundle bundle) {
    [...]
    checkIntent(getIntent());
 }

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    [...]
    checkIntent(intent);
}

public void checkIntent(Intent intent) {
       if (intent.hasExtra("click_action")) {
        ClickActionHelper.startActivity(intent.getStringExtra("click_action"), intent.getExtras(), this);
       }
}

onMessageReceived():

 public void onMessageReceived(RemoteMessage remoteMessage) {
     Map<String, String> data = remoteMessage.getData();        
     if (data.containsKey("click_action")) {
         ClickActionHelper.startActivity(data.get("click_action"), null, this);
     }
 }

要使用 firebase 控制台发送通知,请将键值对作为自定义数据,如下所示:

Key: click_action
Value: <fully qualified classname of your activity>

现在,当收到并点击通知时,它将打开您的活动。如果您的应用程序在前台,它也会立即切换到活动 - 询问用户是否想进入此活动可能会很好(通过在onMessageReceived() 中显示一个对话框)。

【讨论】:

  • 在那个答案中,我不明白应该将处理“自定义数据”的代码放在哪里。
  • 我更新了我的答案。这就是处理自定义数据的方式。在后台时,自定义数据位于启动启动器活动的意图的附加内容中。
  • onMessageReceived() 你提到的,应该放在哪个类?在我为 Firebase 实施的服务中?或者在我想要打开通知的新课程中?
  • 您已经实现并在问题中提到的 onMessageReceived() 。这是如何工作的,如果应用程序在后台,数据将在启动启动器活动的意图中,并且您所需的活动将从 onNewIntent 启动(此意图被“拦截”)。如果在前台 onMessageReceived() 将被调用,您可以从那里开始活动
  • @SaeedSharman 是的,对不起,你是对的,我依赖 diidu 的建议,没有检查何时调用 onNewIntent() (developer.android.com/reference/android/app/…)。更新了我的答案:也检查 onCreate() 中的 Intent。但是像你一样检查 onResume() 也可以正常工作:)
【解决方案2】:

这个问题已经 2 岁了。但仍然是相关的。 这就是您可以使用 Firebase 控制台执行此操作的方法(没有 `click_action)。

当您的应用处于后台时,onMessageReceived 将不会被调用。但是,当您在应用处于后台时收到通知时,您将收到 Intent 以及您在 Firebase 控制台中指定的自定义数据。

因此,当用户点击通知the intent 时,将执行以打开您的启动器活动。您可以在启动器活动中通过getIntent().hasExtra("key") 检查数据。其中"key" 是您在控制台中指定的任何键。

检查你是否有那个"key"然后,你可以再做一个Intent并打电话给startActivity

这是我的一个实现,

在我的SplashActivity > OnCreate 上(如果你有一个启动屏幕作为启动器活动,这个方法看起来最好):

if (getIntent().hasExtra("key")){

      Intent intent = new Intent(this, TargetActivity.class);
      startActivity(intent);
      finish();

} else {
      startActivity(new Intent(this, MainActivity.class));
      finish();
}

这只会启动TargetActivity。您可以根据自己的意愿添加任何功能:)

【讨论】:

  • 你太棒了,我烦了2天,终于找到了你的绝招,你是英雄。
【解决方案3】:

我也有像你一样的问题,但我没有得到任何正确的答案 这是我所知道的事实,

  1. onNewIntent

当应用程序处于后台时,此覆盖方法不起作用,因为工作默认操作是 android.intent.action.MAIN

  1. Firebase 控制台

firebase 控制台没有足够的能力来处理 click_action,这意味着当应用程序在后台时,点击操作无法到达应用程序。

  1. 卷曲

Curl 在应用程序后台工作,但不是前台可能是我找不到。

curl --header "Authorization: key=<Colud_Messaging_Server_Key_here>" --header Content-Type:"application/json" https://fcm.googleapis.com/fcm/send  -d "{\"to\":\"dwdfosu6SDs:APA91bFWxZZB2f8AOgP9MG504cy5AhFECHGbYFfIzVixoAfy-ErT0NYQrREg150CbKYBtk3Ywpu7WQuWsQhk-VmoOe-0iDK3ZgaFZNvYxDuixZB8zQp0zydoXhyrMosi5C4eyBb7Ai1z\",\"notification\": {\"title\": \"Click Action Message\",\"text\": \"Sample message\",\"click_action\":\"noti\",\"ticket_download\":\"noti\"}}"

添加小节

<activity
   android:name=".activity.TicketDownload"
   android:exported="true">
   <intent-filter>
      <action android:name="noti" />
      <category android:name="android.intent.category.DEFAULT" />
   </intent-filter>
</activity>

注意:cloud_messaging_server_key 是定位设置>cloudmessaging

如果有任何新的事实请告诉我。

【讨论】:

    【解决方案4】:

    我使用handleIntent(Intent intent) 方法来处理intent 并移动到该特定屏幕。 以下是我的代码,即使应用程序在后台运行也能完美运行:

    FCMMessagingService.java 其中extends FCMMessagingService

    @Override
        public void handleIntent(Intent intent) {
            super.handleIntent(intent);
    
         Intent i = null;
         String value_action = "";
    
          if (intent.getExtras() != null) {
              if (key.equals("click_action")) {
                    value_action = intent.getExtras().getString(key);
                }
    
              i = new Intent(FCMMessagingService.this, MainActivity.class);
              i.putExtra("notificationFlag", value_action);
              i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    
          }
         PendingIntent pendingIntent = PendingIntent.getActivity(this, notifCount, i, PendingIntent.FLAG_ONE_SHOT);
            final int icon = R.mipmap.logo;
        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
    
        Notification notification;
        notification = notificationBuilder.setSmallIcon(icon).setTicker(title)
                .setAutoCancel(true)
                .setContentTitle(title)
                .setContentText(body)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent)
                .setSmallIcon(R.mipmap.notification_icon)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), icon))
                .build();
    
    
        notificationBuilder.setContentTitle(title);
        notificationBuilder.setContentText(body);
        notificationBuilder.setAutoCancel(true);
        notificationBuilder.setSound(defaultSoundUri);
        notificationBuilder.setContentIntent(pendingIntent);
        notificationBuilder.setLargeIcon(BitmapFactory.decodeResource(getResources(), icon));
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            notificationBuilder.setSmallIcon(R.mipmap.logo);
        } else {
            notificationBuilder.setSmallIcon(R.mipmap.logo);
        }
    
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(notifCount, notification);
    
    }
    

    【讨论】:

      猜你喜欢
      • 2022-08-15
      • 1970-01-01
      • 1970-01-01
      • 2016-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-29
      • 2017-01-05
      相关资源
      最近更新 更多