Funziona da luglio 2019
Android compilazioneSkkVersion 28, buildToolsVersion 28.0.3 e firebase-messaging: 19.0.1
Dopo molte ore di ricerche su tutte le altre domande e risposte StackOverflow e tentando innumerevoli soluzioni obsolete, questa soluzione è riuscita a mostrare le notifiche in questi 3 scenari:
- L'app è in primo piano:
la notifica viene ricevuta dal metodo onMessageReceived nella mia classe MyFirebaseMessagingService
- L'app è stata uccisa (non è in esecuzione in background):
la notifica viene inviata automaticamente alla barra delle notifiche da FCM. Quando l'utente tocca la notifica, l'app viene avviata chiamando l'attività con android.intent.category.LAUNCHER nel manifest. È possibile ottenere la parte dei dati della notifica utilizzando getIntent (). GetExtras () con il metodo onCreate ().
- L'app è in background:
la notifica viene inviata automaticamente alla barra delle notifiche da FCM. Quando l'utente tocca la notifica, l'app viene portata in primo piano avviando l'attività con android.intent.category.LAUNCHER nel manifest. Poiché la mia app ha launchMode = "singleTop" in quell'attività, il metodo onCreate () non viene chiamato perché è già stata creata un'attività della stessa classe, invece viene chiamato il metodo onNewIntent () di quella classe e ottieni i dati parte di la notifica lì utilizzando intent.getExtras ().
Passaggi: 1- Se definisci l'attività principale della tua app in questo modo:
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:largeHeap="true"
android:screenOrientation="portrait"
android:launchMode="singleTop">
<intent-filter>
<action android:name=".MainActivity" />
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
2- aggiungi queste righe con il metodo onCreate () di MainActivity.class
Intent i = getIntent();
Bundle extras = i.getExtras();
if (extras != null) {
for (String key : extras.keySet()) {
Object value = extras.get(key);
Log.d(Application.APPTAG, "Extras received at onCreate: Key: " + key + " Value: " + value);
}
String title = extras.getString("title");
String message = extras.getString("body");
if (message!=null && message.length()>0) {
getIntent().removeExtra("body");
showNotificationInADialog(title, message);
}
}
e questi metodi nello stesso MainActivity.class:
@Override
public void onNewIntent(Intent intent){
//called when a new intent for this class is created.
// The main case is when the app was in background, a notification arrives to the tray, and the user touches the notification
super.onNewIntent(intent);
Log.d(Application.APPTAG, "onNewIntent - starting");
Bundle extras = intent.getExtras();
if (extras != null) {
for (String key : extras.keySet()) {
Object value = extras.get(key);
Log.d(Application.APPTAG, "Extras received at onNewIntent: Key: " + key + " Value: " + value);
}
String title = extras.getString("title");
String message = extras.getString("body");
if (message!=null && message.length()>0) {
getIntent().removeExtra("body");
showNotificationInADialog(title, message);
}
}
}
private void showNotificationInADialog(String title, String message) {
// show a dialog with the provided title and message
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(title);
builder.setMessage(message);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
3- creare la classe MyFirebase in questo modo:
package com.yourcompany.app;
import android.content.Intent;
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
public class MyFirebaseMessagingService extends FirebaseMessagingService {
public MyFirebaseMessagingService() {
super();
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(Application.APPTAG, "myFirebaseMessagingService - onMessageReceived - message: " + remoteMessage);
Intent dialogIntent = new Intent(this, NotificationActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
dialogIntent.putExtra("msg", remoteMessage);
startActivity(dialogIntent);
}
}
4- creare una nuova classe NotificationActivity.class in questo modo:
package com.yourcompany.app;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.ContextThemeWrapper;
import com.google.firebase.messaging.RemoteMessage;
public class NotificationActivity extends AppCompatActivity {
private Activity context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = this;
Bundle extras = getIntent().getExtras();
Log.d(Application.APPTAG, "NotificationActivity - onCreate - extras: " + extras);
if (extras == null) {
context.finish();
return;
}
RemoteMessage msg = (RemoteMessage) extras.get("msg");
if (msg == null) {
context.finish();
return;
}
RemoteMessage.Notification notification = msg.getNotification();
if (notification == null) {
context.finish();
return;
}
String dialogMessage;
try {
dialogMessage = notification.getBody();
} catch (Exception e){
context.finish();
return;
}
String dialogTitle = notification.getTitle();
if (dialogTitle == null || dialogTitle.length() == 0) {
dialogTitle = "";
}
AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(context, R.style.myDialog));
builder.setTitle(dialogTitle);
builder.setMessage(dialogMessage);
builder.setPositiveButton(getResources().getString(R.string.accept), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
}
5- Aggiungi queste righe al Manifest dell'app, all'interno dei tag
<service
android:name=".MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="@string/default_notification_channel_id"/>
<activity android:name=".NotificationActivity"
android:theme="@style/myDialog"> </activity>
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/notification_icon"/>
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/color_accent" />
6- aggiungere queste righe nel metodo Application.java onCreate () o nel metodo MainActivity.class onCreate ():
// notifications channel creation
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Create channel to show notifications.
String channelId = getResources().getString("default_channel_id");
String channelName = getResources().getString("General announcements");
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(new NotificationChannel(channelId,
channelName, NotificationManager.IMPORTANCE_LOW));
}
Fatto.
Ora affinché funzioni correttamente nei 3 scenari citati, è necessario inviare la notifica dalla console Web di Firebase nel modo seguente:
Nella sezione Notifica: Titolo notifica = Titolo da visualizzare nella finestra di notifica (opzionale) Testo notifica = Messaggio da mostrare all'utente (richiesto) Quindi nella sezione Destinazione: App = la tua app Android e nella sezione Opzioni aggiuntive: Canale di notifica Android = default_channel_id Chiave dati personalizzati: valore titolo: (stesso testo qui nel campo Titolo della sezione Notifica) chiave: valore corporeo: (stesso testo qui nel campo Messaggio della sezione Notifica) chiave: valore click_action: .MainActivity Sound = Disabilitato
scade = 4 settimane
Puoi eseguire il debug nell'emulatore con API 28 con Google Play.
Buona programmazione!
Not getting messages here? See why this may be: goo.gl/39bRNJ
. La soluzione, come le risposte di seguito, è disponibile nella documentazione in Messaggi con payload sia di notifica che di dati