android - studio - Consola de Firebase: cómo especificar click_action para las notificaciones
notificaciones en segundo plano android studio (3)
Implementé Firebase y probando las notificaciones de Firebase. Cuando la aplicación está en primer plano, no tengo problemas, implementé un servicio que extiende FirebaseMessagingService y maneja el mensaje y los datos en onMessageReceived
Tengo problemas cuando la aplicación está en segundo plano, me gustaría enviar una notificación que abra una actividad específica y haga lo que programo hacer, no solo abrir la aplicación.
Hice lo descrito en la guía de Firebase, pero no puedo iniciar la actividad específica.
Aquí el manifiesto:
<activity android:name=".BasicNotificationActivity">
<intent-filter>
<action android:name="OPEN_ACTIVITY_1" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Y aquí la consola de Firebase. ¿Qué debo escribir en esos campos para abrir mi "BasicNotificationActivity"?
También tengo problemas como tú, pero no recibo ninguna respuesta correcta, son los hechos que sé,
- onNewIntent
este método de anulación no funciona cuando la aplicación está en segundo plano porque la acción predeterminada de trabajo es android.intent.action.MAIN
- Consola de Firebase
La consola de firebase no tiene la potencia suficiente para manejar click_action, lo que significa que la acción de clic no puede llegar a la aplicación cuando está en segundo plano.
- RIZO
Curl está trabajando en el fondo de la aplicación, pero no en primer plano puede ser que no puedo encontrar.
curl --header "Authorization: key=<Colud_Messaging_Server_Key_here>" --header Content-Type:"application/json" https://fcm.googleapis.com/fcm/send -d "{/"to/":/"dwdfosu6SDs:APA91bFWxZZB2f8AOgP9MG504cy5AhFECHGbYFfIzVixoAfy-ErT0NYQrREg150CbKYBtk3Ywpu7WQuWsQhk-VmoOe-0iDK3ZgaFZNvYxDuixZB8zQp0zydoXhyrMosi5C4eyBb7Ai1z/",/"notification/": {/"title/": /"Click Action Message/",/"text/": /"Sample message/",/"click_action/":/"noti/",/"ticket_download/":/"noti/"}}"
Añadir Minifest
<activity
android:name=".activity.TicketDownload"
android:exported="true">
<intent-filter>
<action android:name="noti" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Nota: cloud_messaging_server_key es locate setting> cloudmessaging
si hay algo nuevo, por favor, háganmelo saber.
Este es un duplicado de esta pregunta: notificaciones de Firebase FCM click_action payload
Pero la respuesta que fue aceptada por el autor de esta pregunta solo indica que no es posible con Firebase Console, pero sí con una solución fácil. Esta respuesta de diidu a la misma pregunta explica la solución alternativa que usaría.
ACTUALIZAR:
Para explicar su respuesta:
Agregue una clase auxiliar (o implemente el método startActivity()
alguna manera):
public class ClickActionHelper {
public static void startActivity(String className, Bundle extras, Context context){
Class cls;
try {
cls = Class.forName(className);
}catch(ClassNotFoundException e){
//means you made a wrong input in firebase console
}
Intent i = new Intent(context, cls);
i.putExtras(extras);
context.startActivity(i);
}
}
En la actividad de iniciador de su aplicación, llame a un comando para verificar las nuevas intenciones en onCreate()
y onNewIntent()
( onNewIntent()
solo se llama en lugar de onCreate()
si la actividad se inicia con el indicador de una sola cima):
@Override
protected void onCreate(Bundle bundle) {
[...]
checkIntent(getIntent());
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
[...]
checkIntent(intent);
}
public void checkIntent(Intent intent) {
if (intent.hasExtra("click_action")) {
ClickActionHelper.startActivity(intent.getStringExtra("click_action"), intent.getExtras(), this);
}
}
Y en onMessageReceived()
:
public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> data = remoteMessage.getData();
if (data.containsKey("click_action")) {
ClickActionHelper.startActivity(data.get("click_action"), null, this);
}
}
Para enviar una notificación con la consola de firebase, coloque un par clave-valor como datos personalizados como este:
Key: click_action
Value: <fully qualified classname of your activity>
Ahora cuando se recibe una notificación y se hace clic en ella, se abrirá su actividad. Si su aplicación está en primer plano, también cambiará inmediatamente a la actividad; probablemente sería bueno preguntarle al usuario si quiere ir a esta actividad o no (mostrando un cuadro de diálogo onMessageReceived()
).
He usado el handleIntent(Intent intent)
para manejar el intent
y pasar a esa pantalla en particular. A continuación está mi código que funciona perfectamente incluso cuando la aplicación está en segundo plano:
FCMMessagingService.java que extends FCMMessagingService
@Override
public void handleIntent(Intent intent) {
super.handleIntent(intent);
Intent i = null;
String value_action = "";
if (intent.getExtras() != null) {
if (key.equals("click_action")) {
value_action = intent.getExtras().getString(key);
}
i = new Intent(FCMMessagingService.this, MainActivity.class);
i.putExtra("notificationFlag", value_action);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
PendingIntent pendingIntent = PendingIntent.getActivity(this, notifCount, i, PendingIntent.FLAG_ONE_SHOT);
final int icon = R.mipmap.logo;
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
Notification notification;
notification = notificationBuilder.setSmallIcon(icon).setTicker(title)
.setAutoCancel(true)
.setContentTitle(title)
.setContentText(body)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent)
.setSmallIcon(R.mipmap.notification_icon)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), icon))
.build();
notificationBuilder.setContentTitle(title);
notificationBuilder.setContentText(body);
notificationBuilder.setAutoCancel(true);
notificationBuilder.setSound(defaultSoundUri);
notificationBuilder.setContentIntent(pendingIntent);
notificationBuilder.setLargeIcon(BitmapFactory.decodeResource(getResources(), icon));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
notificationBuilder.setSmallIcon(R.mipmap.logo);
} else {
notificationBuilder.setSmallIcon(R.mipmap.logo);
}
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notifCount, notification);
}