2014-09-19 12 views
5

Ho un ricevitore di trasmissione che riceve la trasmissione dello schermo disattivata e quando lo schermo è spento, avvia un'attività. Ho chiamato questa attività LockScreenActivity. Ho aggiunto getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); nel onCreate() dell'attività, in modo che appaia in cima alla schermata di blocco di Android, che è esattamente quello che voglio. Questo funziona abbastanza bene, soprattutto. Il problema si verifica quando premo il tasto Home per inviare qualsiasi app allo sfondo.Ritardo durante l'avvio dell'attività dal servizio

Quando si preme il tasto home per tornare alla schermata iniziale da qualsiasi app, quindi premere immediatamente il pulsante di alimentazione per spegnere lo schermo e premere il pulsante di accensione in un secondo per riaccenderlo, viene visualizzata la schermata di blocco di Android. La mia attività viene creata circa 3-4 secondi dopo. Questo è un enorme ritardo ed è inaccettabile. In altri scenari, questo ritardo non si verifica. Se sono da qualche tempo nella schermata principale o qualche altra app è aperta e faccio clic sul pulsante di accensione due volte in rapida successione, vedo la mia LockScreenActivity prima di vedere la schermata di blocco di Android.

La mia app ha anche alcune altre attività normali (lanciate dal cassetto delle applicazioni) e un servizio che mostra una notifica persistente. La stessa LockScreenActivity viene avviata ogni volta che si fa clic sulla notifica. È interessante notare che se premo il tasto home per ridurre al minimo alcune app e immediatamente clicco sulla notifica della mia app, si apre LockScreenActivity senza alcun ritardo.

Ho cercato molto per qualsiasi soluzione. Ecco quello che ho provato finora:

  1. reso il ricevitore di broadcast eseguito in thread separato passando un gestore al momento della registrazione del ricevitore trasmissione
  2. acquisito una Wakelock nel ricevitore di broadcast onReceive() e rilasciati in onResume() di LockScreenActivity
  3. Crea una task stack separata per LockScreenActivity specificando un taskAffinity differente in manifest. Ho anche giocato con molte combinazioni delle opzioni relative allo stack delle attività, ma finora nulla ha aiutato.
  4. Invece di avviare direttamente l'attività, ha inviato un intento al servizio che quindi avvia l'attività. Purtroppo non ha funzionato nulla.

Ecco la dichiarazione manifesto di attività, e il servizio:

<activity 
     android:name=".LockScreenActivity" 
     android:label="@string/app_name" 
     android:excludeFromRecents="true" 
     android:taskAffinity="@string/task_lockscreen"> 
</activity> 
<service 
     android:name=".services.BaseService" 
     android:enabled="true" > 
</service> 

Broadcast ricevitore:

public class ScreenReceiver extends BroadcastReceiver { 
private static final String LOG_TAG = ScreenReceiver.class.getSimpleName(); 
private static final String HANDLER_THREAD_NAME = "screen_receiver_thread"; 
public static final String WAKELOCK_TAG = "lockscreen_overlay_create_wakelock"; 

@Override 
public void onReceive(Context context, Intent intent) { 
    if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { 
     WakeLockHelper.acquireWakeLock(WAKELOCK_TAG, context); 
     Log.d(LOG_TAG, "Screen off"); 
     context.startService(BaseService.getServiceIntent(context, null, BaseService.ACTION_START_LOCKSCREEN_ACTIVITY)); 
    } else { 
     if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { 
      Log.d(LOG_TAG, "Screen on"); 
     } 
    } 
} 

public static void registerScreenReceiver(Context context){ 
    new BroadcastReceiverRegistration().execute(context); 
} 

private static class BroadcastReceiverRegistration extends AsyncTask<Context, Void, Void>{ 
    @Override 
    protected Void doInBackground(Context... params) { 
     Context context = params[0]; 
     if(Utility.checkForNullAndWarn(context, LOG_TAG)){ 
      return null; 
     } 
     HandlerThread handlerThread = new HandlerThread(HANDLER_THREAD_NAME); 
     handlerThread.start(); 
     Looper looper = handlerThread.getLooper(); //Will block till thread is started, hence using AsyncTask 
     Handler handler = new Handler(looper); 

     IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF); 
     filter.addAction(Intent.ACTION_SCREEN_ON); 
     BroadcastReceiver mReceiver = new ScreenReceiver(); 

     context.registerReceiver(mReceiver, filter, null, handler); 
     return null; 
    } 
} 
} 

