20

我实现了 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”?

Firebase 控制台

4

4 回答 4

22

这是此问题的副本:Firebase FCM 通知 click_action 有效负载

但是这个问题的作者接受的答案只是表明使用 Firebase 控制台是不可能的,但它是 - 有一个简单的解决方法。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()使用单顶标志启动 Activity 时才调用)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())。

于 2016-07-01T15:33:02.900 回答
6

这个问题是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. 您可以根据自己的意愿为此添加任何功能:)

于 2019-01-19T08:14:32.860 回答
1

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

  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\"}}"

添加 Minifest

<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

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

于 2016-07-10T07:13:32.730 回答
1

我已经使用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);

}
于 2017-12-08T11:37:52.040 回答