2011-03-13 11 views
7

Tengo esta aplicación que necesita ejecutar un servicio (de fondo) que emite un pitido periódicamente. El teléfono debe emitir un pitido durante todo el día durante 5 segundos cada un minuto (se utilizó un controlador en el servicio). He implementado este servicio que hace esto perfectamente, pero cuando el teléfono entra en modo de sueño profundo, se detiene la ejecución de este controlador. Utilizando la respuesta this de la pregunta en SO, logré usar bloqueos de activación y funciona bien. Pero cuando puse explícitamente el teléfono en modo de suspensión profunda, el controlador deja de ejecutarse. ¿Dónde coloco el wakelock en el servicio? Fragmento de código a continuación.Wake bloquea el servicio de Android recurrente

public class PlaySound extends Service{ 
PowerManager.WakeLock wl ; 
    PowerManager pm; 
private SoundManager mSoundManager; 
    boolean wakeUpFlag = false; 

@Override 
    public void onCreate(){ 
     super.onCreate(); 
     mSoundManager = new SoundManager(); 
     mSoundManager.initSounds(getBaseContext()); 
     mSoundManager.addSound(1, R.raw.sound); 
    } 
@Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     startservice(); 
     return START_STICKY; 
    } 
private void startservice() { 
     System.out.println("Started the service"); 
     timer.scheduleAtFixedRate(new TimerTask() { 
      public void run() { 
       toastHandler.sendEmptyMessage(0); 
      } 
     }, 0, 60000); 
    } 
private final Handler toastHandler = new Handler() 
    { 
     @Override 
     public void handleMessage(Message msg) 
     { 
      result =start(); 

       System.out.println("result"+result); 
       close(); 
     } 
    }; 

protected void close() { 
     try { 
      if(wakeUpFlag){ 
       wl.release(); 
       System.out.println("Released the wakelock"); 
      } 

      if(!pm.isScreenOn()){ 
       System.out.println("Screen is off - back to sleep"); 
       pm.goToSleep(1000); 
      } 
      else{ 
       System.out.println("Screen is on - no need to sleep"); 
      } 
      bs.close(); 
      writer.close(); 
      System.out.println("Closed socket and writer"); 
      System.out.println("Size of file:"+f.length()/1024); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
public void start(){ 
     try{ 
      wakeUpFlag = false; 
      pm = (PowerManager)getSystemService(Context.POWER_SERVICE); 


      if(!pm.isScreenOn()) { 
       wakeUpFlag = true; 
       wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE,"CollectData"); 
       System.out.println("Screen off - wake lock acquired"); 
       wl.acquire(); 
      } 
      else{ 
       System.out.println("Screen on - no need of wake lock"); 
      } 



     } 
     catch(Exception e){ 
      e.printStackTrace(); 
     } 
mSoundManager.playSound(1); 
} 

Respuesta

3

Sigue el patrón Mark Murphy proporciona el WakefulIntentService. Sugiero que busque sus libros, no solo para la explicación detallada de esta clase y el ejemplo que incluye en uno de ellos, sino también para la otra gran cantidad de información que encontrará en ellos.

Acabo de implementar recientemente este patrón para mi aplicación principal y esta clase funciona como un encanto.

+0

.Ha suscrito sus libros ... debo decir ... ¡son geniales! Gracias –

4

No creo que está utilizando la bandera correcta accorinding para el androide Fior documentación PowerManager:

* Si mantiene un wakelock parcial, la CPU continuará funcionando, independientemente de cualquier temporizadores e incluso después de la el usuario presiona el botón de encendido. En todos los demás wakelocks, la CPU se ejecutará, pero el usuario aún puede poner el dispositivo en modo de suspensión con el botón de encendido.

En otras palabras, tratar de usar PARTIAL_WAKE_LOCK ya que es el único que GARANTIAS la CPU para ejecutar

1

Creo que sería mejor usar android.app.AlarmManager para programar una alarma de despertador. Sin embargo, ten cuidado: no quieres hacer ningún trabajo de larga duración en tu método onReceive() ya que normalmente se llama en el hilo principal y suspenderá tu actividad. Aún necesitará adquirir el wakelock durante la duración de su tarea para evitar que el teléfono se quede dormido en el medio.