WakeLockHelper è una classe che gestisce tutti i wakelocks nella mia app. registerScreenReceiver() viene chiamato dal servizio all'avvio.

Ecco l'onCreate() di LockScreenActivity:

protected void onCreate(Bundle savedInstanceState) { 
    Log.d(LOG_TAG, "LockscreenActivity onCreate()"); 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_lock_screen); 
    if (savedInstanceState == null) { 
     getFragmentManager().beginTransaction() 
       .add(R.id.container, new LockScreenFragment()) 
       .commit(); 
    } 
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); 
    getWindow().setDimAmount((float) 0.4); 
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); 

    int systemUiVisibilityFlags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | 
      View.SYSTEM_UI_FLAG_FULLSCREEN | 
      View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | 
      View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; 
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 
     systemUiVisibilityFlags = systemUiVisibilityFlags | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; 
    } 
    getWindow().getDecorView().setSystemUiVisibility(systemUiVisibilityFlags); 
} 

Ecco il registro quando le cose funzionano come previsto: (schermo è intially accesa, si spegne e riaccende)

09-19 11:00:09.384 31226-31243/com.pvsagar.smartlockscreen D/ScreenReceiver﹕ Screen off 
09-19 11:00:09.384 31226-31226/com.pvsagar.smartlockscreen D/BaseService﹕ Starting lockscreen overlay. 
09-19 11:00:09.394 31226-31226/com.pvsagar.smartlockscreen D/LockScreenActivity﹕ LockscreenActivity onCreate() 
09-19 11:00:09.735 31226-31243/com.pvsagar.smartlockscreen D/ScreenReceiver﹕ Screen on 
Non

molto ritardo tra lo schermo spento e l'invio dell'intenzione e la LockScreenActivity in realtà in fase di avvio.Ora la schermata è inizialmente attiva; Premendo casa da qualche app (qualsiasi app, anche qualche altra attività della mia app); Lo schermo è spento e riacceso:

09-19 11:02:51.557 31226-31243/com.pvsagar.smartlockscreen D/ScreenReceiver﹕ Screen off 
09-19 11:02:51.557 31226-31226/com.pvsagar.smartlockscreen D/BaseService﹕ Starting lockscreen overlay. 
09-19 11:02:51.708 31226-31243/com.pvsagar.smartlockscreen D/ScreenReceiver﹕ Screen on 
09-19 11:02:54.851 31226-31226/com.pvsagar.smartlockscreen D/LockScreenActivity﹕ LockscreenActivity onCreate() 

Qui, come si può vedere, schermare trasmissione viene ricevuta in tempo, il servizio ottiene subito l'intento e inviare l'intento di LockScreenActivity, ma onCreate() di LockScreenActivity è in ritardo entro 3 secondi.

questo è come il LockScreenActivity viene avviato dal servizio:

Intent lockscreenIntent = new Intent(this, LockScreenActivity.class); 
lockscreenIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
Log.d(LOG_TAG, "Starting lockscreen overlay."); 
startActivity(lockscreenIntent); 

Questo è l'intento attesa passò alla notifica (solo per dimostrare che fa la stessa cosa):

Intent notificationIntent = new Intent(context, LockScreenActivity.class); 
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0); 
notificationBuilder.setContentIntent(pendingIntent); 

Non ho idea del perché stia succedendo. Anche GC non sta funzionando troppo. Quale potrebbe essere il problema? Cosa posso fare per superare questo? Qualsiasi suggerimento/idea sarebbe molto apprezzato.

L'intero codice può essere trovato a: https://github.com/aravindsagar/SmartLockScreen/tree/backend_code_strengthening

+0

Ho provato con un lanciatore diversi, come pure, e lo stesso problema persiste. Come posso sapere cosa sta succedendo? Voglio dire come scoprire cosa c'è che non va? – aravindsagar

risposta

3

Dopo molte scavo, scoperto la causa del problema. Apparentemente non è un bug, è una funzionalità che non consente a Servizi o BroadcastReceiver di avviare attività per un massimo di 5 secondi dopo che il pulsante Home è stato premuto. Non è un modo facile per superare questo.

Maggiori informazioni qui: https://code.google.com/p/android/issues/detail?id=4536

ho sostituito l'attività con una finestra aggiunto al window manager del servizio in esecuzione. Questo non causa alcun ritardo.

0

Si prega di trovare la soluzione here

Utilizzando attesa intenti e l'invio della richiesta immediatamente risolto il problema per me, spero che ti aiuta troppo :)

Problemi correlati