Obsługa dekoracji systemu

Poniżej znajdziesz informacje o zmianach w obszarach związanych z wyświetlaniem:

Dekoracje systemowe

Android 10 obsługuje konfigurowanie dodatkowych na wyświetlanie określonych elementów dekoracyjnych systemu, takich jak tapeta, pasek nawigacyjny, i program uruchamiający. Domyślnie na głównym ekranie widać wszystkie dekoracje systemowe. ekrany dodatkowe pokazują te opcjonalnie włączone. Obsługa edytora metody wprowadzania (IME) można ustawiać niezależnie od innych dekoracji systemowych.

Użyj formatu: DisplayWindowSettings#setShouldShowSystemDecorsLocked() , aby dodać obsługę dekoracji systemowych na konkretnym wyświetlaczu domyślną wartość w argumencie /data/system/display_settings.xml. Na przykład: Więcej informacji znajdziesz w artykule Ustawienia wyświetlacza.

Implementacja

DisplayWindowSettings#setShouldShowSystemDecorsLocked() jest też widoczny w tych lokalizacjach WindowManager#setShouldShowSystemDecors() do testowania. Wyzwalanie tej metody z zamiarem włączenia dekoracji systemowych, nie dodaje okien dekoracyjnych, podane wcześniej lub usuń je, jeśli wcześniej były widoczne. Najwięcej zmiana obsługi dekoracji systemu zaczyna w pełni obowiązywać dopiero po i ponownym uruchomieniu urządzenia.

Sprawdza, czy w bazie kodu WindowManager są obsługiwane dekoracje systemowe zwykle trwa przez DisplayContent#supportsSystemDecorations() podczas sprawdza pod kątem usług zewnętrznych (np. UI systemu, aby sprawdzić, czy pasek nawigacyjny (powinna być widoczna), użyj WindowManager#shouldShowSystemDecors(). Aby dowiedzieć się, na co wpływa to ustawienie, zapoznaj się z punktami wywołania w tych metod.

Okna dekoracyjne interfejsu systemu

Android 10 dodaje obsługę okien dekoracyjnych systemu tylko na pasku nawigacyjnym. Jest on niezbędny. do poruszania się między aktywnościami i aplikacjami. Pasek nawigacyjny jest domyślnie wyświetlany Afordancje związane z powrotem i domem. Jest to uwzględniane tylko wtedy, gdy docelowy wyświetlacz obsługuje dekoracje systemowe (patrz DisplayWindowSettings).

Pasek stanu jest bardziej skomplikowanym oknem systemowym, a także obszar powiadomień, Szybkie ustawienia i Ekran blokady. Na Androidzie 10, pasek stanu nie jest obsługiwany na wyświetlaczach dodatkowych. Dlatego powiadomienia, ustawienia i pełna blokada klawiszy są dostępne tylko na głównym wyświetlaczu.

Okno systemowe Przegląd/Ostatnie nie jest obsługiwane na dodatkowym ekrany. W Androidzie 10 usługa AOSP wyświetla tylko Ostatnie na domyślny ekran z aktywnością ze wszystkich wyświetlaczy. Po uruchomieniu z Ostatnie, aktywność na drugim wyświetlaczu jest przenoszona na wierzch które będą domyślnie wyświetlane. W przypadku tego podejścia występują znane problemy, takie jak aktualizowany natychmiast, gdy aplikacje pojawią się na innych ekranach.

Implementacja

Aby wdrożyć dodatkowe funkcje interfejsu systemu, producenci urządzeń powinni stosować pojedynczy komponent interfejsu systemu, który nasłuchuje dodania/usunięcia wyświetlaczy oraz prezentacja odpowiednich treści.

Komponent UI systemu, który obsługuje wieloekranowy wyświetlacz w następujących przypadkach:

  • Inicjowanie wielu wyświetlacza podczas uruchamiania
  • Wyświetlacz dodany w czasie działania
  • Wyświetlacz został usunięty w czasie działania

