stopself - sticky service android
Android: ¿está implementando startForeground para un servicio? (6)
Si desea que IntentService sea un servicio de primer plano
entonces deberías anular el uso onHandleIntent()
como este
Override
protected void onHandleIntent(@Nullable Intent intent) {
startForeground(FOREGROUND_ID,getNotification()); //<-- Makes Foreground
// Do something
stopForeground(true); // <-- Makes it again a normal Service
}
¿Cómo hacer una notificación?
sencillo. Aquí está el getNotification()
public Notification getNotification()
{
Intent intent = new Intent(this, SecondActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,0);
NotificationCompat.Builder foregroundNotification = new NotificationCompat.Builder(this);
foregroundNotification.setOngoing(true);
foregroundNotification.setContentTitle("MY Foreground Notification")
.setContentText("This is the first foreground notification Peace")
.setSmallIcon(android.R.drawable.ic_btn_speak_now)
.setContentIntent(pendingIntent);
return foregroundNotification.build();
}
Comprensión más profunda
¿Qué sucede cuando un servicio se convierte en primer plano?
Esto pasa
¿Qué es el servicio en primer plano?
Un servicio de primer plano se asegura de que
El usuario es consciente de que algo está sucediendo en segundo plano al proporcionar la notificación.
El sistema no mata el servicio cuando se queda sin memoria
Así que no estoy seguro de dónde / cómo implementar este método para hacer 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 myServices ''onCreate () pruebo startForeground () ...?
Notification notification = new Notification();
startForeground(1, notification);
Así que sí, estoy un poco perdido e inseguro de cómo implementar esto.
Solución para Oreo 8.1
Me he encontrado con algunos problemas, como RemoteServiceException, debido a un identificador de canal no válido con las versiones más recientes de Android. Así es como 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)
}
}
BackgroundService:
override fun onCreate() {
super.onCreate()
startForeground()
}
private fun startForeground() {
val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
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
}
Comenzaría rellenando por completo la 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 para onCreate()
crearía su notificación y la establecería como primer plano así:
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);
En mi caso, fue totalmente diferente ya que no tenía actividad para lanzar el servicio en Oreo.
A continuación se detallan los pasos que usé para resolver este problema del servicio en primer plano:
SocketService de clase pública extiende Service {private String TAG = this.getClass (). getSimpleName ();
@Override
public void onCreate() {
Log.d(TAG, "Inside onCreate() API");
if (Build.VERSION.SDK_INT >= 26) {
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
mBuilder.setSmallIcon(R.drawable.ic_launcher);
mBuilder.setContentTitle("Notification Alert, Click Me!");
mBuilder.setContentText("Hi, This is Android Notification Detail!");
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// notificationID allows you to update the notification later on.
mNotificationManager.notify(100, mBuilder.build());
startForeground(100, mBuilder.mNotification);
}
Toast.makeText(getApplicationContext(), "inside onCreate()", Toast.LENGTH_LONG).show();
}
@Override
public int onStartCommand(Intent resultIntent, int resultCode, int startId) {
Log.d(TAG, "inside onStartCommand() API");
return startId;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "inside onDestroy() API");
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
Y después de eso para iniciar este servicio, activé debajo de cmd -
adb -s "+ serial_id +" shell am startforegroundservice -n com.test.socket.sample / .SocketService
Esto me ayuda a comenzar el servicio sin actividad en dispositivos Oreo :)
Este es mi código para establecer 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 comenzar mi actividad principal desde la notificación.
Para eliminar la notificación, simplemente llame al stopForeground (verdadero);
Se llama en el Comando onStart (). Consulte mi código en: https://github.com/bearstand/greyparrot/blob/master/src/com/xiong/richard/greyparrot/Mp3Recorder.java