2012-03-31 13 views
6

avvio un'attività da un BroadcastReceiver, che viene attivato da un alaram (tipo RTC_WAKEUP). in onCreate di tale attività aggiungo queste bandiereFLAG_TURN_SCREEN_ON non funziona sempre

getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | 
    WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | 
    WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | 
    WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON   
); 

problema è che a volte (circa 10% dei casi) lo schermo non si accende. l'allarme è attivato correttamente (qui il suono di una notifica, che viene attivato anche nel ricevitore su Ricevi(), quindi, se premo il pulsante di accensione del telefono, lo schermo si accende, mostra la mia attività e si spegne all'istante. che, il pulsante di accensione funziona bene. questo accada su Android 2.3.7 e qui è il metodo OnReceive()

@Override 
public void onReceive(Context context, Intent intent) { 
    m_Context = context; 

    Bundle extras = intent.getExtras(); 
    final int id = extras.getInt("timer_id"); 

    Intent activityIntent = new Intent(m_Context, MyActivity.class); 
    activityIntent.putExtra("timer_id", id); 
    activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP); 
    m_Context.startActivity(activityIntent); 

    // and now load the alarm sound and play it for the desired time 
    showFinishedNotification(); 
} 

vorrei evitare di usare PowerManager, come ha bisogno di un permesso, e le bandiere sono il preferito modo.

quello che potrebbe essere un problema? logcat non mostra alcun problema ...

+0

siete riusciti ad aggirare il problema? – Redwarp

+0

@Redwarp L'unica soluzione era utilizzare un'autorizzazione WAKE_LOCK e utilizzare un blocco statico. C'è un nuovo 'WakefulBroadcastReceiver' nella libreria di supporto, che gestisce il wake lock parziale. Ha bisogno del permesso di cource. – shelll

risposta

3

il problema è che a volte (circa il 10% dei casi) lo schermo non si accende

Se dovessi indovinare, il dispositivo si sta riaddormentando prima dell'avvio dell'attività. Una volta restituito il numero onReceive(), il dispositivo può e si riaddormenta, e ci vorrà qualche tempo dopo il ritorno onReceive() prima che inizi l'attività.

Questo stesso scenario, ma sostituendo startActivity() con startService(), è il motivo per cui ho dovuto scrivere WakefulIntentService, che utilizza un WakeLock per garantire che il dispositivo rimane sveglio abbastanza a lungo per poter fare il suo lavoro, quindi rilascia il WakeLock.

+0

il dispositivo dovrebbe essere sveglio, poiché è in riproduzione l'audio della notifica. ... posso mettere il ricevitore in stato di Stop con Thread.sleep (...) e il dispositivo non si addormenta? o con un messaggio in ritardo (nuovo gestore()). postDelayed (...))? – shelll

+0

@shelll: "potrei mettere il ricevitore in modalità sleep con Thread.sleep (...) e il dispositivo non si addormenterà?" -- no. Innanzitutto, ciò impedirà l'avvio dell'attività fino a dopo il completamento di "sleep()", perché "onReceive()" viene richiamato sul thread dell'applicazione principale. Secondo, Android ucciderà il tuo 'BroadcastReceiver' se legherai troppo a lungo il thread dell'applicazione principale. "Posso mettere il ricevitore in modalità sleep con Thread.sleep (...) e il dispositivo non si addormenta?" - Questo non impedirà al dispositivo di addormentarsi. Aumenterebbe di molto la frequenza di questo problema. – CommonsWare

+0

OK, quindi non dormire(), ma come posso sentire il suono della notifica (lo ripeto finché non viene annullato manualmente), ma lo schermo non si accende? – shelll

5

Sono un po 'in ritardo per la festa qui, ma ho combattuto per un po' ora e finalmente ho trovato il modo di sbloccare lo schermo ogni volta. Aggiungo i flag nell'evento onAttachToWindow(). Tipicamente lo faccio da un WakefulBroadcastReceiver in modo che le transizioni dello schermo siano fluide, ma questo dipende dal caso d'uso.

@Override 
public void onAttachedToWindow() { 
    super.onAttachedToWindow(); 
    //Screen On 
    getWindow().addFlags(
      WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED 
        | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD 
        | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON 
        | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); 
} 

private void clearFlags() { 
    //Don't forget to clear the flags at some point in time. 
    getWindow().clearFlags(
       WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED 
         | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD 
         | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON 
         | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); 
} 
5

Dalla mia esperienza e la ricerca su questo argomento:

  • Il FLAG_TURN_SCREEN_ON non può essere utilizzato per accendere il sullo schermo e fuori più volte nella vostra applicazione.

  • Il FLAG_TURN_SCREEN_ON può essere utilizzato solo una volta per cambiare lo schermo ON quando creating a new activity (preferibilmente nel metodo onCreate()) o when re-creating a view.

Ora, è possibile aggirare questa limitazione:

  • Il lancio di un nuova attività e impostando il flag lì, poi finendo l'attività (da parte dell'utente o di programmazione) per lasciare la schermata di turno off.
  • Impostare i parametri params.screenBrightness su as "dim" as possible, a volte la schermata "appare OFF". È quindi possibile aumentare la luminosità per "accendere" lo schermo.Tuttavia, questo spesso non funziona in quanto lo schermo è ancora scuro ma visibile, inoltre questo non funziona se l'utente blocca il telefono.
  • Utilizzo di Power Manager Wakelock (funziona ancora, ma Android ha deprecato questa funzionalità, quindi scoraggiano l'utilizzo di questa tecnica). Tuttavia, per quanto posso dire questo è l'unico modo in cui posso ottenere la mia applicazione per attivare lo schermo ON/OFF in modo affidabile.

Nessuno di questi è l'ideale (in realtà si sentono come hack) ma basta utilizzare quello che meglio si adatta alle proprie esigenze applicative.

Si può leggere di più qui:

Problemi correlati