Gdy interfejs systemu wykryje dodanie wyświetlacza przed WindowManagerem, utworzy zalicza je do sytuacji wyścigowej. Aby tego uniknąć, zastosuj niestandardowe wywołanie zwrotne z WindowManager do interfejsu systemowego po dodaniu wyświetlacza zamiast subskrypcji Zdarzenia DisplayManagera.DisplayListener. Dla przykładowej implementacji pomoc dotyczącą paska nawigacyjnego znajdziesz na CommandQueue.Callbacks#onDisplayReady i WallpaperManagerInternal#onDisplayReady w przypadku tapet.

Oprócz tego Android 10 udostępnia te aktualizacje:

  • Klasa NavigationBarController kontroluje wszystkie funkcje związane z paskami nawigacyjnymi.
  • Aby wyświetlić dostosowany pasek nawigacyjny, zobacz CarStatusBar.
  • Aplikacja TYPE_NAVIGATION_BAR nie jest już ograniczona do jednej osoby i można go używać w przypadku każdego wyświetlacza.
  • Komponent IWindowManager#hasNavigationBar() został zaktualizowany, aby zawierał displayId – tylko w interfejsie systemowym.

Wyrzutnia

W Androidzie 10 każdy wyświetlacz skonfigurowany do obsługi dekoracje systemowe mają specjalny stos domowy do działań uruchamiających w typie WindowConfiguration#ACTIVITY_TYPE_HOME. Każdy wyświetlacz korzysta z osobnej instancji działania programu uruchamiającego.

Rysunek 1. Przykład programu uruchamiającego z kilkoma wyświetlaczami dla platform/development/samples/MultiDisplay

Większość istniejących programów uruchamiających nie obsługuje wielu wystąpień i nie są one zoptymalizowane do dużych ekranów. Poza tym często oczekujemy czegoś innego na ekranach dodatkowych/zewnętrznych. Aby udostępnić dedykowaną aktywność dodatkową Android 10 wprowadza kategorię SECONDARY_HOME w zamierzeniach filtry. Wystąpienia tej aktywności są używane na wszystkich wyświetlaczach, które obsługują system dekoracji, po jednej na wyświetlacz.

<activity>
    ...
    <intent-filter>
        <category android:name="android.intent.category.SECONDARY_HOME" />
        ...
    </intent-filter>
</activity>

Działanie musi mieć tryb uruchamiania, który nie zapobiega i dostosowują się do różnych rozmiarów ekranu. Tryb uruchamiania nie może to być singleInstance ani singleTask.

Implementacja

Na Androidzie 10 RootActivityContainer#startHomeOnDisplay() automatycznie wybiera odpowiedni komponent i intencję w zależności od wyświetlania gdzie uruchamia się ekran główny. RootActivityContainer#resolveSecondaryHomeActivity() zawiera logikę wyszukiwania komponentu aktywności programu uruchamiającego w zależności od wybranego programu uruchamiającego i w razie potrzeby można użyć domyślnego ustawienia systemu (patrz ActivityTaskManagerService#getSecondaryHomeIntent()).

Ograniczenia w zakresie bezpieczeństwa

Oprócz ograniczeń dotyczących aktywności na ekranach dodatkowych, aby uniknąć możliwości utworzenia przez szkodliwą aplikację wyświetlacza wirtualnego – Dekoracje systemowe i odczytują poufne informacje, program uruchamiający na wyświetlaczach wirtualnych należących do systemu. Menu z aplikacjami nie wyświetla treści niesystemowych wyświetlaczy wirtualnych.

Tapety

W Androidzie 10 (i nowszych) tapety są obsługiwane na wyświetlaczach dodatkowych:

Rysunek 2. Animowana tapeta na wewnętrznym i zewnętrznym ekranie wyświetla (poniżej)

