21

我试图在点击通知时打开Activity,下面是我的代码。点击通知没有打开提到的活动

Intent intent = new Intent(this.getApplicationContext(), NotificationActivity.class); 
intent.putExtra("msgBody",messageBody); 
intent.putExtra(Constants.NOTIF_INTENT_TYPE,Constants.NOTIF_INTENT_TYPE); 

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 
       |Intent.FLAG_ACTIVITY_SINGLE_TOP 
       |Intent.FLAG_ACTIVITY_CLEAR_TOP); //Tried with many options here 

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 , intent, 
             PendingIntent.FLAG_CANCEL_CURRENT); 

Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); 

NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) 
       .setSmallIcon(R.drawable.otp_icon) 
       .setContentTitle("Push MSG") 
       .setContentText(messageBody) 
       .setAutoCancel(true) 
       .setSound(defaultSoundUri) 
       .setContentIntent(pendingIntent); 

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

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

Android清单:

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

    <uses-sdk 
     android:minSdkVersion="17" 
     android:targetSdkVersion="21" /> 

    <supports-screens 
     android:anyDensity="true" 
     android:largeScreens="true" 
     android:normalScreens="true" 
     android:smallScreens="true" /> 

    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.READ_LOGS" /> 
    <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 

    <application 
     android:name=".AndroidPushApp" 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher"> 
     <activity 
      android:name=".PushSplashScreen" 
      android:screenOrientation="portrait"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
     <activity 
      android:name=".MainApplicationScreen" 
      android:screenOrientation="portrait" 
      android:windowSoftInputMode="adjustResize"> 
      <intent-filter> 
       <action android:name="android.intent.action.VIEW" /> 
       <category android:name="android.intent.category.DEFAULT" /> 
       <category android:name="android.intent.category.BROWSABLE" /> 
      </intent-filter> 
     </activity> 
     <activity 
      android:name=".StartActivity" 
      android:launchMode="singleTask" 
      android:screenOrientation="portrait" 
      android:uiOptions="splitActionBarWhenNarrow" 
      android:windowSoftInputMode="adjustResize"> 
      <intent-filter> 
       <action android:name="android.intent.action.VIEW" /> 
       <category android:name="android.intent.category.DEFAULT" /> 
       <category android:name="android.intent.category.BROWSABLE" /> 
      </intent-filter> 
     </activity> 

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

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

     <meta-data 
      android:name="com.google.android.gms.version" 
      android:value="@integer/google_play_services_version" /> 

     <activity 
      android:name=".NotificationActivity" 
      android:exported="true" 
      android:label="@string/title_activity"> 
      <intent-filter> 
       <category android:name="android.intent.category.DEFAULT" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 

每当我从FCM得到通知我打电话此通知。 NotificationActivity没有打开,只要我点击通知,而是应用程序打开(我平常的应用程序流的splash screen->starting activity)。每当我在应用程序已经打开的时候收到通知,NotificationActivity就会被打开,但是当应用程序尚未打开时就不会。有人能帮我解决这个问题吗?

注:请我重申NotificationActivity.class上,当应用程序尚未打开状态的通知点击时是没有得到开放。

+0

使用FLAG_ONE_SHOT https://开头开发商.android.com/reference/android/app/PendingIntent.html#FLAG_ONE_SHOT并让我知道。 –

+0

@SagarGangawane试过没有运气 – rick

+0

@rick请发布您的_AndroidManifest.xml_。 – earthw0rmjim

回答

0

您可以指定任何Activity成为推送通知接收器:

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

这为活动意图过滤指定哪些活动将在响应中推出的推送通知(PACKAGE_NAME是你的Android应用程序包)

因此,您可以在您要打开的Activity中添加此意图过滤器,只需点击推送通知即可。

+0

为什么选择投票?它为我工作。也请尝试添加此行。 Adheesh

0

如果您详细阅读火力文档,有两种类型的有效载荷

  • 数据有效载荷
  • 通知有效载荷

的数据有效载荷触发onMessageReceived( )当app是前景和背景时回调。通知有效负载不是这种情况,它只在前台状态下触发回调。所以,如果你使用数据有效载荷,应该解决这个问题。

+0

通知在我的情况下每次都会被解雇。我在打开屏幕时遇到问题,而不是通知触发 – rick

+1

尝试在意图中使用FLAG_ACTIVITY_CLEAR_TOP标志,在PendingIntent中使用FLAG_CANCEL_CURRENT标志。 –

0

检查此代码并让我知道。

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

您必须在pendingIntent中使用FLAG_UPDATE_CURRENT

PendingIntent pendingIntent = PendingIntent.getActivity(this, notificationId /* Request code */, intent, 
      PendingIntent.FLAG_UPDATE_CURRENT); 

,并通过同一个ID notificationManager

