Al hacer clic en la notificación no se abre la actividad mencionada

Estoy tratando de abrir una Activity cuando se hace clic en la notificación y debajo está mi código.

 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()); 

Manifiesto de 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> 

Siempre que recibo una notificación de FCM estoy llamando a esta notificación. NotificationActivity no se abre cuando hago clic en notificación, sino que la aplicación se está abriendo ( splash screen->starting activity de splash screen->starting activity de mi flujo de aplicaciones habitual). Cada vez que recibo una notificación mientras la aplicación ya está abierta, se está abriendo NotificationActivity , pero no cuando la aplicación no está abierta. ¿Podría alguien ayudarme por favor en la resolución de esto?

Nota: Por favor, estoy reiterando que NotificationActivity.class no se está abriendo cuando se hace clic en la notificación cuando la aplicación ya no está abierta.

Según la documentación de FCM , para recibir y manejar mensajes,

Si desea recibir notificaciones cuando su aplicación está en primer plano, debe agregar alguna lógica de administración de mensajes.

Para recibir mensajes, utilice un servicio que amplíe FirebaseMessagingService. Su servicio debe anular la devolución de llamada onMessageReceived, que se proporciona para la mayoría de los tipos de mensaje, con las siguientes excepciones:

1). Notificaciones enviadas cuando tu aplicación está en segundo plano. En este caso, la notificación se entrega a la bandeja del sistema del dispositivo. Un usuario pulsa en una notificación abre el lanzador de aplicaciones de forma predeterminada.

2). Mensajes con la carga de notificación y de datos, tanto de fondo como de primer plano. En este caso, la notificación se entrega a la bandeja del sistema del dispositivo y la carga útil de datos se entrega en los extras de la intención de la Actividad del lanzador.

Introduzca aquí la descripción de la imagen

Así que básicamente, tenemos dos tipos de cargas útiles

1). Carga útil de la notificación

2). Carga de datos

3). Ambos (un tipo adicional que podemos considerar).

Ahora vamos a discutir uno por uno estas cargas útiles. Antes de que usted necesita entender cómo puede enviar estas cargas útiles a su aplicación. Todo lo que tienes que hacer es hacer uso de cualquier herramienta que pueda realizar HTTP POST Request . En mi caso, estoy usando la herramienta Postman , un complemento de Google Chrome.

Antes de hacer una HTTP Post Request para FCM , debes considerar tres cosas:

1). URL de solicitud de publicación HTTP: https://fcm.googleapis.com/fcm/send

2). Encabezados de solicitud:

yo). Tipo de contenido: application / json

Ii). Autorización: key = YOUR_SERVER_KEY

A continuación se muestra la captura de pantalla de la misma para mostrar cómo se ve.

Introduzca aquí la descripción de la imagen

3). Cuerpo: En esto vamos a tener JSON para Notification y Data Payloads .

  • Así que a partir de la carga de notificación , la más simple de todas. En este caso, onMessageReceived() se llama sólo cuando la aplicación está en Foreground , para todos los demás casos, es una System Tray Notification , que abre la Launcher Activity cuando se hace clic. Esto es útil cuando no desea controlar las Notifications por su cuenta y no muchos datos para tratar cuando se Notification . Incluso puedes controlar el sonido, el icono y click_action (solo cuando la aplicación está en Foreground ) sin escribir ningún código en tu onMessageReceived() . Un ejemplo de un cuerpo de tal HTTP POST Request se adjunta en la captura de pantalla de abajo.

Introduzca aquí la descripción de la imagen

Para abrir la Activity deseada al enviar el parámetro click_action, debes usar el siguiente código en tu onMessageReceived() .

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

Y debajo de su método 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); } 

NOTA: Esta clave click_action funcionará sólo cuando la aplicación esté en primer plano, para todos los demás casos cuando la aplicación esté en Background y cerrada, no funcionará. Incluso no se abre la Actividad del Lanzador, en caso de Fondo y Cerrado, si se especifica este parámetro.

  • Ahora viene la carga de datos . Esto es similar al que tenemos en GCM . Esto es muy importante si queremos manejar todas las cosas de la Notification por ourselve igual que todos estábamos haciendo en el caso de GCM . A continuación se muestra un ejemplo de un cuerpo de dicha HTTP POST Request .

Introduzca aquí la descripción de la imagen

Así que en este caso, onMessageReceived() se llama cada vez y esto funcionará de la misma manera que el de GCM , tan útil para todos nosotros. Tienes que Override onMessageReceived() como se muestra a continuación.

 @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()); } 
  • Por último, pero no menos importante, podemos enviar tanto Notification y Data Payloads también. En este caso, onMessageReceived() se llama cuando la aplicación está en Foreground . Para el fondo y el estado cerrado, la Notification viene en la bandeja del sistema similar a la Notification Payload pero la única diferencia es que podemos tener data extras también que podemos utilizar para redirigir el usuario a una Activity deseada, cuando chascado en una Notification . A continuación se muestra el ejemplo de un cuerpo de tal HTTP POST Request A continuación se muestra un ejemplo de un cuerpo de dicha HTTP POST Request HTTP POST Request .

Introduzca aquí la descripción de la imagen

Al hacer clic en una Notification en la Bandeja del Sistema, se abrirá la Launcher Activity del Launcher Activity y Necesitará Override onCreate() de su Launcher Activity para obtener los data extras y redirigir al usuario a la Activity deseada. Debajo está el código, usted tiene que escribir en onCreate() de su Activity para redirigir el usuario a la Activity deseada.

 @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 } 

