web-dev-qa-db-fra.com

Les messages de notification FCM ne sont pas reçus dans la version Android Oreo?

J'ai envoyer une notification FCM du serveur aux utilisateurs. Cela fonctionne bien (jusqu’à api 25), mais à Oreo lorsque l’application n’est pas en arrière-plan (les services sont fermés) (ou) complètement fermée. ont attaché le code FCM

Manifest.xml

<?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>

app/gradle

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'

MyFirebaseMessagingService.Java

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

MainActivity.Java

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);
            }
        });
    }
}
20
Srinivasan M

Lorsque vous ciblez Android 8.0 (API de niveau 26), vous devez implémenter un ou plusieurs canaux de notification. Si votre targetSdkVersion est défini sur 25 ou inférieur, lorsque votre application s'exécute sur Android 8.0 (API niveau 26) ou supérieur, il se comporte de la même manière que sur les appareils fonctionnant sous Android 7.1 (API niveau 25) ou inférieur.

Remarque: Si vous ciblez Android 8.0 (API niveau 26) et publiez une notification sans spécifier de canal de notification, la notification n'apparaît pas et le système enregistre une erreur.

Remarque: Vous pouvez activer un nouveau paramètre dans Android 8.0 (API niveau 26) pour afficher un avertissement à l'écran qui apparaît sous forme de pain grillé lorsqu'une application ciblant Android 8.0 (API niveau 26) tente de publier sans notification. canal. Pour activer le paramètre d'un périphérique de développement exécutant Android 8.0 (API de niveau 26), accédez à Paramètres> Options du développeur et activer les avertissements Afficher le canal de notification.

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

Création d'une notification push sur Android Oreo

Pour créer une notification, vous utiliserez la classe NotificationCompat.Builder. Le constructeur utilisé auparavant ne prenait que le contexte, mais sous Android O, le constructeur ressemble à ceci:

NotificationCompat.Builder(Context context, String channelId)

L'extrait de code suivant vous montrera comment créer une notification -

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 vous donne quelques fonctions supplémentaires pour personnaliser votre notification -

setNumber () - vous permet de définir le numéro affiché dans le appuyez longuement sur le menu setChannelId () - vous permet de définir explicitement l'identificateur de canal si vous utilisez l'ancien constructeur setColor () - permet à une valeur RVB de définir un thème de couleur pour votre notification setBadgeIconType () - vous permet de définir une icône à afficher dans le menu de la presse longue

pour plus d'informations voir l'exemple ici

5
Vishal Thakkar

"À partir d'Android 8.0 (API niveau 26), toutes les notifications doivent être attribuées à un canal, sinon celui-ci n'apparaîtra pas."

Les notifications individuelles doivent maintenant être placées dans un canal spécifique. ( Référence )

Option 1 [simple] Modifier la version cible d'Android Android 7.1 (niveau 25 de l'API) ou une version inférieure.

compileSdkVersion 25
    defaultConfig {
        applicationId "com.fcm"
        minSdkVersion 16
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "Android.support.test.runner.AndroidJUnitRunner"
    }

Option 2 Si vous ne souhaitez pas modifier la version cible, suivez la méthode suivante

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

Utiliser le constructeur suivant Builder

NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(appContext, [id you mentioned above in constructor of NotificationChannel])

Créer la notification à partir du générateur

nm.notify("0", notificationBuilder.build())
5
aanshu

Vous pouvez utiliser la classe ci-dessous pour générer une notification dans les versions inférieure et supérieure d'Android (testé entre 4.2 (Jelly bean) et 8.1.1 (Oreo)).

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

Appelez simplement cette classe à partir de FCM, avec contexte et msg . En tant que classe de thread, vous pouvez également mettre à jour la notification à tout moment.

N'oubliez pas d'appeler la méthode destroyNotification () , à la fin de votre travail.

Vous pouvez le découvrir et y apporter des modifications à votre guise

1
Ranjan Das

Dans la version oreo ne peut pas ajouter de notification sans Channel, vous devez donc ajouter le code suivant dans la notification firebase. La classe de service de notification oreo sans channel ne peut pas envoyer de notification: 

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