当应用程序在后台/未运行时,点击通知无法打开特定的活动。

9
通知点击事件只有在应用程序打开并且执行通知点击时才会启动指定的活动。如果应用程序在后台/未运行并执行通知点击,则应用程序的MainActivity将打开。简而言之,它就像按照活动堆栈正常打开应用程序,而不是打开PendingIntent中指定的活动。
我想根据其类型将通知点击重定向到两个不同的活动(ApprovalDetailActivity和ConversationDetailActivity)。
我正在使用FCM进行推送通知。我在此处粘贴我的清单文件和FCMListener文件。请帮帮我。
MyFirebaseMessagingService.java中的sendNotification()函数。
private void sendNotification(String messageBody)
    {
        Intent intent;
        System.out.println("----message body: " + messageBody);
        if(notificationBundle.getCategory().equalsIgnoreCase(Master.KEY_PUSH_NOTIFICATION_CONVERSATION))
        {
            intent = new Intent(this, ConversationDetailActivity.class);
            /*Conversation conversation = Master.notificationBundle.getConversation();
            Master.conversationsList = new ArrayList<>();
            Master.conversationsList.add(conversation);*/
        }
        else
        {
            intent = new Intent(this, ApprovalDetailActivity.class);
            if(notificationBundle.getApprovalType().equals("I"))
                intent.putExtra(Master.KEY_WHICH_APPROVAL, Master.KEY_VERIFICATIONS);
            else if(notificationBundle.getApprovalType().equals("A"))
                intent.putExtra(Master.KEY_WHICH_APPROVAL, Master.KEY_APPROVALS);
            else
                intent.putExtra(Master.KEY_WHICH_APPROVAL, Master.KEY_COMPLETED);

            intent.putExtra(Master.KEY_IS_FROM_CONVERSATION, false);
        }

        intent.putExtra(Master.KEY_PUSH_NOTIFICATION_POST_ID , notificationBundle.getPostID());
        intent.putExtra(Master.KEY_IS_FROM_PUSH_NOTIFICATION, true);
        intent.putExtra(Master.KEY_POSITION, 0);

        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
                PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.mnet_icon)
                .setContentTitle(getString(R.string.app_name))
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

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

        int random = (int) ((new Date().getTime() / 1000L) % Integer.MAX_VALUE);
        notificationManager.notify(random, notificationBuilder.build());
    }

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="mnet.mediaware.com.m_net">

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <application
        android:name=".MnetApplication"
        android:allowBackup="true"
        android:icon="@drawable/mnet_icon"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".activities.LoginActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:label="@string/app_name"
            android:launchMode="singleTask"
            android:theme="@style/Theme.AppCompat.Light.NoActionBar.FullScreen">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".activities.MainActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:label="@string/title_activity_main"
            android:launchMode="singleTask"
            android:theme="@style/AppTheme.NoActionBar" />

        <activity
            android:name=".activities.ConversationDetailActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:label="@string/title_activity_conversation_detail"
            android:parentActivityName=".activities.MainActivity"
            android:theme="@style/AppTheme.NoActionBar"
            android:launchMode="singleTask"
            android:windowSoftInputMode="stateHidden|adjustResize">
            <intent-filter>
                <action android:name="mnet.mediaware.com.m_net.activities.ConversationDetailActivity" />
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="http" />
            </intent-filter>

            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="mnet.mediaware.com.m_net.activities.MainActivity" />
        </activity>
        <activity
            android:name=".activities.ApprovalDetailActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:label="@string/title_activity_approval_detail"
            android:parentActivityName=".activities.MainActivity"
            android:theme="@style/AppTheme.NoActionBar"
            android:windowSoftInputMode="stateHidden|adjustResize">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="mnet.mediaware.com.m_net.activities.MainActivity" />
        </activity>
        <activity
            android:name=".activities.NewConversationActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:label="@string/title_activity_new_conversation"
            android:parentActivityName=".activities.MainActivity"
            android:theme="@style/AppTheme.NoActionBar"
            android:windowSoftInputMode="stateHidden|adjustResize">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="mnet.mediaware.com.m_net.activities.MainActivity" />
        </activity>
        <activity
            android:name=".activities.NotificationActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:label="@string/title_activity_notification"
            android:parentActivityName=".activities.MainActivity"
            android:theme="@style/AppTheme.NoActionBar"
            android:windowSoftInputMode="stateHidden|adjustResize">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="mnet.mediaware.com.m_net.activities.MainActivity" />
        </activity>
        <activity
            android:name=".activities.ProfileActivity"
            android:label="@string/title_activity_profile"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:parentActivityName=".activities.MainActivity"
            android:theme="@style/AppTheme.NoActionBar">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="mnet.mediaware.com.m_net.activities.MainActivity" />
        </activity>

        <service
            android:name=".utils.firebase.MyFirebaseMessagingService">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT"/>
            </intent-filter>
        </service>

        <service
            android:name=".utils.firebase.MyFirebaseInstanceIDService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
            </intent-filter>
        </service>

    </application>