notificationManager.notify(notificationId /* ID of notification */, notificationBuilder.build()); 
+0

感谢您的回答。我已经尝试过,但没有运气。 – rick

0

多数民众赞成在intented行为。如果你的应用程序在后台,通知是由android系统创建的,它没有你的pendingIntent动作。所以它不起作用。在前台情况下,它的工作原理是通知是由您的代码创建的。

请检查下面的链接文档。 https://firebase.google.com/docs/notifications/android/console-device#receive_and_handle_messages

+0

然后,如何通过点击通知来打开预期的活动,而不管应用程序是处于前景还是后台。现在,当我的应用程序处于后台时,它会在点击通知时打开它。当服务器通过gcm或fcm向设备发送通知有效载荷时,请建议 – rick

+0

,您必须添加数据有效载荷,即“data”:{“your_action_key”:“action_value_like_activity”}并从您的_onMessageRecievedmethod(RemoteMessage remoteMessage)_中读取并创建通知通过解析remoteMessage.getData()。 – rafa

14

FCM文档,用于接收和处理消息,

如果你想收到通知时,您的应用程序是在 前景,你需要添加一些消息处理逻辑。

要接收消息,请使用延伸到 FirebaseMessagingService的服务。您的服务应覆盖 onMessageReceived回调,该回调为大多数消息类型提供, ,但以下情况除外:

1)。当您的应用处于后台时发送的通知。在 这种情况下,通知被传递到设备的系统托盘。 默认情况下,用户点击通知将打开应用程序启动器。 2)。包含通知和数据有效负载的邮件,包括背景 和前景。在这种情况下,通知将传送到 设备的系统托盘,并且数据有效负载将以您的启动程序活动意图的附加组件 传送。

enter image description here

因此,基本上,我们有两种类型的有效载荷

1)的。通知有效负载

2)。数据有效载荷

3)。两者(我们可以考虑的另一种类型)。

现在让我们逐个讨论这些有效载荷。在此之前,您需要了解如何将这些有效负载发送到您的应用程序。您只需使用任何可执行HTTP POST Request的工具即可。在我的情况下,我使用邮差工具,一个谷歌浏览器插件。

之前作出HTTP Post RequestFCM,你必须要考虑三件事情:

1)。 HTTP发布请求网址:https://fcm.googleapis.com/fcm/send

2)。请求头:

i)。内容类型:应用程序/ json

ii)。授权:key = YOUR_SERVER_KEY

以下是显示其外观的截图。

enter image description here

3)。正文:在这我们将有JSONNotificationData Payloads

  • 因此,从开始通知有效负载,最简单的。在这种情况下,onMessageReceived()被称为只有当应用程序是在Foreground,对于所有其他情况下,这是一个System Tray Notification,点击它时打开Launcher Activity。如果您不想自己控制Notifications,并且在Notification到来时没有太多数据需要处理,这会很有帮助。您甚至可以在没有在您的onMessageReceived()中编写任何代码的情况下控制声音,图标和click_action(仅在应用程序位于Foreground时)。在下面的屏幕截图中附加了HTTP POST Request这个主体的一个示例。

enter image description here

如果要打开发送click_action参数时所需Activity,你必须使用下面的代码在你的onMessageReceived()

@Override 
public void onMessageReceived(RemoteMessage remoteMessage) { 
    if (null != remoteMessage.getNotification().getClickAction()) { 
      startActivity(remoteMessage.getNotification().getClickAction(), null, this); 
    } 
} 

以下是您startActivity()方法:

public void startActivity(String className, Bundle extras, Context context) { 
    Class cls = null; 
    try { 
     cls = Class.forName(className); 
    } catch (ClassNotFoundException e) { 
     //means you made a wrong input in firebase console 
    } 
    Intent intent = new Intent(context, cls); 
    if (null != extras) { 
     intent.putExtras(extras); 
    } 
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 
      | Intent.FLAG_ACTIVITY_CLEAR_TASK); 
    context.startActivity(intent); 
} 

注:此click_action键将只有当应用程序在 前景,对于所有其他情况下,当应用程序在后台和 已关闭,它不起作用。如果指定了此参数,它甚至不会在“背景”和“关闭”情况下打开启动器活动, 。

  • 现在到了数据有效载荷。这与我们在GCM中的那个类似。这是非常重要的,如果我们想要处理Notification所有的东西,我们都在做GCM的情况。下面显示了HTTP POST Request的一个主体的示例。

enter image description here

因此,在这种情况下,onMessageReceived()被称为每次,这将在一样的方法的GCM工作,这样有助于我们所有人。您必须如下所示OverrideonMessageReceived()

@Override 
public void onMessageReceived(RemoteMessage remoteMessage) { 
    Map<String, String> data = remoteMessage.getData(); 
    if (null != data && 0 < data.size()) { 
     if (data.containsKey("custom_key_1")) { 
      sendNotification(data.get("custom_key_1")); 
     } 
    } 
} 

