Ich habe eine FCM-Benachrichtigung vom Server an die Benutzer gesendet. Es funktioniert einwandfrei (bis api 25), aber in Oreo, wenn sich die Anwendung nicht im Hintergrund befindet (Dienste sind geschlossen) (oder) vollständig geschlossen FCM-Code angehängt haben
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
package="com.fcm">
<application
Android:allowBackup="true"
Android:icon="@mipmap/ic_launcher"
Android:label="@string/app_name"
Android:roundIcon="@mipmap/ic_launcher_round"
Android:supportsRtl="true"
Android:theme="@style/AppTheme">
<activity Android:name=".MainActivity">
<intent-filter>
<action Android:name="Android.intent.action.MAIN" />
<category Android:name="Android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
Android:name=".MyFirebaseMessagingService">
<intent-filter>
<action Android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
<intent-filter>
<action Android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<meta-data
Android:name="com.google.firebase.messaging.default_notification_icon"
Android:resource="@drawable/ic_stat_ic_notification" />
<meta-data
Android:name="com.google.firebase.messaging.default_notification_color"
Android:resource="@color/colorAccent" />
<meta-data
Android:name="com.google.firebase.messaging.default_notification_channel_id"
Android:value="fcm"/>
<meta-data Android:name="firebase_messaging_auto_init_enabled"
Android:value="false" />
<meta-data Android:name="firebase_analytics_collection_enabled"
Android:value="false" />
</application>
</manifest>
apply plugin: 'com.Android.application'
Android {
compileSdkVersion 28
defaultConfig {
applicationId "com.fcm"
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "Android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-Android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.Android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.Android.support.test:runner:1.0.2'
androidTestImplementation 'com.Android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.google.firebase:firebase-messaging:17.1.0'
}
apply plugin: 'com.google.gms.google-services'
package com.fcm;
import Android.app.Service;
import Android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
public class MyFirebaseMessagingService extends FirebaseMessagingService
{
@Override
public void onNewToken(String s)
{
super.onNewToken(s);
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
Log.e("FCM Message Received","You Have FCM Message");
}
}
package com.nexge.fcm;
import Android.support.v7.app.AppCompatActivity;
import Android.os.Bundle;
import Android.util.Log;
import com.google.Android.gms.tasks.OnSuccessListener;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.InstanceIdResult;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener( this, new OnSuccessListener<InstanceIdResult>() {
@Override
public void onSuccess(InstanceIdResult instanceIdResult) {
String newToken = instanceIdResult.getToken();
Log.e("newToken",newToken);
}
});
}
}
Wenn Sie Android 8.0 (API-Ebene 26) als Ziel auswählen, müssen Sie einen oder mehrere Benachrichtigungskanäle implementieren. Wenn Ihre targetSdkVersion auf 25 oder niedriger eingestellt ist und Ihre App unter Android 8.0 (API Level 26) oder höher ausgeführt wird, verhält sie sich genauso wie auf Geräten, auf denen Android 7.1 (API Level 25) oder niedriger ausgeführt wird.
Hinweis: Wenn Sie ein Ziel für Android 8.0 (API Level 26)} festlegen und eine Benachrichtigung ohne Angabe eines Benachrichtigungskanals bereitstellen, wird die Benachrichtigung nicht angezeigt und das System meldet einen Fehler.
Hinweis: Sie können eine neue Einstellung in Android 8.0 (API-Ebene 26) aktivieren, um eine Warnung auf dem Bildschirm anzuzeigen, die als Toast angezeigt wird, wenn eine App, die Android 8.0 (API-Ebene 26) anspricht, versucht, ohne zu posten ein Benachrichtigungskanal. Um die Einstellungen für ein Entwicklungsgerät mit Android 8.0 (API Level 26) zu aktivieren, navigieren Sie zu Einstellungen> Entwickleroptionen und Aktivieren Sie den Benachrichtigungskanal anzeigen Warnungen.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
String id = "id_product";
// The user-visible name of the channel.
CharSequence name = "Product";
// The user-visible description of the channel.
String description = "Notifications regarding our products";
int importance = NotificationManager.IMPORTANCE_MAX;
NotificationChannel mChannel = new NotificationChannel(id, name, importance);
// Configure the notification channel.
mChannel.setDescription(description);
mChannel.enableLights(true);
// Sets the notification light color for notifications posted to this
// channel, if the device supports this feature.
mChannel.setLightColor(Color.RED);
notificationManager.createNotificationChannel(mChannel);
}
Erstellen einer Push-Benachrichtigung unter Android Oreo
Um eine Benachrichtigung zu erstellen, verwenden Sie die NotificationCompat.Builder-Klasse. Der Konstruktor, der zuvor verwendet wurde, hat nur Kontext als Parameter verwendet. In Android O sieht der Konstruktor jedoch so aus:
NotificationCompat.Builder(Context context, String channelId)
Das folgende Code-Snippet zeigt Ihnen, wie Sie eine Benachrichtigung erstellen -
Intent intent1 = new Intent(getApplicationContext(), Ma
inActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 123, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getApplicationContext(),"id_product")
.setSmallIcon(R.drawable.flatpnicon) //your app icon
.setBadgeIconType(R.drawable.flatpnicon) //your app icon
.setChannelId(id)
.setContentTitle(extras.get("nt").toString())
.setAutoCancel(true).setContentIntent(pendingIntent)
.setNumber(1)
.setColor(255)
.setContentText(extras.get("nm").toString())
.setWhen(System.currentTimeMillis());
notificationManager.notify(1, notificationBuilder.build());
Android O bietet Ihnen einige weitere Funktionen zum Anpassen Ihrer Benachrichtigung -
setNumber () - Ermöglicht das Festlegen der in .__ angezeigten Zahl. Menü lange gedrückt halten setChannelId () - Damit können Sie die Kanal-ID explizit festlegen, wenn Sie den alten Konstruktor .__ verwenden. setColor () - Ermöglicht einem RGB-Wert, ein Farbschema für Ihre Benachrichtigung festzulegen setBadgeIconType () - Mit dieser Option können Sie festlegen, dass ein Symbol im lang gedrückten Menü angezeigt wird
für mehr Info siehe Beispiel hier
"Ab Android 8.0 (API-Level 26) müssen alle Benachrichtigungen einem Kanal zugewiesen werden, sonst werden sie nicht angezeigt."
Einzelne Benachrichtigungen müssen jetzt in einem bestimmten Kanal abgelegt werden. ( Referenz )
Option 1 [einfach] Ändern Sie die Android-Zielversion Android 7.1 (API Level 25) oder niedriger.
compileSdkVersion 25
defaultConfig {
applicationId "com.fcm"
minSdkVersion 16
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "Android.support.test.runner.AndroidJUnitRunner"
}
Option 2 Wenn Sie die Zielversion nicht ändern möchten, gehen Sie wie folgt vor
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationChannel nc = new NotificationChannel(“[enter your product id]”, “[Name]”,NotificationManager.IMPORTANCE_MAX);
nc.setDescription(“[your description for the notification]”);
nc.enableLights(true);
nc.setLightColor(Color.GREEN);
nm.createNotificationChannel(nc);
}
Folgenden Builder-Konstruktor verwenden
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(appContext, [id you mentioned above in constructor of NotificationChannel])
Erstelle die Benachrichtigung aus dem Builder
nm.notify("0", notificationBuilder.build())
Sie können unter Klasse zum Generieren von Benachrichtigungen in der unteren und oberen Version von Android (Getestet von 4.2 (Jelly Bean) bis 8.1.1 (Oreo)) verwenden.
public final class NotificationHelper extends Thread {
private Context context;
private NotificationManager notifManager;
private NotificationCompat.Builder notification_compact;
private Notification.Builder notification_builder;
private int OREO_NOTIFICATION_TYPE = 2; //setting default notificaiton type 2, as 1 is not for constant updating
//put string channel name and id in **<>**
private static final String CHANNEL_ONE_ID = "<Your_channel_string_ID>";
private static final String CHANNEL_ONE_NAME = "<Your channel_String_NAME>";
private static final String CHANNEL_TWO_ID = "<Your_channel_string_ID_TWO>";
private static final String CHANNEL_TWO_NAME = "<Your channel_String_NAME_TWO>";
private String title = "", message = "";
/**
* @param context content of activity
* @param title title for notification_compact
* @param message message to show in notification_compact
*/
public NotificationHelper(Context context, String title, String message) {
this.context = context;
this.title = title;
this.message = message;
notifManager = getManager();
}
@Override
public void run() {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {
//do stuff for oreo
createChannels();
postNotificationAboveV25(OREO_NOTIFICATION_TYPE, title);
} else {
//do stuff for other versions
postNotificationUptoV25();
}
}
//method to show notificaiton above nougat
private void postNotificationAboveV25(int id, String title) {
notification_builder = getNotificatonBuilder(id, title);
if (notification_builder != null) {
getManager().notify(id, notification_builder.build());
}
}
//get pending intent to launch activity
private PendingIntent getPendingIntent() {
Intent startActivity = context.getPackageManager()
.getLaunchIntentForPackage(context.getPackageName())
.setPackage(null)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
return PendingIntent.getActivity(context, 0, startActivity, 0);
// Intent resultIntent = new Intent(context, ActionActivity.class);
// return PendingIntent.getActivity(context, AppHelper.NOTIFICATION_ID, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
//method to get notification builder above nougat
private Notification.Builder getNotificatonBuilder(int id, String title) {
switch (id) {
case 1:
return notification_builder = getNotification1(title, message);
case 2:
return notification_builder = getNotification2(title, message);
default:
return notification_builder = getNotification2(title, message);
}
}
//Create the notification_compact that’ll be posted to Channel One
//use this one if your notification is a type of Push notificaiton
// or
//if you are not updating it in continues intervals like every 4 or 5 seconds(ex. Timer)
@SuppressLint("NewApi")
private Notification.Builder getNotification1(String title, String body) {
return new Notification.Builder(context, CHANNEL_ONE_ID)
.setContentTitle(title)
.setContentText(body)
.setSmallIcon(R.drawable.app_icon)
.setAutoCancel(true)
.setTicker(title + AppHelper.getMessage(R.string.started))
.setColor(AppHelper.getColor(context, R.color.colorPrimary))
.setContentIntent(getPendingIntent());
}
//Create the notification_compact that’ll be posted to Channel Two
//use this for continues intervals or updating continuesly
@SuppressLint("NewApi")
private Notification.Builder getNotification2(String title, String body) {
return new Notification.Builder(context, CHANNEL_TWO_ID)
.setContentTitle(title)
.setContentText(body)
.setTicker(title + AppHelper.getMessage(R.string.started))
.setSmallIcon(R.drawable.app_icon)
.setAutoCancel(true)
.setColor(AppHelper.getColor(context, R.color.colorPrimary))
.setContentIntent(getPendingIntent());
}
//method to post notification upto Nougat i.e., below api level 26
@SuppressLint("NewApi")
private void postNotificationUptoV25() {
notification_compact = new NotificationCompat.Builder(context);
notification_compact.setAutoCancel(true);
notification_compact.setSmallIcon(R.drawable.app_icon);
notification_compact.setTicker(title + AppHelper.getMessage(R.string.started));
notification_compact.setContentTitle(title);
notification_compact.setContentText(message);
notification_compact.setColor(AppHelper.getColor(context, R.color.colorPrimary));
notification_compact.setContentIntent(getPendingIntent());
// notification_compact.setWhen(1506067106762L);
getManager().notify(AppHelper.NOTIFICATION_ID, notification_compact.build());
}
//method to update notification
public void updateNotification(String time) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {
//update above NOUGAT V25
if (notification_builder != null) {
notification_builder.setContentText(message + " " + time);
getManager().notify(AppHelper.NOTIFICATION_ID, notification_builder.build());
}
} else {
//update below NOUGAT V25
if (notification_compact != null) {
notification_compact.setContentText(message + " " + time);
getManager().notify(AppHelper.NOTIFICATION_ID, notification_compact.build());
}
}
}
//method to update remainting notification
public void updateRemainingNotification(String time) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {
//update above NOUGAT V25
if (notification_builder != null) {
notification_builder.setContentText(time + AppHelper.getMessage(R.string.remaining));
getManager().notify(AppHelper.NOTIFICATION_ID, notification_builder.build());
}
} else {
//update below NOUGAT V25
if (notification_compact != null) {
notification_compact.setContentText(time + AppHelper.getMessage(R.string.remaining));
getManager().notify(AppHelper.NOTIFICATION_ID, notification_compact.build());
}
}
}
//method to create channels which is necessary above Nougat(API - 25) i.e., at Oreo(API - 26)
@SuppressLint("NewApi")
private void createChannels() {
NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ONE_ID,
CHANNEL_ONE_NAME, notifManager.IMPORTANCE_DEFAULT);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.setShowBadge(true);
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
getManager().createNotificationChannel(notificationChannel);
NotificationChannel notificationChannel2 = new NotificationChannel(CHANNEL_TWO_ID,
CHANNEL_TWO_NAME, notifManager.IMPORTANCE_DEFAULT);
notificationChannel2.enableLights(false);
notificationChannel2.enableVibration(true);
notificationChannel2.setLightColor(Color.RED);
notificationChannel2.setShowBadge(false);
getManager().createNotificationChannel(notificationChannel2);
}
//method to get Object of Notification Manager
private NotificationManager getManager() {
if (notifManager == null)
notifManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
return notifManager;
}
/**
* call this method to destroy notification
*/
public void destroyNotification() {
if (notifManager != null)
notifManager.cancel(AppHelper.NOTIFICATION_ID);
}
}
Rufen Sie diese Klasse einfach von FCM mit context und msg ..__ auf. Als Thread-Klasse können Sie die Benachrichtigung auch ständig aktualisieren.
Vergessen Sie nicht, die destroyNotification () - Methode aufzurufen, wenn Ihre Arbeit endet.
Sie können es nach Belieben entdecken und ändern
notification = new NotificationCompat.Builder(this, Android_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_small_logo)
.setLargeIcon(picture)
.setContentTitle("Title")
.setContentText("Body")
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build();
Android_CHANNEL_ID = "CHANNEL_ID"
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
intent = new Intent(getApplicationContext(), HomeActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
In der oreo-Version kann keine Benachrichtigung ohne Channel hinzugefügt werden. Sie müssen daher folgenden Code in der Firebase-Benachrichtigung hinzufügen.
private void sendMyNotification(String message,String title) {
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
Uri soundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
if (Android.os.Build.VERSION.SDK_INT >= Android.os.Build.VERSION_CODES.O) {
@SuppressLint("WrongConstant")
NotificationChannel notificationChannel=new NotificationChannel("my_notification","n_channel",NotificationManager.IMPORTANCE_MAX);
notificationChannel.setDescription("description");
notificationChannel.setName("Channel Name");
notificationManager.createNotificationChannel(notificationChannel);
}
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.listlogo)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.tlogo))
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setSound(soundUri)
.setContentIntent(pendingIntent)
.setDefaults(Notification.DEFAULT_ALL)
.setPriority(NotificationManager.IMPORTANCE_MAX)
.setOnlyAlertOnce(true)
.setChannelId("my_notification")
.setColor(Color.parseColor("#3F5996"));
//.setProgress(100,50,false);
notificationManager.notify(0, notificationBuilder.build());
}
Dann senden Sie Benachrichtigungen ohne data{}
Objekt in Ihrem JSON. Das ist ein alter Bug (?) Oder soll so funktionieren. Wenn Ihre Benachrichtigung keine Daten enthält, werden keine Benachrichtigungen ausgelöst, während sich Ihre App im Vordergrund befindet.
Beispiel json:
"notification":
{
"title": "notification_title",
"body": "notification_body"
},
"data":
{
"example":"hey",
"example2":"you need me."
},
"priority" : "high",
"registration_ids":
[
"crYjxvFkASE:APA91bGv4GWj9erJ6LsblEzpag5ObkcESEsBthxsJObJ38DhZ3GbSMLlGQK3qS_qvUvrcrg_cqBgCWhBeq1X2wgxO7gmcc_gW0jM4qZYYugF5wraTHwvDKNnjQwn8dpyGEbFMXLOCvE9"
]
nur Datenbenachrichtigungen werden auf Android Oreo
versuchen Sie, die Benachrichtigung zu entfernen
`
remove this key notification
{"notification":
{
"title": "notification_title",
"body": "notification_body"
},
// keep only the data key
"data":
{
"example":"hey",
"example2":"you need me."
},
"priority" : "high",
"registration_ids":
[]
`
wenn sich die App im Hintergrund befindet, wird onRecievedMessage nicht aufgerufen, wenn die Nutzdaten sowohl den Benachrichtigungsschlüssel als auch den Datenschlüssel enthalten.
also entfernen Sie die Benachrichtigung .. und behalten Sie nur den Datenschlüssel .. und es wird gut funktionieren