10

Kilka lat temu napisałem aplikację alarmową, która działała na systemie Android 2, a teraz próbuję ją zaktualizować do systemu Android 4. W szczególności Samsung Galaxy S4.Android Galaxy S4 - Aktywność widoczna na ekranie blokady

W systemie Android 2, jeśli telefon był w trybie uśpienia, obudziłby telefon i wyświetli ekran "Odłóż lub odrzuć" na ekranie blokady.

W systemie Android 4 budzi telefon, ale trzeba go odblokować, a następnie otworzyć obszar powiadomień, a następnie kliknąć powiadomienie o alarmie, zanim będzie można nacisnąć "Odrzuć".

ja zawsze przy użyciu tego kodu, aby zrobić waking:

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

Czytałem 8 różnych pytania StackOverflow w tej sprawie. Większość z nich podaje powyższy kod, który działał dla mnie wiele lat temu w systemie Android 2, ale nie działa w systemie Android 4. Ale żaden z nich nie pomógł mi rozwiązać tego problemu. Oto pytania, które czytałem i próbowałem:

Android: remove or disable programmatically the Lock Screen on Samsung Galaxy S2 device

How do I create an Activity that is visible on top of the lock screen

How to start a dialog (like alarm dimiss /snooze) that can be clicked without unlocking the screen

Android activity over default lock screen

android device locked, yet want alarm to sound and dialog to appear

Android dialog over lock screen

Show dialog with touch events over lockscreen in Android 2.3

Czy ktoś ma jakieś pomysły, co się zmieniło w Androida 4, które mogły spowodować to?

EDYCJA: Oto jeden z najprostszych przykładów, jakie widziałem w oknie dialogowym alarmu, które nie pojawia się "zminimalizowane". Nie, jak napisano, pojawiają się na ekranie blokady, ale można naprawić z WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED

http://wptrafficanalyzer.in/blog/setting-up-alarm-using-alarmmanager-and-waking-up-screen-and-unlocking-keypad-on-alarm-goes-off-in-android/

Jest napisany z FragmentActivity i DialogFragment, ale nadal działa jako aktywny. Używa AlertDialog.Builder do utworzenia okna dialogowego, a jeśli spróbujesz zrobić to z układem XML, to nie zadziała. Czemu?

+0

ustawiłeś to zezwolenie w manifeście? -> bofredo

+0

Tak, to uprawnienie zawsze było ustawione i używane do pracy na Androidzie 2. – howrad

+0

Próbowałem czegoś nowego. Ustawiłem Blokada ekranu na Brak, ale nadal widzę problem. Aby dać analogię do komputera stacjonarnego, jest tak, jakby okno dialogowe było uruchamiane "zminimalizowane" - zanim pojawi się okno dialogowe, należy dotknąć powiadomienia alarmu. Gdy telefon jest włączony, okno dialogowe wyświetla się tak, jak powinno, ale gdy telefon jest wyłączony, okno dialogowe zaczyna być zminimalizowane. I to nie był problem w systemie Android 2.3 – howrad

Odpowiedz

15

Wyjaśniałem to, a odpowiedź była zupełnie inna niż oczekiwałem.

ten fragment kodu został zawarty w próbce budzik z Android 2, w Działaniu AlarmAlert.java:

@Override 
protected void onStop() { 
    super.onStop(); 
    // Don't hang around. 
    finish(); 
} 

Dla porównania, można zobaczyć plik z kodem przykład w Git przeszłych right here, zawierający powyższą funkcję onStop. To nigdy nie spowodowało problemu w Androidzie 2.

Ale w Androidzie 4, jeśli telefon był wyłączony, ten onStop wystrzeliłby tuż przed wybudzeniem telefonu, skutecznie "minimalizując" Aktywność. Po usunięciu tej funkcji natychmiast zadziałała ponownie.

Ale zastanawiam się, czy to jest problem, który dostają inni ludzie tacy jak @radley i @Guardanis? Wydaje się to mało prawdopodobne, ale daj nam znać, jeśli to rozwiąże Twoje problemy.

Jeśli odwiedzasz tę odpowiedź w przyszłości, a ty dostajesz ten problem, co chciałbym spróbować to:

  1. Wyjmij onStop funkcje.

  2. Dodaj ten kod do działania:

    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); 
    
  3. Upewnij się, że używasz pełną motywu ekranu, a nie tematem dialogowe.

  4. to nie mieć znaczenie dla mnie, ale można spróbować ustawić showOnLockScreen wyraźnie w manifeście: <activity android:name="com.example.MyActivity" android:showOnLockScreen="true"/>

  5. Drugą rzeczą, która nie zrobić różnicę dla mnie, ale może spróbować jest dodanie flaga WindowManager.LayoutParams.FLAG_FULLSCREEN

Mam nadzieję, że to pomoże innym!

+4

Szczególnie nie używanie motywu dialogowego robi różnicę! – bk138

+0

Czy ktoś wie, dlaczego funkcja onStop() jest rzekomo wywoływana podczas aktywności, gdy telefon wychodzi z trybu uśpienia? Obserwuję to również i powoduje to problemy, gdy chcę umieścić działanie przed ekranem blokady. Wszelkie aktualizacje będą mile widziane! –

+0

czy istnieje alternatywa dla motywu okna dialogowego? Chcę wyświetlić okno dialogowe podobne do wiadomości na zablokowanym ekranie i nie mogę użyć motywu okna dialogowego, tylko na pełnym ekranie .. –

3

