2012-03-29 8 views
7

Tengo un IntentService y quiero que sea permanente con una notificación en curso. El problema es que la notificación aparece y luego desaparece de inmediato. El servicio continúa funcionando. ¿Cómo debo usar startForeground en un IntentService?StartForeground para IntentService

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    super.onStartCommand(intent, flags, startId); 
    Notification notification = new Notification(R.drawable.marker, "Notification service is running", 
      System.currentTimeMillis()); 
    Intent notificationIntent = new Intent(this, DashboardActivity.class); 
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| 
     Intent.FLAG_ACTIVITY_SINGLE_TOP); 
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); 
    notification.setLatestEventInfo(this, "App", 
      "Notification service is running", pendingIntent); 
    notification.flags|=Notification.FLAG_NO_CLEAR; 
    startForeground(1337, notification); 
    return START_STICKY; 
} 

@Override 
protected void onHandleIntent(Intent intent) { 

    String id = intent.getStringExtra(ID); 
    WebSocketConnectConfig config = new WebSocketConnectConfig(); 
    try { 
     config.setUrl(new URI("ws://" + App.NET_ADDRESS 
       + "/App/socket?id="+id)); 
    } catch (URISyntaxException e) { 
     e.printStackTrace(); 
    } 
    ws = SimpleSocketFactory.create(config, this); 
    ws.open(); 
} 

Gracias

+2

incluyen su código demasiado – waqaslam

Respuesta

9

esto no debería ser un IntentService. Según lo escrito, su IntentService vivirá por un milisegundo más o menos. Una vez que onHandleIntent() regresa, el servicio se destruye. Esto debería ser un Service normal, donde bifurca su propio hilo y gestiona la duración del hilo y el servicio.

La razón por la cual su Notification se va inmediatamente es porque el servicio se va a cerrar inmediatamente.

+1

Gracias, me convertí en un servicio y ahora se está trabajando. – Matroska

+2

Votación abajo porque: es probable que sea una respuesta incorrecta. Extracto de los documentos de IntentService: "Todas las solicitudes se manejan en un solo hilo de trabajo: * pueden tomar el tiempo que sea necesario * (y no bloqueará el bucle principal de la aplicación), pero solo se procesará una solicitud a la vez". Nada dijo acerca de milisegundos o menos. https://developer.android.com/reference/android/app/IntentService.html – GregoryK

+1

Tal como está escrito, este 'IntentService' durará un milisegundo más o menos, por la sencilla razón de que el código en' onHandleIntent() 'solo tardará un milisegundo en ejecutarse. – CommonsWare

1

Como documentation para IntentService estados:

... el servicio se inicia cuando sea necesario, se encarga de cada Intención a su vez mediante un hilo trabajador, y se detiene a sí misma cuando se queda sin trabajo.

Entonces, supongo que el problema es que su servicio está sin trabajo después de que se haya terminado onHandleIntent(). Por lo tanto, el servicio se detiene y la notificación se desaprovecha. Por lo tanto, el concepto de IntentService probablemente no sea el mejor caso para su tarea.


Como el título de la pregunta es "StartForeground para IntentService", me gustaría aclarar algunas cosas:

Es muy simple para hacer su IntentService para funcionar en primer plano (véase a continuación Código), pero para asegurarse de que necesita considerar varias cosas:

  • No ejecute el servicio en primer plano si solo lleva unos segundos: eso podría molestar a los usuarios. Imagine que ejecuta tareas breves periódicamente; eso hará que las notificaciones aparezcan y desaparezcan. Uhhhh *

  • Es posible que deba hacer que su servicio sea capaz de mantener el dispositivo en funcionamiento (pero esa es otra historia que se cubre bastante bien en stackoverflow) *

  • Si ha puesto en cola múltiples intentos de IntentService, el siguiente código terminará mostrando/ocultando la notificación. (Así que podría haber una mejor solución para su caso, ya que @CommonsWare sugiere extender el Servicio y hacer todo usted mismo, sin embargo, quisiera mencionar que no hay nada en JavaDent para IntentService que diga que solo funciona unos segundos; funciona tanto como lo que tiene que hacer algo.)


public class ForegroundService extends IntentService { 

    private static final String TAG = "FrgrndSrv"; 

    public ForegroundService() { 
     super(TAG); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 

     Notification.Builder builder = new Notification.Builder(getBaseContext()) 
       .setSmallIcon(R.drawable.ic_foreground_service) 
       .setTicker("Your Ticker") // use something from something from R.string 
       .setContentTitle("Your content title") // use something from something from 
       .setContentText("Your content text") // use something from something from 
       .setProgress(0, 0, true); // display indeterminate progress 

     startForeground(1, builder.build()); 
     try { 
      doIntesiveWork(); 
     } finally { 
      stopForeground(true); 
     } 
    } 

    protected void doIntesiveWork() { 
     // Below should be your logic that takes lots of time 
     try { 
      Thread.sleep(10000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

Una regla general para la programación de computadoras es: nunca haga suposiciones sobre un recurso que otra cosa adquirió en su nombre. No creaste el hilo de fondo utilizado por 'IntentService'; por lo tanto, no debe hacer suposiciones sobre cuánto tiempo puede usarlo de manera segura. Nos encontramos con este problema con 'AsyncTask', donde Google modificó las reglas para' execute() ', lo que te limita a un único hilo en todas las tareas. Si desea mantener un hilo por más tiempo que un breve período de tiempo, cree su propio hilo. Votación hacia abajo para recomendar prácticas de programación embarazosas. – CommonsWare

+1

@CommonsWare Veo tu punto y lo entiendo. Eso tiene sentido. En realidad, estaba un poco en desacuerdo con la afirmación "Como está escrito, su IntentService vivirá por un milisegundo más o menos". No estoy tratando de hacer suposiciones, API java dice: "IntentService es una clase base para servicios que manejan solicitudes asíncronas (expresadas como Intents) bajo demanda. Los clientes envían solicitudes a través de startService (Intent) llamadas; el servicio se inicia según sea necesario, maneja cada Intento a su vez usando un hilo de trabajo, y se detiene cuando se queda sin trabajo ". – GregoryK

Cuestiones relacionadas