2014-09-19 34 views
5

Ekran kapalı yayınını alan bir yayın alıcım var ve ekran kapatıldığında, bir Etkinlik başlatır. Bu etkinliği LockScreenActivity olarak adlandırdım. Etkinliğin numaralı telefonuna getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); ekledim, böylece Android kilit ekranının üstünde, tam olarak istediğim gibi görünüyor. Bu çoğunlukla iyi çalışır. Arka planda herhangi bir uygulamasını göndermek için ana ekran düğmesine bastığımda sorun olur.Hizmetten etkinlik başlatılırken gecikme

Herhangi bir uygulamadan ana ekrana dönmek için ana ekran düğmesine bastığımda ve sonra hemen ekrana kapatmak için güç düğmesine basın ve tekrar açmak için güç düğmesine bir saniye basın, Android kilit ekranını gösterir. Etkinliğim yaklaşık 3-4 saniye sonra oluşturuluyor. Bu büyük bir gecikme ve kabul edilemez. Diğer senaryolarda bu gecikme olmaz. Bir süredir ana ekrandaydım veya başka bir uygulama açıksa ve hızlı bir şekilde arka arkaya iki kez güç düğmesine tıklarsam, Android kilit ekranını görmeden önce LockScreenActivity özelliğini görüyorum.

Uygulamamda ayrıca birkaç normal etkinlik (Uygulama çekmecesinden başlatıldı) ve kalıcı bir bildirim gösteren bir hizmet var. Bildirim kilitlendiğinde, aynı LockScreenActivity başlatılır. İlginçtir ki, bazı uygulamaları en aza indirgemek ve hemen uygulamamın bildirimini tıklatmak için ana sayfa düğmesine basarsam, herhangi bir gecikme olmadan LockScreenActivity özelliğini açar.

Herhangi bir çözüm için çok arama yaptım. Ben bugüne kadar dışarı çalıştığım buydu: yayın alıcısı kaydederken

  1. yayın alıcısı en onReceive() bir Uyandırma kilidi Edinilmiş ve onResume() ilk kez kullanıma sunulmasından bir işleyici geçirerek ayrı iplik çalıştırmak yayın alıcısını Yapılan LockScreenActivity
  2. Bildiride farklı bir taskAffinity belirtmek suretiyle LockScreenActivity için ayrı bir görev yığını oluşturdu. Ayrıca, etkinlik yığınıyla ilgili seçeneklerin bir çok kombinasyonunu da oynadım, ancak hiçbir şey şu ana kadar yardımcı olmamıştır.
  3. Etkinliği doğrudan başlatmak yerine, daha sonra etkinliği başlatan servise bir niyet gönderilir. Hiçbir şey maalesef işe yaramadı.

    <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> 
    

    Yayın alıcısı:

    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 Uygulamamda tüm wakelocks yöneten bir sınıftır

İşte tezahür aktivitenin beyanı ve hizmet bu. Servis başladığında registerScreenReceiver() Servis tarafından çağrılır.

İşte LockScreenActivity ait onCreate() var:

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); 
} 

şey beklendiği gibi çalışırken İşte günlüğü var:;

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 

Değil (Ekran başlangıçta açık o açılıp kapandığında ve) Ekran kapalı ve niyet ve aslında LockScreenActivity gönderme arasında çok fazla gecikme.Şimdi Ekran başlangıçta; Bazı uygulamalardan evine basıyorum (herhangi bir uygulama, hatta kendi uygulamamın başka bir aktivitesi); Ekran üzerinde tekrar kapatılır ve:

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() 

Burada, bkz, hizmet derhal niyet alır yayın zamanında ulaşmasına ekran kapatma ve LockScreenActivity niyetiyle göndermek, ama LockScreenActivity ait onCreate() geciktirilir gibi 3 saniye.

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

Bu bildirime geçirilen bekleyen niyet (sadece aynı şeyi yapar göstermek için) olan:

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); 

Bu LockScreenActivity hizmeti tarafından başlatılır nasıl Bunun neden olduğu hakkında hiçbir fikrim yok. GC de çok fazla çalışmıyor. Sorun ne olabilir? Bunu aşmak için ne yapabilirim? Herhangi bir öneri/fikir büyük ölçüde takdir edilecektir. https://github.com/aravindsagar/SmartLockScreen/tree/backend_code_strengthening

+0

Ben de farklı bir fırlatıcı kullanılarak denedim umut ve Aynı problem devam ediyor. Neler olduğunu nasıl bilebilirim? Neyin yanlış olduğunu nasıl öğreneceğim? – aravindsagar

cevap

3

çok kazma sonra sorunun nedenini öğrendim: En

bütün kod

bulunabilir. Görünüşe göre bu bir hata değil, Servisler veya BroadcastReceivers'ın ev düğmesine basıldıktan sonra 5 saniyeye kadar aktiviteleri başlatmasına izin vermeyen bir özellik. Bunu aşmanın kolay bir yolu yok. Burada

diğer bilgiler: https://code.google.com/p/android/issues/detail?id=4536

Ben koşu hizmetinin pencere yöneticisine eklenen bir pencere ile faaliyetini yerini aldı. Bu herhangi bir gecikmeye neden olmaz.

0

hemen benim için sorun çözüldü Niyet Bekleyen ve isteği göndererek kullanarak çözüm here

bulabilirsiniz, çok yardımcı olur :)