web-dev-qa-db-fra.com

Certains périphériques Oreo ne reçoivent pas de notification push

Samsung S8/S5/J2/Note3 obtiennent Firebase Push Notification avec succès soit l'application est tué, en arrière-plan ou au premier plan, 

mais Infinix Note 5 (Android One- Oreo) et Oppo F9(Oreo) n'obtiennent pas de notification Push si l'application est tuée, ils fonctionnent correctement si l'application est en arrière-plan ou au premier plan.

J'ai parcouru de nombreux articles, ceci et ceci , mentionne que les téléphones chinois ont ce problème, et que certains utilisateurs peuvent contourner le problème pour que ces notifications fonctionnent sur leurs téléphones. 

mais je veux savoir si quelque chose est possible du côté du développement pour que la notification fonctionne sur chaque appareil Android. 

Je cible l'API 27, et c'est mon code

public class FirebaseMessagingService  extends com.google.firebase.messaging.FirebaseMessagingService {


  @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        String from = remoteMessage.getFrom();
        Map data = remoteMessage.getData();

        JSONObject jsonObject = new JSONObject();
        Set<String> keys = remoteMessage.getData().keySet();
        for (String key : keys) {
            try {
                jsonObject.put(key, remoteMessage.getData().get(key));
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        message= jsonObject.getString("message");

         sendNotification(message, urlToOpen);



    private void sendNotification(final String msg, final String urlToOpen) {


        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
                PendingIntent.FLAG_ONE_SHOT);

        String channelId = getString(R.string.notification_channel_general);
        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

        NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(this, channelId)
                        .setSmallIcon(R.drawable.notification_icon)
                        .setContentTitle("App Name")
                        .setContentText(msg)
                        .setAutoCancel(true)
                        .setSound(defaultSoundUri)
                        .setPriority(Notification.PRIORITY_MAX)
                        .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(channelId,
                    "App Channel",
                    NotificationManager.IMPORTANCE_HIGH);
            notificationManager.createNotificationChannel(channel);
        }

    notificationManager.notify(0, notificationBuilder.build());

Gradle

compileSdkVersion 27
defaultConfig {
    applicationId "com.myapp.app"
    minSdkVersion 19
    targetSdkVersion 27
    versionCode 2
    versionName "1"
    multiDexEnabled true
    testInstrumentationRunner "Android.support.test.runner.AndroidJUnitRunner"
    vectorDrawables.useSupportLibrary = true
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-Android.txt'), 'proguard-rules.pro'
    }
    debug {
        // Disable fabric build ID generation for debug builds
        ext.enableCrashlytics = false
    }
}

implementation 'com.google.firebase:firebase-messaging:15.0.0'
implementation 'com.google.Android.gms:play-services-location:15.0.0'
implementation 'com.google.Android.gms:play-services-auth:15.0.0'
implementation 'com.google.Android.gms:play-services-basement:16.0.1'
implementation 'com.google.Android.gms:play-services-ads-identifier:16.0.0'
implementation 'com.google.Android.gms:play-services-stats:16.0.1'
implementation 'com.google.Android.gms:play-services-tasks:16.0.1'
implementation 'com.google.Android.gms:play-services-ads-identifier:16.0.0'
implementation 'com.google.Android.gms:play-services-ads-identifier:16.0.0'
implementation 'com.google.Android.gms:play-services-maps:16.0.0'
12
Taha Kirmani

Source: Activer les services d'arrière-plan et les travaux (ou FCM) dans les ROM chinois

Infinix Note 5 (Android One-Oreo) et Oppo F9 (Oreo) ne reçoivent pas de notification Push si l'application est tuée, ils fonctionnent correctement si l'application est en arrière-plan ou au premier plan.

ROM chinoises utilisant (Oxygen OS, MIUI, etc.) lorsque les applications sont balayées depuis la barre des applications récente, votre application se termine (de la même manière que Forcer arrêter). Et, à cause de cela, chaque tâche exécutée en arrière-plan, telle que Services, permet de supprimer Jobs avec l'application. Même les FCM à priorité élevée ne voient pas la lumière du jour dans les ROM chinoises

Problèmes en temps réel:

1) Vous ne pouvez pas aller chercher l’emplacement de l’utilisateur. Donc, aucune application ne fonctionnerait correctement si cela dépend de l'emplacement en temps réel

2) Vous ne pouvez pas recevoir les notifications FCM haute priorité 

3) Aucune tâche/tâche spécifique au temps ne serait exécutée si l'application ne se trouvait pas dans le bac et bien d'autres….

Solution 

l’utilisateur doit activer le démarrage automatique dans les paramètres de l’application pour que le service d’arrière-plan/la tâche reste en cours d’exécution.Par défaut, cette option est désactivée.

