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:
- Android: administrar múltiples notificaciones push en el dispositivo de una aplicación
- Enviar difusión al hacer clic en la notificación
- La aplicación Ionic / Cordova no recibe notificación push en el fondo
- Firebase Push Notification - Cómo mostrar mensaje multilínea en Notificación
- notificaciones push de Google Chrome 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.
- Spring pedalea cliente web sockets para android
- Parse Push - Cómo abrir automáticamente una actividad sin la acción del usuario al recibir un empujón en Android
- Nuevo error de origen desconocido del registro de la API de GCM
- Enviar Notificaciones push a iOS / Android en WiFi cerrado (sin conexión a Internet)
- ¿Hay alguna razón para continuar usando IntentService para manejar mensajes de GCM?
- ¿Está com.google.android.c2dm.intent.RECEIVE todavía en uso?
- Cómo mostrar las notificaciones Heads up android
- Despierta Android Phone / tablet?
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.
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.
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á enForeground
, para todos los demás casos, es unaSystem Tray Notification
, que abre laLauncher Activity
cuando se hace clic. Esto es útil cuando no desea controlar lasNotifications
por su cuenta y no muchos datos para tratar cuando seNotification
. Incluso puedes controlar el sonido, el icono y click_action (solo cuando la aplicación está enForeground
) sin escribir ningún código en tuonMessageReceived()
. Un ejemplo de un cuerpo de talHTTP POST Request
se adjunta en la captura de pantalla de abajo.
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 laNotification
por ourselve igual que todos estábamos haciendo en el caso deGCM
. A continuación se muestra un ejemplo de un cuerpo de dichaHTTP POST Request
.
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
yData Payloads
también. En este caso,onMessageReceived()
se llama cuando la aplicación está enForeground
. Para el fondo y el estado cerrado, laNotification
viene en la bandeja del sistema similar a laNotification Payload
pero la única diferencia es que podemos tenerdata extras
también que podemos utilizar para redirigir el usuario a unaActivity
deseada, cuando chascado en unaNotification
. A continuación se muestra el ejemplo de un cuerpo de talHTTP POST Request
A continuación se muestra un ejemplo de un cuerpo de dichaHTTP POST Request
HTTP POST Request
.
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:
-
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;
-
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:
-
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>
-
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 ..
- Problemas con EditText y teclado suave en un fragmento
- Android: mkdirs () / mkdir () en el almacenamiento externo devuelve false