private void sendNotification(String messageBody) { 
     Intent intent = new Intent(this, DesiredActivity.class); 
     intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
     PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, 
       PendingIntent.FLAG_ONE_SHOT); 

     Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); 
     NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) 
       .setSmallIcon(R.drawable.ic_stat_ic_notification) 
       .setContentTitle("FCM Message") 
       .setContentText(messageBody) 
       .setAutoCancel(true) 
       .setSound(defaultSoundUri) 
       .setContentIntent(pendingIntent); 

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

     notificationManager.notify(0 /* ID of notification */, notificationBuilder.build()); 
} 
  • 最后但并非最不重要的,我们可以同时发送NotificationData Payloads为好。在这种情况下,当应用程序位于Foreground时,将调用onMessageReceived()。对于背景和关闭状态,Notification进入系统托盘类似于Notification Payload,但唯一的区别是我们可以有data extras以及我们可以用来将用户重定向到期望的Activity,当点击Notification时。以下是这种HTTP POST Request的主体的示例。下面示出了这样的HTTP POST Request的主体的示例。

enter image description here

当在系统托盘上的Notification点击,它会打开Launcher Activity,你需要OverrideonCreate()Launcher Activity的得到data extras并重定向用户到所需Activity。以下是代码,您必须编写您的ActivityonCreate()以将用户重定向到所需的Activity

@Override 
protected void onCreate(@Nullable Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    if(getIntent().hasExtra("custom_key_1") && getIntent().getStringExtra("custom_key_1") 
      .equals("custom_value_1")){ 
     startActivity(new Intent(this, DesiredActivity.class)); 
     finish(); 
     return; 
    } 

    // other operations 
} 

另一种情况,以这种类型是,当你的Launcher Activitymanifest被定义为launchMode="true"并且当Notification到达时,你的Launcher Activity处于Foreground。因此,当您点击通知时,您必须在Launcher ActivityOverrideonNewIntent()方法中打开所需的Activity。以下是相同的示例代码。

@Override 
protected void onNewIntent(Intent intent) { 
    super.onNewIntent(intent); 
    if (getIntent().hasExtra("custom_key_1") && getIntent().getStringExtra("custom_key_1") 
       .equals("custom_value_1")) { 
      startActivity(new Intent(this, DesiredActivity.class)); 
      finish(); 
    } 
} 

因此,在短期,我会说这是好去与数据有效载荷类型,因为它提供了更多的灵活性和控制权Notification而我们都被用来GCM更重要的,所以这种类型我们都想要更喜欢什么。

注意:有些设备在 中收到通知的问题背景,因为我在这里发现了一些相同的查询。此外,在 时间,我正在调查这些情况下,我的华硕手机没有在上述任何类型的背景中收到 通知。所以 不知道这些设备有什么问题。

+0

如上所述,我需要打开通知点击活动,而不是onmessagereceived,请建议 – rick

+0

该解决方案处理每个案件相同。请再次通过它,让我知道你没有得到 –

+0

请看看更新的答案,希望这将有助于:) –

0

对不起,没有评论,因为我是一个相当新的人。

你可以做进一步调查以下两两件事:通知已创建

  1. 后,使用shell命令“亚行外壳dumpsys活动我[你的包名]”中看到您的通知,细节,以确认它真的是你想要的。 请记住用您自己的软件包名称替换“[您的软件包名称]”;

  2. 在使用“adb logcat -v threadtime -b events”重现此事件期间跟踪事件日志。

发布这两个,我们可能会得到一些有关什么是错误的问题。

0

设置如下图所示

Intent intent = new Intent(this.getApplicationContext(), NotificationActivity.class); 
intent.putExtra("msgBody",messageBody); 
intent.putExtra(Constants.NOTIF_INTENT_TYPE,Constants.NOTIF_INTENT_TYPE); 

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0); 

它添加到使用

.setContentIntent(pendingIntent); 
0

我在FirebaseMessagingService使用您的通知尚待处理的意图:

/** 
* Create and show a simple notification containing the received FCM message. 
* 
* @param messageBody FCM message body received. 
*/ 
private void sendNotification(String title, String messageBody, String data) { 
    Intent intent = new Intent(this, MainActivity.class); 
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, 
      PendingIntent.FLAG_ONE_SHOT); 

    Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); 
    NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(getApplicationContext()) 
      .setSmallIcon(R.mipmap.ic_launcher) 
      .setContentTitle(title) 
      .setContentText(messageBody) 
      .setAutoCancel(true) 
      .setSound(defaultSoundUri) 
      .setContentIntent(pendingIntent); 

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

    notificationManager.notify(id++ /* ID of notification */, notificationBuilder.build()); 
} 
相关问题