Exemple de code

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent = new Intent();

        String manufacturer = Android.os.Build.MANUFACTURER;

        switch (manufacturer) {

            case "xiaomi":
                intent.setComponent(new ComponentName("com.miui.securitycenter",
                        "com.miui.permcenter.autostart.AutoStartManagementActivity"));
                break;
            case "oppo":
                intent.setComponent(new ComponentName("com.coloros.safecenter",
                        "com.coloros.safecenter.permission.startup.StartupAppListActivity"));

                break;
            case "vivo":
                intent.setComponent(new ComponentName("com.vivo.permissionmanager",
                        "com.vivo.permissionmanager.activity.BgStartUpManagerActivity"));
                break;
        }

      List<ResolveInfo> arrayList =  getPackageManager().queryIntentActivities(intent,
              PackageManager.MATCH_DEFAULT_ONLY);

        if (arrayList.size() > 0) {
            startActivity(intent);
        }
    }

}
7
Nilesh Rathod

Dans l'Oreo, ils introduisent un nouveau concept de canalisation de la notification Push. Vous pouvez en savoir plus sur la canalisation ici . Mettre en œuvre la notification pour Oreo et au-dessus du minerai ci-dessous séparément. Vous pouvez vous référer à la réponse suivante pour résolvez le problème .

J'ai résolu le problème dans xamarin.Android, j'espère que cela fonctionnera pour vous. 

5
K K

Depuis oreo, il y a une nouvelle implémentation de Notification Channels ( démarré sous Android 8.0 (API niveau 26) )

vous devez donc créer le canal en utilisant le code ci-dessous

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence name = "News Channel";
            String description = "Default Notification News Channel";
            int importance = NotificationManager.IMPORTANCE_DEFAULT;
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
            channel.setDescription(description);
            NotificationManager notificationManager = getAppContext().getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        }

et remplacer le constructeur de notification comme ci-dessous

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getAppContext(),CHANNEL_ID);

en supposant que vous ayez la valeur CHANNEL_ID comme vous le souhaitez

String CHANNEL_ID = "DEFAULT_NEWS_CHANNEL";

cela a déjà été testé avec le périphérique OnePlus3T, il devrait donc fonctionner pour vous

4
Ashfaq Ahmed

C’est le problème de tous les appareils chinois. Une fois que vous avez tué l’application, elle est supprimée de la mémoire et pas toujours active ... mais dans le cas des autres fabricants, ce n’est pas le cas .. l'application complètement de la mémoire. Moi aussi j'ai fait face à ce problème avec les appareils xiaomi .... ils ont une option pour verrouiller l'application, ce qui permet de garder l'application en mémoire même si elle est morte pour effacer la mémoire vive

4
nitish29

J'espère que le code suivant fonctionnera pour vous. Cela fonctionne pour moi dans tous les appareils.

        Intent notificationIntent = new Intent(context, SplashScreenActivity.class);

        notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

        Uri notificationSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

        NotificationManager notificationManager =
                (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence nameChannel = context.getString(R.string.app_name);
            String descChannel = context.getString(R.string.app_name);
            int importance = NotificationManager.IMPORTANCE_DEFAULT;
            NotificationChannel channel = new NotificationChannel(context.getString(R.string.app_name), nameChannel, importance);
            channel.setDescription(descChannel);
            // Register the channel with the system; you can't change the importance
            // or other notification behaviors after this
            assert notificationManager != null;
            notificationManager.createNotificationChannel(channel);
        }

        PendingIntent pendingIntent = PendingIntent.getActivity((context), 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        // Create Notification
        NotificationCompat.Builder notification = new NotificationCompat.Builder(context, context.getString(R.string.app_name))
                .setChannelId(context.getString(R.string.app_name))
                .setContentTitle(TextUtils.isEmpty(title) ? getString(R.string.app_name) : title)
                .setContentText(description)
                .setTicker(context.getString(R.string.app_name))
                .setSmallIcon(R.drawable.ic_stat_name)
                .setSound(notificationSound)
                .setLights(Color.RED, 3000, 3000)
                .setVibrate(new long[]{500, 500})
                .setWhen(System.currentTimeMillis())
                .setDefaults(Notification.DEFAULT_SOUND)
                .setAutoCancel(true)
                .setContentIntent(pendingIntent);

        if (result != null) {
            notification.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(result));
        }

        assert notificationManager != null;
        notificationManager.notify(100, notification.build());

Je viens de créer Notification Channel, Check If condition for Oreo.

Faites-moi savoir si vous rencontrez un problème. Je suis ici pour vous aider.

Merci.

3
Pratik Butani

J'ai eu le même problème et après avoir cherché et travaillé, J'ai découvert que l'utilisateur devait activer l'autorisation de démarrage automatique et d'optimisation de la batterie manuellement Pour plus de détails, voir this link

0
amin pinjari