Nie jestem pewien, czy to jest problem we wszystkich przypadkach, ale dokumentacja na ShowWhenLocked mówi, że dotyczy tylko najwyższego ekranu w pełnym ekranie. Miałem okno o tematyce jako okno dialogowe, które nie działało, ale działało dobrze, gdy zmieniłem je na zwykłe okno pełnoekranowe.

+0

W stylach.xml, ustawiłem element nadrzędny 'android: Theme.DeviceDefault.Light.NoActionBar.Fullscreen', dodałem flagę' WindowManager.LayoutParams.FLAG_FULLSCREEN', ale nadal nie działa. Czy jest coś jeszcze, co muszę zrobić, aby był pełnoekranowy i działa? – howrad

1

Jedno z pytań, które łączysz z odpowiedzią, która wydawała mi się rozwiązaniem tego problemu.

Jest to kod używam który wydaje się działać:

@Override 
public void onAttachedToWindow() { 
     Window window = getWindow(); 

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

     super.onAttachedToWindow(); 
    } 

Jestem również wyraźnie deklarując to w definicji działalności w manifeście:

<activity 
    android:name="com.example.MyActivity" 
    android:label="@string/app_name" 
    android:showOnLockScreen="true" 
    > 

Android activity over default lock screen

+0

Podczas pracy z listą flag przy użyciu znaku + lub a | _should_ powinien dawać taki sam wynik. Ponieważ wszystkie flagi są potęgami dwóch, bitowe OR i dodawanie są równoważne, ale użycie bitowego OR będzie nieco szybsze. Przetestowałem również ten konkretny przykład i oba generują całkowitą wartość 6815872. Żadna z nich nie rozwiązuje tego problemu w Galaxy S4, przepraszam. – howrad

+0

Masz rację, zaktualizowałem swoją odpowiedź. –

+0

Próbowałem twojej zaktualizowanej odpowiedzi, ale jeśli ekran jest wyłączony, działanie nadal jest uruchamiane w zasadzie "zminimalizowane". Musisz otworzyć pasek powiadomień i kliknąć powiadomienie, aby je zobaczyć. Jakieś inne pomysły na temat tego, czego może mi brakować? – howrad

1

Dobrze - więc ostatnio miałem z tym problem, ale z kartą 5,0.2 Galaxy A. Co zaskakujące, to co działa na każdym innym urządzeniu nie działa na Samsunga (tak było od pierwszego urządzenia Samsung Galaxy, łamią się czegoś nowego każdego wydania!)

Ogólnym rozwiązaniem dla wykazujące aktywność na ekranie blokady dla większości urządzeń jest

//wake up device and show even when on lock screen 
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 | 
     WindowManager.LayoutParams.FLAG_FULLSCREEN); 

jednak to nie działa na urządzeniach samsung. Usunięcie FLAG_DISMISS_KEYGUARD robi to jednak.

Patrząc na docs dla tej flagi mamy

Okno flagę: po ustawieniu okna spowoduje zablokowanej klawiaturze zostać odwołany, tylko jeśli nie jest to bezpieczna blokada klawiatury zamka. Ponieważ taka blokada klawiatury nie jest potrzebna dla bezpieczeństwa, nigdy nie pojawi się ponownie, jeśli użytkownik przejdzie do innego okna (w przeciwieństwie do FLAG_SHOW_WHEN_LOCKED, która tylko tymczasowo ukryje zabezpieczone i niezabezpieczone blokady klawiszy, ale zapewni, że pojawią się ponownie, gdy użytkownik przejdzie do inny interfejs, który ich nie ukrywa). Jeśli blokada klawiatury jest obecnie aktywna i jest bezpieczna (wymaga wzoru odblokowania), zanim użytkownik będzie musiał ją potwierdzić przed wyświetleniem tego okna, chyba że ustawiono również FLAG_SHOW_WHEN_LOCKED.

i FLAG_SHOW_WHEN_LOCKED mamy

Okno flag specjalną flagę pozwolić okna wyświetlane, gdy ekran jest zablokowana. Dzięki temu okna aplikacji będą miały pierwszeństwo przed kluczem straży lub innymi ekranami blokującymi. Może być użyty z FLAG_KEEP_SCREEN_ON , aby włączyć ekran i wyświetlić okna bezpośrednio przed wyświetleniem okna strażniczego klucza . Może być używany z FLAG_DISMISS_KEYGUARD do automatycznego w pełni odrzuca niezabezpieczone blokady klawiatury. Ta flaga ma zastosowanie tylko do najwyższego okna na pełnym ekranie .

Można zobaczyć mogą być używane razem, ale wydaje się, Samsung nie będzie przejmować FLAG_SHOW_WHEN_LOCKED jeśli urządzenie jest zablokowane i FLAG_DISMISS_KEYGUARD jest obecny. Moja aplikacja wymaga ustawienia ekranu blokady, więc usunięcie flagi blokującej klawiaturę pozwala mi pokazywać pełnoekranowe czynności na ekranie blokady. Dla mnie, nie dla Samsunga.

+0

Witam, wypróbowałem Twoje rozwiązanie, nadal nie działa. gdy wchodzę i odblokowuję ekran, widzę moją stronę główną aplikacji, zamiast aktywności, która powinna pojawić się jako powiadomienie –

+0

, jeśli nie widzisz nowej aktywności w ogóle, na górze lub poniżej ekranu blokady, to sugeruje, że nie rozpoczynasz działalności w pierwszej kolejności. – Dori

+0

Mine jest pełnoekranowym przejęciem –