Android: ¿implementando startForeground para un servicio?
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.
Yo comenzaría completando completamente el Notification
. Aquí hay un proyecto de muestra que demuestra el uso de startForeground()
.
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);
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;
}
}
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