</manifest>

使用 PendingIntent.FLAG_UPDATE_CURRENT。 - shinilms
1
使用标志PendingIntent.FLAG_UPDATE_CURRENT会带您前往您的活动。 继续编码吧,伙计 ;) 哈哈哈哈 - buzzingsilently
你是怎么解决的,我也遇到了完全相同的问题。 - Abdulmalek
6个回答

8
根据Firebase Cloud Messaging文档,如果Activity在前台,则会调用onMessageReceived方法。如果Activity在后台或关闭状态,则通知消息将显示在应用程序启动器活动的通知中心中。 更多信息请查看此链接

Launcher Activity(LoginActivity)的意图具有Extras。但是,当我从这个Activity启动ConversationDetailActivity(如果FCM extras存在),startActivity()函数什么也不做。因此,ConversationDetailActivity没有打开。可能的原因是什么? - backslashN
你是否已经在Intent中添加了这个标志?intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - Aayush Thakur
是的,我也尝试过这个方法,但没有帮助。我已经发布了另一个问题来解决这个问题。请在这里回答:链接 - backslashN
这是答案;但是这里最重要的事情是消息中的数据负载实际上将在启动器意图中。因此,我们应该尝试在活动的onNewIntent()中解析数据负载,而不是在FirebaseMessasingService的onMessageReceived()中解析它。 - Sira Lam
@SiraLam 我们也可以像Postman一样从API/后端使用通知,然后在FirebaseMessagingService Payload中使用。因此,您可以使用后端或从Postman使用Firebase API,而不是使用Firebase控制台。 - Aayush Thakur
那么,我们还有其他解决方案吗? 我们是否可以通过点击通知来导航到除MainActivity之外的特定活动? - GiridharaSPK

3

只有这个方法对我起作用。我的方法很简单。确保您在要直接打开的活动中添加此内容。

        <intent-filter>
            <action android:name="MainActivity" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>

同时,在推送通知中,您需要添加一个新的负载:click_action。它应该是这样的 -

"notification": {
  "title": "hello",
  "body": "test message",
  "click_action": "MAIN_ACTIVITY"
},

注意:您可以根据自己的喜好将其命名为MAIN_ACTIVITY,但必须在两个位置上相同。

3

当应用程序处于后台时,通知消息会被传递。在这种情况下,通知会传递到设备的系统托盘。用户点击通知默认会打开应用程序启动器。

当接收到同时具有通知和数据有效负载的消息时,应用程序处于后台。在这种情况下,通知将传递到设备的系统托盘,并且数据有效负载将在启动器 Activity 的意图附加项中传递

if (getIntent().getExtras() != null) {
for (String key : getIntent().getExtras().keySet()){
    String value = getIntent().getExtras().getString(key);
    Log.d(TAG, "Key: " + key + " Value: " + value);
}}

使用此代码获取意图数据


1
我想我已经为您准确地找到了答案。 TaskStackBuilder的用法和定义 请不要忽视上面链接中的精彩视频。
TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(getContext());
taskStackBuilder.addNextIntentWithParentStack(intent);
PendingIntent pendingIntent = taskStackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

我已经尝试使用这个pendingIntent,但是在点击推送通知时它只会跳转到启动画面。有什么帮助吗?我想要跳转到特定的活动页面。 - GiridharaSPK

1
当应用程序在后台时,Firebase推送通知数据有效负载会传递到启动器活动中。因此,在启动器活动中,您可以简单地检查并打开相应的屏幕。
 if (intent.hasExtra("data")) {

    }

0

在启动器活动中从意图获取捆绑包(用于推送通知数据有效负载),然后启动您的特定活动。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接