FCM 点击如何在应用程序处于后台状态时打开用户指定的活动而不是默认活动

Posted

技术标签:

【中文标题】FCM 点击如何在应用程序处于后台状态时打开用户指定的活动而不是默认活动【英文标题】:FCM Tap on how to open a User specified activity instead of default activity when app is in background state 【发布时间】:2019-08-03 17:57:40 【问题描述】:

FCM 工作正常,当应用程序处于前台状态时,设备上会出现通知,当点击通知时,它会重定向到我指定的 Activity,所以它工作正常。

但我的挑战是,当应用程序处于后台状态并且被点击时,它会重定向到默认活动,但我想导航到指定的活动。

这是 MyFirebaseMessagingService 类:

public class MyFirebaseMessagingService extends FirebaseMessagingService 
    private static final String TAG = "MyFirebaseMsgService";
    private String title, messageBody;

    /**
     * Called when message is received.
     *
     * @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
     */
    // [START receive_message]
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) 
        // [START_EXCLUDE]

        if (remoteMessage.getData().size() > 0) 
            Log.d(TAG, "Message data payload: " + remoteMessage.getData());
            if (remoteMessage.getData() != null && remoteMessage.getData().size() > 0) 
                title = remoteMessage.getData().get("title");
                if (TextUtils.isEmpty(title)) title = "Bocawest";
                messageBody = remoteMessage.getData().get("message");
            
            handleNow();
        

        // Check if message contains a notification payload.
        if (remoteMessage.getNotification() != null) 
            Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());

            sendNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody());
        

        // Also if you intend on generating your own notifications as a result of a received FCM
        // message, here is where that should be initiated. See sendNotification method below.
        if (!TextUtils.isEmpty(messageBody))
            sendNotification(title, messageBody);
        //sendNotification(remoteMessage.getNotification().getBody());
        Intent intent = new Intent();
        intent.setAction("com.android.bocawest");
        sendBroadcast(intent);
    
    // [END receive_message]

    /**
     * Handle time allotted to BroadcastReceivers.
     */
    private void handleNow() 
        Log.d(TAG, "Short lived task is done.");
    

    /**
     * Create and show a simple notification containing the received FCM message.
     *
     * @param messageBody FCM message body received.
     */
    private void sendNotification(String title, String messageBody) 
        PendingIntent pendingIntent;
        if (SharedPreference.getBoolean(getApplicationContext(), getApplicationContext().getResources().getString(R.string.sp_isLoginIN))) 
            Intent intent = new Intent(this, NotificationsActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                    PendingIntent.FLAG_UPDATE_CURRENT);
         else 
            Intent intent = new Intent(this, LoginActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                    PendingIntent.FLAG_UPDATE_CURRENT);
        


        String channelId = getString(R.string.default_notification_channel_id);
        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(this, channelId)
                        .setSmallIcon(R.drawable.ic_launcher)
                        .setContentTitle(title)
                        .setContentText(messageBody)
                        .setAutoCancel(true)
                        .setSound(defaultSoundUri)
                        .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        // Since android Oreo notification channel is needed.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) 
            NotificationChannel channel = new NotificationChannel(channelId,
                    "Bocawest",
                    NotificationManager.IMPORTANCE_DEFAULT);
            notificationManager.createNotificationChannel(channel);
        

        notificationManager.notify(0, notificationBuilder.build());
    

注意:NotificationsActivity 是我指定的活动。 HomeActivity 是默认活动

我知道有很多类似的问题,但我没有找到任何特定于我的用例的东西。 请帮帮我。

【问题讨论】:

【参考方案1】:

@Laxman parlapelly 根据 Firebase standered 当您的应用在后台收到通知并且用户点击通知时,它将仅打开默认活动。 如果你想打开你指定的活动,那么你只需要通过你的默认活动。

例如,在您的情况下,当用户点击通知时,它将打开您的 Home 活动,并且您需要从 HomeActivity 的 oncreate 方法打开 NotificationsActivity(以及需要的捆绑包)


当应用程序在后台时点击通知,然后 HomeActivity 的 onCreate() 方法将被调用,因此您可以编写代码来打开通知活动

@Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        animLay = findViewById(R.id.root_lay_la);
        Intent intent = new Intent(this,NotificationActivity.class);
        //intent.putExtra("KEY",getIntent().getStringExtra("data")); if u need to pass data
        startActivity(intent);
    

【讨论】:

是的,我知道这些信息,但我无法在 HomeActivity 的 oncreate 方法中编写打开 NotificationsActivity 所需的那种代码。你能在这里给我这个逻辑吗 如果您在应用程序处于后台时实现通知点击,请检查我编辑的答案 它如何知道它是否来自背景?我的意思是当应用程序登录时它进入 Home Activity,但是根据您在 Home Activity 中的上述代码直接导航到 NotificationActivity 而没有任何逻辑? 它如何知道它是否来自后台?--> \当你的应用程序在前面时,你不需要在托盘中显示通知,我也想你已经接受了广播接收器通知到达时将触发的您各自的活动 这意味着每次应用登录时都会直接进入通知活动而不是主页活动。【参考方案2】:

if(SharedPreference.getBoolean(getApplicationContext(), getApplicationContext().getResources().getString(R.string.sp_isLoginIN))) 把这个逻辑写在 HomeActivity(in onCreate() before setContentView ()) 所以每次用户都将被重定向到 HomeActivity,如果满足上述条件,用户将再次被重定向到 NotificationsActivity 否则将继续使用 HomeActivity

检查 - Navigate to different activities on notification click

【讨论】:

当应用处于后台时,我无法处理通知负载 您必须修改有效负载数据才能做到这一点 - firebase.google.com/docs/cloud-messaging/concept-options 你能解释一下我如何修改有效载荷。真的,我在这上面花了很多时间。现在在我的有效负载中只有通知数据即将到来..数据有效负载是空的,当我从后台处理通知时,通知有效负载将无法工作所以请帮助我... 尝试在数据部分发送所有内容(整个json有效负载)并完全删除通知部分 我可以从哪里发送?【参考方案3】:

这对我有用 - 只需在onMessageReceived()中添加下面的代码

Intent intent = new Intent(this, NotificationsActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |Intent.FLAG_ACTIVITY_CLEAR_TASK);

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "111")
.setSmallIcon(R.drawable.logo)
.setContentTitle(getString(R.string.yhnn))
.setContentText(title)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
// Set the intent that will fire when the user taps the notification
.setContentIntent(pendingIntent)
.setSound(sound)
.setAutoCancel(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);

// notificationId is a unique int for each notification that you must define
notificationManager.notify(5, builder.build());

【讨论】:

以上是关于FCM 点击如何在应用程序处于后台状态时打开用户指定的活动而不是默认活动的主要内容,如果未能解决你的问题,请参考以下文章

当应用程序处于后台状态时,FCM 多个推送通知无法正常工作

如何在接收 fcm 推送通知时处于退出状态时打开应用程序 - REACT NATIVE

当应用程序处于后台状态时,FCM多次推送通知无法正常工作

当应用程序处于后台状态时,Google FCM getIntent 未返回预期数据

当应用程序处于后台状态时,Google FCM getIntent 未返回预期数据

ionic 3:在 android fcm.onNotification() 中,当应用程序处于后台时,点击通知时不会调用