13

Jusqu'ici, j'ai ajouté mon code pour utiliser ContextCompat.startForegroundService(context, intentService); pour démarrer mon service. De cette façon, il fonctionne sur android < 26 et sur Android 26 (Oreo) ainsi.Oreo - Le service de premier plan n'affiche pas la notification de premier plan

Je vois encore une différence, dans android oreo Je ne vois pas ma notification de premier plan personnalisé (je vois seulement la notification "l'application est en cours d'exécution"). Dois-je ajuster quelque chose là aussi?

Mon service ressemble à ceci:

public class BaseOverlayService extends Service { 
    @Override 
    public void onCreate() { 
     super.onCreate(); 
     moveToForeground(); 
    } 

    private void moveToForeground() { 
     Notification notification = ...; 
     super.startForeground(NOTIFICATION_ID, notification); 
    } 
} 

exemple officiel

Cet exemple (https://github.com/googlesamples/android-play-location/blob/master/LocationUpdatesForegroundService/app/src/main/java/com/google/android/gms/location/sample/locationupdatesforegroundservice/LocationUpdatesService.java#L200) montre que commentaire, que je devrais utiliser suivant, mais startServiceInForeground n'existe pas ...

if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O) { 
    NotificationManager mNotificationManager = ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)); 
    mNotificationManager.startServiceInForeground(new Intent(this, BaseOverlayService.class), NOTIFICATION_ID, notification); 
} else { 
    startForeground(NOTIFICATION_ID, notification); 
} 

Modifier

Mon avis est créé comme celui-ci, qui travaille sur des milliers d'appareils Android avec l'API < 26 jusqu'à présent:

protected Notification foregroundNotification(int notificationId) 
{ 
    boolean paused = MainApp.getPrefs().sidebarServicePaused(); 
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this); 
    builder.setSmallIcon(R.drawable.icon_not); 
    builder.setContentIntent(notificationIntent()); 
    builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.icon)); 
    builder.setContentTitle(getString(R.string.derived_app_name)); 
    builder.setContentText(getString(checkStatus() ? (paused ? R.string.service_notification_text_paused : R.string.service_notification_text_running) : R.string.service_notification_text_preparing)); 
    builder.setColor(Color.parseColor("#25baa2")); 

    if (MainApp.getPrefs().hideNotificationIcon()) 
     builder.setPriority(NotificationCompat.PRIORITY_MIN); 
    else 
     builder.setPriority(NotificationCompat.PRIORITY_MAX); 

    if (paused) 
     builder.addAction(R.drawable.ic_play_arrow_black_24dp, getString(R.string.resume), resumeIntent(this)); 
    else 
     builder.addAction(R.drawable.ic_pause_black_24dp, getString(R.string.pause), pauseIntent(this)); 

    return builder.build(); 
} 

Répondre

11

Vous devrez peut-être définir canal de notification pour votre application. Vérifiez le journal, il devrait y avoir un avertissement. Vérifiez this pour l'introduction

Je vais vous donner un exemple, ce serait dans Kotin. Tout d'abord, créez un cours comme celui-ci. Vous devrez appeler createMainNotificationChannel() une fois au début de votre application.

class NotificationManager(private val context: Context) { 

    companion object { 
     private val CHANNEL_ID = "YOUR_CHANNEL_ID" 
     private val CHANNEL_NAME = "Your human readable notification channel name" 
     private val CHANNEL_DESCRIPTION = "description" 
    } 

    @RequiresApi(Build.VERSION_CODES.O) 
    fun getMainNotificationId(): String { 
     return CHANNEL_ID 
    } 

    @RequiresApi(Build.VERSION_CODES.O) 
    fun createMainNotificationChannel() { 
      val id = CHANNEL_ID 
      val name = CHANNEL_NAME 
      val description = CHANNEL_DESCRIPTION 
      val importance = android.app.NotificationManager.IMPORTANCE_LOW 
      val mChannel = NotificationChannel(id, name, importance) 
      mChannel.description = description 
      mChannel.enableLights(true) 
      mChannel.lightColor = Color.RED 
      mChannel.enableVibration(true) 
      val mNotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as android.app.NotificationManager 
      mNotificationManager.createNotificationChannel(mChannel) 
    } 
} 

Ensuite, vous pouvez utiliser util comme ce

fun createNotificationCompatBuilder(context: Context): NotificationCompat.Builder { 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 
     return NotificationCompat.Builder(context, NotificationManager(context).mainNotificationId) 
    } else { 
     return NotificationCompat.Builder(context) 
    } 
} 
+0

Le lien que vous avez ajouté est de toute façon très bien, merci. Une question cependant: Est-ce que ce changement signifie, que je n'ai pas nécessairement besoin de montrer une notification pour un service de premier plan plus dans Android Oreo? Parce que les gens m'ont dit que mon application travaille sur Android oreo sans la notification ainsi ... – prom85

+1

eghmmm ... En fait, il ne peut pas fonctionner sans notification. Le travail de fond n'est pas autorisé dans Android o sans composants visibles comme l'activité ou la notification. Si vous exécutez votre service sans système de composants visible, il va le tuer après un certain temps. Vous avez donc besoin d'une notification pour le service si vous souhaitez effectuer un travail d'arrière-plan. Si vous avez besoin d'exécuter quelque chose en arrière-plan avec un certain délai, vous devez vérifier [répartiteur de travail Firebase] (https://github.com/firebase/firebase-jobdispatcher-android). Il vous permet d'exécuter un service planifié. –

+0

J'ai une application de barre latérale avec des éléments de l'interface utilisateur sur le 'WindowManager' et il semble fonctionner avec la notification invisible que j'utilise jusqu'à maintenant (la notification invisible est celle sans canal). Je n'ai pas eu de plaintes dans quelques jours maintenant. L'émulateur ne tue pas mon service dans les 5 secondes non plus – prom85