138 votes

Android - mise en œuvre de startForeground pour un service ?

Je ne suis donc pas sûr de savoir où/comment mettre en œuvre cette méthode pour faire fonctionner mon service en avant-plan. Actuellement, je démarre mon service par ce qui suit dans une autre activité :

Intent i = new Intent(context, myService.class); 
context.startService(i);

Et ensuite, dans le onCreate() de myServices, j'essaie le startForeground()... ?

Notification notification = new Notification();
startForeground(1, notification);

Donc oui, je suis un peu perdu et incertain de la façon de mettre en œuvre cette solution.

0 votes

Cela ne fonctionne pas, du moins pour autant que je puisse dire, mon service fonctionne toujours comme un service d'arrière-plan et est tué.

0 votes

139voto

CommonsWare Points 402670

Je commencerais par remplir complètement le Notification . Voici un exemple de projet démontrant l'utilisation de startForeground() .

10 votes

Est-il possible d'utiliser startForeground() sans notification ? Ou peut-on mettre à jour ultérieurement la même notification ?

3 votes

Y a-t-il une raison particulière pour laquelle vous avez utilisé 1337 ?

34 votes

@DoctorOreo : Il doit être unique dans l'application, mais pas nécessairement unique sur l'appareil. J'ai choisi 1337 parce que, eh bien, c'est 1337 . :-)

82voto

mikebertiean Points 2533

Depuis votre activité principale, démarrez le service avec le code suivant :

Intent i = new Intent(context, MyService.class); 
context.startService(i);

Alors dans votre service pour onCreate() vous construisez votre notification et la mettez en avant-plan comme ceci :

Intent notificationIntent = new Intent(this, MainActivity.class);

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
                notificationIntent, 0);

Notification notification = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.app_icon)
                .setContentTitle("My Awesome App")
                .setContentText("Doing some work...")
                .setContentIntent(pendingIntent).build();

startForeground(1337, notification);

43voto

Rawa Points 876

Solution pour Oreo 8.1

J'ai rencontré des problèmes tels que RemoteServiceException à cause d'un identifiant de canal invalide avec les versions les plus récentes d'Android. Voici comment je l'ai résolu :

Activité :

override fun onCreate(savedInstanceState: Bundle?) {
    val intent = Intent(this, BackgroundService::class.java)

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        startForegroundService(intent)
    } else {
        startService(intent)
    }
}

BackgroundService :

override fun onCreate() {
    super.onCreate()
    startForeground()
}

private fun startForeground() {

    val channelId =
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                createNotificationChannel()
            } else {
                // If earlier version channel ID is not used
                // https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
                ""
            }

    val notificationBuilder = NotificationCompat.Builder(this, channelId )
    val notification = notificationBuilder.setOngoing(true)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setPriority(PRIORITY_MIN)
            .setCategory(Notification.CATEGORY_SERVICE)
            .build()
    startForeground(101, notification)
}

@RequiresApi(Build.VERSION_CODES.O)
private fun createNotificationChannel(): String{
    val channelId = "my_service"
    val channelName = "My Background Service"
    val chan = NotificationChannel(channelId,
            channelName, NotificationManager.IMPORTANCE_HIGH)
    chan.lightColor = Color.BLUE
    chan.importance = NotificationManager.IMPORTANCE_NONE
    chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
    val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    service.createNotificationChannel(chan)
    return channelId
}

ÉQUIVALENT JAVA

public class YourService extends Service {

    // Constants
    private static final int ID_SERVICE = 101;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        return START_STICKY;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        // do stuff like register for BroadcastReceiver, etc.

        // Create the Foreground Service
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        String channelId = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? createNotificationChannel(notificationManager) : "";
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId);
        Notification notification = notificationBuilder.setOngoing(true)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setPriority(PRIORITY_MIN)
                .setCategory(NotificationCompat.CATEGORY_SERVICE)
                .build();

        startForeground(ID_SERVICE, notification);
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private String createNotificationChannel(NotificationManager notificationManager){
        String channelId = "my_service_channelid";
        String channelName = "My Foreground Service";
        NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH);
        // omitted the LED color
        channel.setImportance(NotificationManager.IMPORTANCE_NONE);
        channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
        notificationManager.createNotificationChannel(channel);
        return channelId;
    }
}

32voto

Richard Points 79

Voici mon code pour mettre le service au premier plan :

private void runAsForeground(){
    Intent notificationIntent = new Intent(this, RecorderMainActivity.class);
    PendingIntent pendingIntent=PendingIntent.getActivity(this, 0,
            notificationIntent, Intent.FLAG_ACTIVITY_NEW_TASK);

    Notification notification=new NotificationCompat.Builder(this)
                                .setSmallIcon(R.drawable.ic_launcher)
                                .setContentText(getString(R.string.isRecording))
                                .setContentIntent(pendingIntent).build();

    startForeground(NOTIFICATION_ID, notification);

}

Je dois créer une notification à l'aide de PendingIntent, afin de pouvoir lancer mon activité principale à partir de cette notification.

Pour supprimer la notification, il suffit d'appeler la fonction stopForeground(true) ;

Il est appelé dans le onStartCommand(). Veuillez vous référer à mon code à : https://github.com/bearstand/greyparrot/blob/master/src/com/xiong/richard/greyparrot/Mp3Recorder.java

23voto

Edgar Khimich Points 89

En plus de RAWA réponse, cette paix du code :

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    startForegroundService(intent)
} else {
    startService(intent)
}

Vous pouvez changer pour :

ContextCompat.startForegroundService(context, yourIntent);

Si vous regardez à l'intérieur de cette méthode, vous verrez qu'elle fait tout le travail de vérification pour vous.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X