Deweloperzy mogą zadeklarować obsługę funkcji tapety, przesyłając android:supportsMultipleDisplays="true" w: WallpaperInfo – definicja XML. Deweloperzy tapet też ma wczytywać zasoby przy użyciu kontekstu wyświetlania w WallpaperService.Engine#getDisplayContext()

Platforma tworzy 1 instancję WallpaperService.Engine na wyświetlacz, więc każdy z nich ma własną powierzchnię i kontekst wyświetlania. aby każdy z silników rysował niezależnie, z różną liczbą klatek na sekundę z uwzględnieniem VSYNC.

Wybieranie tapet na poszczególne ekrany

Android 10 nie zapewnia bezpośredniej obsługi platformy do wybierania tapet dla poszczególnych ekranów. W tym celu stały identyfikator wyświetlacza to aby zachować ustawienia tapety na wyświetlaczu. Parametr Display#getDisplayId() jest dynamiczny, więc nie ma gwarancji, że Po ponownym uruchomieniu ekran fizyczny będzie miał ten sam identyfikator.

Jednak w Androidzie 10 dodano DisplayInfo.mAddress, który zawiera stabilne identyfikatory ekranów fizycznych i może być używany do na przyszłość. Na wdrożenie tej logiki jest już niestety za późno. na Androida 10. Sugerowane rozwiązanie:

  1. Aby ustawić tapety, użyj interfejsu API WallpaperManager.
  2. Wartość WallpaperManager jest pobierana z Context a każdy obiekt Context zawiera informacje o odpowiadających wyświetlacz (Context#getDisplay()/getDisplayId()). Dzięki temu możesz uzyskaj displayId z instancji WallpaperManager bez dodawania nowych metod.
  3. Jeśli chodzi o platformę, użyj parametru displayId uzyskanego ze Context i zmapuj go na identyfikator statyczny (taki jak port fizyczny wyświetlacz). Użyj identyfikatora statycznego, aby zachować wybraną tapetę.

To rozwiązanie korzysta z dotychczasowych implementacji selektorów tapet. Jeśli zostało otwarte na określonym wyświetlaczu i używa odpowiedniego kontekstu, aby ustawić tapetę, system może automatycznie zidentyfikować wyświetlacz.

Jeśli musisz ustawić tapetę na innym ekranie niż bieżący display, a potem utwórz nowy obiekt Context dla docelowego (Context#createDisplayContext) i uzyskaj WallpaperManager instancję z tego wyświetlacza.

Ograniczenia w zakresie bezpieczeństwa

System nie wyświetla tapet na wyświetlaczach wirtualnych, które nie należą do niego. Wynika to z obaw związanych z bezpieczeństwem, że szkodliwa aplikacja może utworzyć wyświetlacz z włączoną obsługą dekoracji systemowych i odczytuje informacji z powierzchni (takich jak prywatne zdjęcia).

Implementacja

W Androidzie 10 IWallpaperConnection#attachEngine() i IWallpaperService#attach() akceptują displayId do tworzenia połączeń z poszczególnymi wyświetlaczami. WallpaperManagerService.DisplayConnector uwzględnia wartości dla poszczególnych wyświetlaczy mechanizm tapety i połączenie. W usłudze WindowManager kontrolery tapet są utworzona dla każdego obiektu DisplayContent w momencie budowy, a nie jeden WallpaperController dla wszystkich wyświetlaczy.

Niektóre publiczne implementacje metod WallpaperManager (takie jak WallpaperManager#getDesiredMinimumWidth()) zaktualizowano do mocy obliczeniowej i dostarczają informacje o odpowiednich wyświetlaczach. WallpaperInfo#supportsMultipleDisplays() i odpowiadające im atrybut zasobu, dzięki czemu deweloperzy aplikacji mogą Tapety są gotowe na wiele ekranów.

Jeśli usługa tapet widoczna na wyświetlaczu domyślnym nie obsługuje na kilku wyświetlaczach, system wyświetla domyślną tapetę na i wyświetlacze.

Rysunek 3. Działanie funkcji zastępczej tapety na potrzeby ekranów dodatkowych