Otro caso de este tipo es, cuando la Launcher Activity se define como launchMode="true" en el manifest y cuando llega la Notification , su Launcher Activity está en el Foreground . Por lo tanto, cuando hace clic en la notificación, tiene que Override el método onNewIntent() en su Launcher Activity para abrir la Activity deseada. A continuación se muestra el código de ejemplo para el mismo.

 @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(); } } 

Así que en resumen, yo diría que es bueno ir con el tipo de carga de datos, ya que proporciona más flexibilidad y control sobre la Notification y, lo que es más importante, ya que todos estamos acostumbrados a GCM , por lo que este tipo es lo que todos preferiríamos.

Nota: Algunos dispositivos están teniendo problemas para recibir notificaciones en segundo plano, ya que encontré algunas consultas sobre el mismo aquí. Por otra parte en el momento, estaba investigando estos casos, mi teléfono ASUS no estaba recibiendo notificaciones en el fondo para cualquiera de los tipos mencionados anteriormente. Así que no estoy seguro de cuál es el problema con estos dispositivos.

Si lee los documentos de firebase en detalle, hay dos tipos de cargas útiles

  • Carga útil de los datos
  • Carga útil de la notificación

La carga de datos activa la devolución de llamada onMessageReceived () cuando la aplicación es a la vez de primer plano y de fondo. Esto no es el caso con la carga de notificación, que activa la devolución de llamada sólo en estado de primer plano. Por lo tanto, si se utiliza la carga de datos de este problema debe ser resuelto.

Compruebe este código y hágamelo saber.

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

Tienes que usar FLAG_UPDATE_CURRENT en pendingIntent.

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

Y también pasar el mismo id a notificationManager

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

Ese es el comportamiento intencionado. Si su aplicación está en segundo plano, la notificación es creada por el sistema android que no tiene su acción pendingIntent. Por lo tanto, no funciona. En el caso del primero plano trabaja porque la notificación es creada por su código.

Por favor, consulte el documento en el enlace de abajo. https://firebase.google.com/docs/notifications/android/console-device#receive_and_handle_messages

Puede especificar cualquier Activity to be receiver para notificaciones push:

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

Este filtro de intenciones para la actividad especifica qué actividad se iniciará en respuesta a la notificación push ( PACKAGE_NAME es el paquete de la aplicación para Android)

Por lo tanto, puede agregar este filtro de intenciones en su Activity que desea abrir con el clic de notificación Push.

Siento no agregar un comentario como soy un recién nuevo.

Sólo puede hacer las siguientes dos cosas para investigar más:

  1. Una vez creada la notificación, utilice el comando shell "adb shell dumpsys activity i [su nombre de paquete]" para ver su notificación en detalle, para confirmar que es realmente lo que desea. Recuerde reemplazar "[su nombre de paquete]" con su propio nombre de paquete;

  2. Seguimiento del registro de eventos durante el tiempo que está reproduciendo esto utilizando "adb logcat -v threadtime -b eventos".

Publicar ambos y podemos obtener algo útil sobre lo que está pasando mal bajo el capó.

Establezca su intención pendiente como a continuación

 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); 

Agregue a su notificación usando

 .setContentIntent(pendingIntent); 

Utilizo esto en mi 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()); } 

El problema podría ser que está intentando iniciar la aplicación iniciando una actividad que NO está marcada como actividad de LANZADOR.

El sistema intenta resolver la intención de la notificación con respecto a la actividad de la aplicación. Sin embargo, debido a que su aplicación no se inicia, la actividad predeterminada de lanzador predeterminada se activa por defecto y, por lo tanto, se activa.

Pienso en dos maneras de resolver este problema:

  1. Haz de tu NotificationActivity una actividad de lanzador (en AndroidManifest.xml):

      <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> 
  2. Si desea pasar por la actividad actual del lanzador, debe manejar / enrutar los datos de la intención entrante en el método onCreate de su iniciador y reenviar los datos necesarios a la actividad de destino:

     Intent sourceIntent = getIntent(); String targetClassName = sourceIntent.getComponent().getClassName(); if(targetClassName.equals(NotificationActivity.class.getName())){ //Not 100% that this is the right .equals check, maybe you need NotificationActivity.class.getSimpleName() instead? Maybe use a debugger to figure out what classname comes from the notification.. Intent destIntent = new Intent(this.getApplicationContext(), NotificationActivity.class); destIntent.putExtra("msgBody",sourceIntent.getExtra("msgBody")); destIntent.putExtra(Constants.NOTIF_INTENT_TYPE,Constants.NOTIF_INTENT_TYPE); startActivity(this, destIntent); } 

En ambos casos, al construir la intención pendiente también debe deshacerse del indicador singleTop ya que su implementación de NotificationActivity no sigue el ciclo de vida singleTop

Espero que sea la solución a su lucha ..

  • BroadcastReceiver no se llama cuando la pantalla está bloqueada en Android
  • Servicio de notificación de Google / Apple Push (APNS / GCM)
  • Tamaño de icono de la barra de estado de Android - Uso de Cordova / Phonegap Push Plugin
  • Enviar notificación a un tema específico en Firebase en Java
  • Analizar notificaciones push en Android
  • Firebase onMessageReceived no llamado cuando la aplicación está en segundo plano
  • Un servidor que envía notificaciones push a dispositivos Android e iOS
  • Android, notificación Push mediante parse.com, inicia automáticamente la aplicación
  • FCM: onMessageReceived no se llama, la notificación no llegó incluso después de enviar msg a fcm?
  • Firebase Cloud Messaging: mejores prácticas
  • ¿Las notificaciones no siempre se reciben por teléfono?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.