Android: ¿implementando startForeground para un servicio?

Resuelto JDS asked hace 54 años • 11 respuestas

Así que no estoy seguro de dónde ni cómo implementar este método para que mi servicio se ejecute en primer plano. Actualmente comienzo mi servicio por lo siguiente en otra actividad:

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

¿Y luego en onCreate() de myServices pruebo startForeground()...?

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

Así que sí, estoy un poco perdido y no estoy seguro de cómo implementar esto.

JDS avatar Jan 01 '70 08:01 JDS
Aceptado

Yo comenzaría completando completamente el Notification. Aquí hay un proyecto de muestra que demuestra el uso de startForeground().

CommonsWare avatar Jun 18 '2011 18:06 CommonsWare

Desde su actividad principal, inicie el servicio con el siguiente código:

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

Luego, en su servicio, onCreate()crearía su notificación y la configuraría como primer plano de esta manera:

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);
mikebertiean avatar Mar 15 '2016 17:03 mikebertiean

Solución para Oreo 8.1

He encontrado algunos problemas como RemoteServiceException debido a una identificación de canal no válida con las versiones más recientes de Android. Así lo resolví:

Actividad :

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

Servicio en segundo plano:

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
}

EQUIVALENTE 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;
    }
}
Rawa avatar Nov 29 '2017 09:11 Rawa

Este es mi código para configurar el servicio en primer plano:

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

}

Necesito crear una notificación usando PendingIntent, para poder iniciar mi actividad principal desde la notificación.

Para eliminar la notificación, simplemente llame a stopForeground(true);

Se llama en onStartCommand(). Consulte mi código en: https://github.com/bearstand/greyparrot/blob/master/src/com/xiong/richard/greyparrot/Mp3Recorder.java

Richard avatar Jan 26 '2015 03:01 Richard