Interfejsy API Androida 4.1

Poziom API: 16

Android 4.1 (JELLY_BEAN) to kolejne rozwiązanie na platformie, która oferuje lepszą wydajność i większą wygodę użytkowników. Dodaje nowe funkcje dla użytkowników i deweloperów aplikacji. Ten dokument zawiera wprowadzenie do najbardziej godnych uwagi i przydatnych nowych interfejsów API dla deweloperów aplikacji.

Android 4.1 jest dostępny dla deweloperów aplikacji w Menedżerze pakietów SDK jako obraz systemu, który możesz uruchomić w emulatorze Androida oraz na platformie SDK, na której możesz stworzyć aplikację. Jak najszybciej pobierz obraz i platformę systemu, aby skompilować i przetestować swoją aplikację na Androidzie 4.1.

Aby lepiej zoptymalizować aplikację pod kątem urządzeń z Androidem 4.1, ustaw targetSdkVersion na "16", zainstaluj ją na obrazie systemu Androida 4.1, przetestuj ją, a następnie opublikuj aktualizację z tą zmianą.

Możesz używać interfejsów API w Androidzie 4.1, a jednocześnie obsługiwać starsze wersje. Aby to zrobić, dodaj do kodu warunki, które przed wykonaniem interfejsów API nieobsługiwanych przez minSdkVersion sprawdzają poziom interfejsu API systemu. Aby dowiedzieć się więcej o zachowywaniu zgodności wstecznej, przeczytaj artykuł Tworzenie interfejsów zgodnych z wsteczną wersją.

Więcej informacji o tym, jak działają poziomy interfejsu API, znajdziesz w artykule Co to jest poziom interfejsu API?.

Komponenty aplikacji

Usługi izolowane

Jeśli określisz wartość android:isolatedProcess="true" w tagu <service>, usługa Service będzie działać w osobnym procesie identyfikatora użytkownika, który nie ma własnych uprawnień.

Zarządzanie pamięcią

Nowe stałe ComponentCallbacks2, takie jak TRIM_MEMORY_RUNNING_LOW i TRIM_MEMORY_RUNNING_CRITICAL, dostarczają procesom na pierwszym planie więcej informacji o stanie pamięci, zanim system wywoła metodę onLowMemory().

Nowa metoda getMyMemoryState(ActivityManager.RunningAppProcessInfo) umożliwia pobieranie ogólnego stanu pamięci.

Dostawcy treści

Nowa metoda (acquireUnstableContentProviderClient()) umożliwia dostęp do metody ContentProviderClient, która może być „niestabilna”, dzięki czemu aplikacja nie ulegnie awarii, jeśli tak zrobi to dostawca treści. Jest to przydatne podczas interakcji z dostawcami treści w osobnej aplikacji.

Animowane tapety

Nowy protokół intencji, który umożliwia bezpośrednie uruchamianie podglądu animowanej tapety, dzięki czemu użytkownicy mogą łatwo wybrać animowaną tapetę bez konieczności opuszczania aplikacji i poruszania się za pomocą selektora tapet Dom.

Aby uruchomić selektor animowanych tapet, wywołaj startActivity() za pomocą polecenia Intent, używając elementu ACTION_CHANGE_LIVE_WALLPAPER oraz dodatku, który określa animowaną tapetę ComponentName jako ciąg znaków w komponencie EXTRA_LIVE_WALLPAPER_COMPONENT.

Nawigacja po stosie aplikacji

Android 4.1 znacznie ułatwia wdrożenie odpowiednich wzorców projektowych dotyczących nawigacji w górę. Wystarczy, że dodasz android:parentActivityName do każdego elementu <activity> w pliku manifestu. System używa tych informacji, aby otwierać odpowiednie działanie, gdy użytkownik naciśnie przycisk W górę na pasku działań (jednocześnie zakończy działanie bieżące). Jeśli więc zadeklarujesz obiekt android:parentActivityName dla każdej aktywności, nie potrzebujesz metody onOptionsItemSelected() do obsługi zdarzeń kliknięć na ikonie aplikacji na pasku działań. System obsługuje teraz to zdarzenie i wznawia lub tworzy odpowiednie działanie.

Jest to szczególnie przydatne w sytuacjach, gdy użytkownik wchodzi w jedną z działań w aplikacji przez szczegółową intencję, np. z powiadomienia lub intencji z innej aplikacji (jak opisano w przewodniku projektowania dotyczącym nawigowania między aplikacjami). Jeśli użytkownik wykona działanie w ten sposób, aplikacja może nie mieć wstecznego stosu aktywności, który można wznowić w miarę przechodzenia na wyższy poziom. Jeśli jednak podasz atrybut android:parentActivityName aktywności, system rozpozna, czy aplikacja zawiera już wsteczny stos działań nadrzędnych. Jeśli nie, utworzy syntetyczny stos wsteczny zawierający wszystkie aktywności nadrzędne.

Uwaga: gdy użytkownik wykona w Twojej aplikacji głęboką aktywność i utworzy w niej nowe zadanie, system wstawi do niego stos działań nadrzędnych. Dlatego naciśnięcie przycisku Wstecz powoduje też powrót po stosie działań nadrzędnych.

Gdy system tworzy syntetyczny stos wsteczny dla aplikacji, kompiluje podstawowy element Intent, aby utworzyć nowe wystąpienie każdej aktywności nadrzędnej. Nie ma więc zapisanego stanu działań nadrzędnych w taki sposób, w jaki użytkownik poruszał się po nich w sposób naturalny. Jeśli dowolna z działań nadrzędnych zwykle wyświetla interfejs zależny od kontekstu użytkownika, brakuje tych informacji kontekstowych i należy je dostarczyć, gdy użytkownik cofnie się przez stos. Jeśli np. użytkownik ogląda album w aplikacji muzycznej, przejście do góry może spowodować wyświetlenie działania, w którym wymienione są wszystkie albumy z wybranego gatunku. W takim przypadku, jeśli należy utworzyć stos, musisz poinformować aktywność nadrzędną o gatunku, do którego należy bieżący album. Dzięki temu element nadrzędny będzie mógł wyświetlić odpowiednią listę, tak jakby użytkownik rzeczywiście pochodził z tej aktywności. Aby dostarczać takie informacje syntetycznej aktywności nadrzędnej, musisz zastąpić metodę onPrepareNavigateUpTaskStack(). Otrzymasz obiekt TaskStackBuilder utworzony przez system w celu syntezy działań nadrzędnych. TaskStackBuilder zawiera obiekty Intent, których system używa do tworzenia poszczególnych aktywności nadrzędnych. W swojej implementacji onPrepareNavigateUpTaskStack() możesz zmodyfikować odpowiedni element Intent, aby dodać dane, których aktywność nadrzędna może używać do określenia odpowiedniego kontekstu i wyświetlania odpowiedniego interfejsu.

Gdy system tworzy TaskStackBuilder, dodaje obiekty Intent, które są używane do tworzenia działań nadrzędnych, w logicznej kolejności, zaczynając od góry drzewa aktywności. Dlatego ostatni element Intent dodany do tablicy wewnętrznej jest bezpośrednim elementem nadrzędnym wobec bieżącej aktywności. Jeśli chcesz zmienić Intent w elemencie nadrzędnym aktywności, najpierw określ długość tablicy za pomocą funkcji getIntentCount() i przekaż tę wartość do editIntentAt().

Jeśli struktura aplikacji jest bardziej złożona, dostępnych jest kilka innych interfejsów API, które pozwalają na obsługę zachowania nawigacji w górę i pełne dostosowanie syntetycznego stosu wstecznego. Do interfejsów API, które dają Ci dodatkową kontrolę, należą:

onNavigateUp()
Zastąp to ustawienie, aby wykonać działanie niestandardowe, gdy użytkownik naciśnie przycisk w górę.
navigateUpTo(Intent)
Wywołaj to działanie, aby zakończyć bieżące działanie i przejść do aktywności wskazanej przez Intent. Jeśli działanie znajduje się w stosie wstecznym, ale nie jest najbliższym elementem nadrzędnym, wtedy wszystkie pozostałe działania między bieżącą aktywnością a aktywnością określoną w intencji również zostaną zakończone.
getParentActivityIntent()
Wywołaj ten element, aby uzyskać element Intent, który będzie uruchamiać logiczny element nadrzędny dla bieżącej aktywności.
shouldUpRecreateTask(Intent)
Wywołuj je, aby sprawdzić, czy należy utworzyć syntetyczny stos wsteczny, aby przejść w górę. Zwraca wartość „true”, jeśli trzeba utworzyć stos syntetyczny, lub „false”, jeśli istnieje już odpowiedni stos.
finishAffinity()
Wywołaj tę czynność, aby zakończyć bieżącą aktywność i wszystkie aktywności nadrzędne z tą samą koligacją zadań, które są powiązane z bieżącą aktywnością. Jeśli zastąpisz działania domyślne, takie jak onNavigateUp(), wywołaj tę metodę podczas tworzenia syntetycznego stosu wstecznego podczas nawigacji w górę.
onCreateNavigateUpTaskStack
Zastąp to ustawienie, jeśli chcesz w pełni kontrolować sposób tworzenia stosu zadań syntetycznych. Jeśli chcesz po prostu dodać więcej danych do intencji dla stosu wstecznego, zastąp onPrepareNavigateUpTaskStack()

Większość aplikacji nie musi jednak korzystać z tych interfejsów API ani implementować onPrepareNavigateUpTaskStack(). Aby jednak uzyskać właściwe działanie, wystarczy dodać android:parentActivityName do każdego elementu <activity>.

Multimedia

Kodeki multimediów

Klasa MediaCodec zapewnia dostęp do kodeków multimedialnych niskiego poziomu do kodowania i dekodowania multimediów. Możesz utworzyć instancję MediaCodec, wywołując metodę createEncoderByType() w celu zakodowania multimediów lub wywoływając metodę createDecoderByType(), aby dekodować multimedia. Każda z tych metod przyjmuje typ MIME odpowiadający rodzajowi multimediów, które chcesz kodować lub dekodować, na przykład "video/3gpp" lub "audio/vorbis".

Po utworzeniu instancji MediaCodec możesz wywołać metodę configure(), aby określić właściwości, takie jak format multimediów lub to, czy treść ma być szyfrowana.

Bez względu na to, czy kodujesz czy dekodujesz multimedia, reszta procesu jest taka sama po utworzeniu obiektu MediaCodec. Najpierw wywołaj getInputBuffers(), aby uzyskać tablicę wejściowych obiektów ByteBuffer, i getOutputBuffers(), aby uzyskać tablicę wyjściowych obiektów ByteBuffer.

Gdy przygotujesz się do kodowania lub dekodowania, wywołaj funkcję dequeueInputBuffer(), aby uzyskać pozycję indeksu ByteBuffer (z tablicy buforów wejściowych), której należy użyć do przesyłania multimediów źródłowych. Gdy wypełnisz obiekt ByteBuffer zasobami multimedialnymi, zwolnij prawa własności do bufora, wywołując metodę queueInputBuffer().

Podobnie w przypadku bufora wyjściowego wywołaj dequeueOutputBuffer(), aby uzyskać pozycję indeksu elementu ByteBuffer, w którym otrzymasz wyniki. Po przeczytaniu danych wyjściowych z ByteBuffer zwolnij prawo własności, wywołując releaseOutputBuffer().

Zaszyfrowane dane multimedialne możesz obsługiwać w kodekach, wywołując queueSecureInputBuffer() w połączeniu z interfejsami API MediaCrypto zamiast zwykłego queueInputBuffer().

Więcej informacji o korzystaniu z kodeków znajdziesz w dokumentacji MediaCodec.

Nagrywaj dźwięk po wskazaniu

Nowa metoda startRecording() umożliwia rozpoczynanie nagrywania dźwięku na podstawie sygnału zdefiniowanego przez MediaSyncEvent. MediaSyncEvent określa sesję audio (taką jak zdefiniowaną przez zasadę MediaPlayer), która po jej zakończeniu uruchamia rejestrator dźwięku i rozpoczyna nagrywanie. Dzięki tej funkcji możesz na przykład odtworzyć dźwięk wskazujący początek sesji nagrywania, a nagrywanie rozpocznie się automatycznie, więc nie musisz ręcznie synchronizować dźwięku z początkiem nagrywania.

Chronologicznie ścieżki tekstowe

MediaPlayer obsługuje teraz zarówno ścieżki tekstowe w pamie, jak i poza nim. Ścieżki tekstowe w paśmie to ścieżki tekstowe w źródle multimediów MP4 lub 3GPP. Ścieżki tekstowe spoza zakresu można dodać jako zewnętrzne źródło tekstu za pomocą metody addTimedTextSource(). Po dodaniu wszystkich zewnętrznych źródeł ścieżek tekstowych należy wywołać funkcję getTrackInfo(), aby pobrać odświeżoną listę wszystkich dostępnych ścieżek w źródle danych.

Aby ustawić ścieżkę do użycia z MediaPlayer, musisz wywołać selectTrack(), podając pozycję indeksu ścieżki, której chcesz użyć.

Aby otrzymać powiadomienie, gdy ścieżka tekstowa będzie gotowa do odtwarzania, wdróż interfejs MediaPlayer.OnTimedTextListener i przekaż ją do setOnTimedTextListener().

Efekty dźwiękowe

Klasa AudioEffect obsługuje teraz dodatkowe typy wstępnego przetwarzania dźwięku podczas nagrywania dźwięku:

  • Reduktor echa akustycznego (AEC) z AcousticEchoCanceler usuwa sygnał odbierany od urządzenia zdalnego z przechwyconego sygnału audio.
  • Automatyczna kontrola wzmocnienia (AGC) z AutomaticGainControl automatycznie normalizuje wyjście rejestrowanego sygnału.
  • Reduktor szumu (NS) z funkcją NoiseSuppressor usuwa szum w tle z przechwyconego sygnału.

Możesz zastosować te efekty z procesora wstępnego do dźwięku zarejestrowanego za pomocą AudioRecord przy użyciu jednej z podklas AudioEffect.

Uwaga: nie gwarantujemy, że wszystkie urządzenia będą obsługiwać te efekty, dlatego zawsze sprawdzaj dostępność, wywołując isAvailable() dla odpowiedniej klasy efektów audio.

Odtwarzanie bez przerw

Teraz możesz odtwarzać bez przerw między 2 oddzielnymi obiektami MediaPlayer. W dowolnym momencie przed zakończeniem pierwszego MediaPlayer wywołanie setNextMediaPlayer(), a Android próbuje uruchomić drugiego gracza w momencie, gdy pierwszy się zatrzyma.

Router multimediów. Nowe interfejsy API MediaRouter, MediaRouteActionProvider i MediaRouteButton zapewniają standardowe mechanizmy i interfejsy użytkownika do wybierania miejsc odtwarzania multimediów.

Aparat

Ruch automatycznego ustawiania ostrości

Nowy interfejs Camera.AutoFocusMoveCallback umożliwia wychwytywanie zmian w ruchu automatycznego ustawiania ostrości. Możesz zarejestrować swój interfejs w setAutoFocusMoveCallback(). Następnie, gdy aparat będzie w trybie ciągłego autofokusu (FOCUS_MODE_CONTINUOUS_VIDEO lub FOCUS_MODE_CONTINUOUS_PICTURE), otrzymasz wywołanie do onAutoFocusMoving(), które informuje, czy autofokus zaczął się poruszać czy przestał się poruszać.

Dźwięki aparatu

Klasa MediaActionSound udostępnia prosty zestaw interfejsów API do generowania standardowych dźwięków wywoływanych przez kamerę lub inne działania związane z multimediami. Należy używać tych interfejsów API do odtwarzania odpowiedniego dźwięku podczas tworzenia niestandardowych kadrów lub kamer.

Aby odtworzyć dźwięk, po prostu utwórz instancję obiektu MediaActionSound, wywołaj load(), aby wstępnie wczytać odpowiedni dźwięk, a potem w odpowiednim momencie wywołaj play().

Połączenia

Android Beam

Android BeamTM obsługuje teraz przesyłanie dużych ładunków przez Bluetooth. Gdy określisz dane do przesłania za pomocą nowej metody setBeamPushUris() lub nowego interfejsu wywołania zwrotnego NfcAdapter.CreateBeamUrisCallback, Android przekazuje dane do Bluetootha lub innej metody, aby przyspieszyć przesyłanie. Jest to szczególnie przydatne w przypadku dużych ładunków, takich jak pliki graficzne i audio, oraz nie wymaga widocznego parowania urządzeń. Aplikacja nie musi wykonywać żadnych dodatkowych czynności, aby korzystać z przesyłania danych przez Bluetooth.

Metoda setBeamPushUris() przyjmuje tablicę obiektów Uri określających dane, które chcesz przenieść z aplikacji. Możesz też wdrożyć interfejs NfcAdapter.CreateBeamUrisCallback, który możesz określić na potrzeby swojej aktywności, wywołując setBeamPushUrisCallback().

Gdy używany jest interfejs wywołania zwrotnego, system wywołuje metodę createBeamUris() interfejsu, gdy użytkownik wykonuje udostępnienie za pomocą Android Beam, aby można było zdefiniować identyfikatory URI do udostępnienia w czasie udostępniania. Jest to przydatne, gdy identyfikatory URI do udostępnienia mogą się różnić w zależności od kontekstu użytkownika w ramach działania, natomiast wywołanie setBeamPushUris() jest przydatne, gdy udostępniane identyfikatory URI są zawsze aktualne i można je bezpiecznie zdefiniować z wyprzedzeniem.

Wykrywanie usług sieciowych

Android 4.1 dodaje obsługę funkcji wykrywania usług w trybie multicast DNS, która umożliwia znajdowanie usług oferowanych przez urządzenia równorzędne przez Wi-Fi (np. urządzenia mobilne, drukarki, kamery, odtwarzacze multimedialne i inne) zarejestrowane w sieci lokalnej i łączenie się z nimi.

Nowy pakiet android.net.nsd zawiera nowe interfejsy API, które umożliwiają rozgłaszanie usług w sieci lokalnej, wykrywanie lokalnych urządzeń w sieci i łączenie się z urządzeniami.

Aby zarejestrować usługę, musisz najpierw utworzyć obiekt NsdServiceInfo i zdefiniować różne właściwości usługi za pomocą metod takich jak setServiceName(), setServiceType() i setPort().

Następnie musisz wdrożyć NsdManager.RegistrationListener i przekazać go do registerService() za pomocą NsdServiceInfo.

Aby wykryć usługi w sieci, zaimplementuj NsdManager.DiscoveryListener i przekaż go do discoverServices().

Gdy NsdManager.DiscoveryListener otrzymuje wywołania zwrotne dotyczące znalezionych usług, musisz rozwiązać problem z usługą, wywołując resolveService(), przesyłając implementację NsdManager.ResolveListener, która odbiera obiekt NsdServiceInfo z informacjami o wykrytej usłudze, co umożliwia zainicjowanie połączenia.

Wykrywanie usługi P2P sieci Wi-Fi

Interfejsy Wi-Fi P2P API w Androidzie 4.1 zostały ulepszone, aby umożliwić wykrywanie usług przed powiązaniem w WifiP2pManager. Dzięki temu przed nawiązaniem połączenia będzie można wykrywać i filtrować urządzenia w pobliżu według usług korzystających z sieci Wi-Fi P2P, a wykrywanie usług sieciowych umożliwia wykrywanie usług w już połączonej sieci (np. lokalnej sieci Wi-Fi).

Aby przesłać aplikację jako usługę przez Wi-Fi, a inne urządzenia mogą wykryć Twoją aplikację i się z nią połączyć, wywołaj addLocalService() za pomocą obiektu WifiP2pServiceInfo opisującego usługi aplikacji.

Aby zainicjować wykrywanie urządzeń w pobliżu przez Wi-Fi, musisz najpierw zdecydować, czy będziesz korzystać z funkcji Bonjour czy Upnp. Aby korzystać z usługi Bonjour, skonfiguruj najpierw kilka detektorów wywołań zwrotnych z usługą setDnsSdResponseListeners(), która wymaga zarówno WifiP2pManager.DnsSdServiceResponseListener, jak i WifiP2pManager.DnsSdTxtRecordListener. Aby użyć funkcji Upnp, wywołaj setUpnpServiceResponseListener(). Wymaga to użycia WifiP2pManager.UpnpServiceResponseListener.

Zanim zaczniesz odkrywać usługi na urządzeniach lokalnych, musisz też zadzwonić pod numer addServiceRequest(). Gdy obiekt WifiP2pManager.ActionListener przekazywany do tej metody otrzyma wywołanie zwrotne, możesz zacząć wykrywać usługi na urządzeniach lokalnych, wywołując metodę discoverServices().

Po wykryciu usług lokalnych otrzymasz połączenie zwrotne na numer WifiP2pManager.DnsSdServiceResponseListener lub WifiP2pManager.UpnpServiceResponseListener, w zależności od tego, czy jesteś zarejestrowanym użytkownikiem Bonjour czy Upnp. Wywołanie zwrotne odebrane w obu przypadkach zawiera obiekt WifiP2pDevice reprezentujący urządzenie równorzędne.

Wykorzystanie sieci

Nowa metoda isActiveNetworkMetered() umożliwia sprawdzenie, czy urządzenie jest obecnie połączone z siecią z pomiarem użycia danych. Sprawdzając ten stan przed wykonywaniem intensywnych transakcji sieciowych, możesz ułatwić użytkownikom zarządzanie wykorzystaniem danych, które może wiązać się z kosztami, oraz podjąć świadomą decyzję o tym, czy transakcja zostanie zrealizowana teraz czy później (na przykład po połączeniu urządzenia z Wi-Fi).

Ułatwienia dostępu

Interfejsy API usług ułatwień dostępu

Zasięg interfejsów API usług ułatwień dostępu na Androidzie 4.1 został znacznie większy. Umożliwia teraz tworzenie usług, które monitorują większą liczbę zdarzeń wejściowych, takich jak złożone gesty, i reagują na nie, za pomocą onGesture() i innych zdarzeń wejściowych. Służą do tego dodatkowe klasy AccessibilityEvent, AccessibilityNodeInfo i AccessibilityRecord.

Usługi ułatwień dostępu mogą też wykonywać w imieniu użytkownika różne czynności, m.in. klikać, przewijać i przeglądać tekst za pomocą funkcji performAction i setMovementGranularities. Metoda performGlobalAction() umożliwia też usługom wykonywanie takich działań jak Wstecz, Ekran główny czy otwieranie ostatnich aplikacji i powiadomień.

Spersonalizowana nawigacja po aplikacji

Tworząc aplikację na Androida, możesz teraz dostosowywać schematy nawigacji, znajdując elementy, które można zaznaczyć, i widżety wprowadzania za pomocą findFocus() i focusSearch(), oraz ustawiać fokus za pomocą setAccessibilityFocused().

Łatwiejsze korzystanie z widżetów

Nowa klasa android.view.accessibility.AccessibilityNodeProvider umożliwia tworzenie złożonych niestandardowych widoków w usługach ułatwień dostępu, dzięki czemu mogą one prezentować informacje w bardziej przystępny sposób. android.view.accessibility.AccessibilityNodeProvider umożliwia widżetowi użytkownika z zaawansowaną zawartością, taką jak siatka kalendarza, aby prezentować logiczną semantyczną strukturę usług ułatwień dostępu, która jest całkowicie oddzielona od struktury układu widżetu. Ta semantyczna struktura umożliwia usługom ułatwień dostępu bardziej przydatny model interakcji dla użytkowników z wadami wzroku.

Kopiuj i wklej

Kopiowanie i wklejanie z intencjami

Możesz teraz powiązać obiekt ClipData z Intent metodą setClipData(). Jest to szczególnie przydatne w przypadku przesyłania wielu identyfikatorów URI content: do innej aplikacji, np. przy udostępnianiu wielu dokumentów. Identyfikatory URI content: dostarczane w ten sposób uwzględniają flagi intencji, oferując dostęp do odczytu lub zapisu, co umożliwia przyznawanie dostępu do wielu identyfikatorów URI w intencji. Po uruchomieniu intencji ACTION_SEND lub ACTION_SEND_MULTIPLE identyfikatory URI podane w intencji są teraz automatycznie przekazywane do intencji ClipData, aby odbiorca mógł uzyskać do nich dostęp.

Obsługa stylów HTML i ciągów znaków

Klasa ClipData obsługuje teraz tekst ze stylem (w postaci ciągów znaków HTML lub Androida). Możesz dodać tekst w stylu HTML do interfejsu ClipData za pomocą narzędzia newHtmlText().

Skrypt renderowania

Ulepszyliśmy funkcję obliczania w narzędziu Renderscript o te funkcje:

  • Obsługa wielu jąder w ramach jednego skryptu.
  • Obsługa odczytu alokacji z odfiltrowanymi próbkami z obliczeń w nowym interfejsie API skryptu rsSample.
  • Obsługa różnych poziomów dokładności FP w: #pragma.
  • Obsługa wysyłania zapytań o dodatkowe informacje z obiektów RS za pomocą skryptu obliczeniowego.
  • Liczne usprawnienia działania aplikacji.

Dostępne są też nowe pragmy do definiowania dokładności liczebności zmiennoprzecinkowej wymaganej przez funkcje Renderscript. Dzięki temu możesz włączyć na ścieżce procesora operacje takie jak szybkie operacje matematyczne na wektorach NEON, które w innym przypadku nie byłyby możliwe w pełnym standardzie IEEE 754-2008.

Uwaga: eksperymentalny mechanizm graficzny Renderscript jest teraz wycofany.

Animacja

Animacje uruchamiające aktywność

Możesz teraz uruchomić Activity, korzystając z animacji powiększenia lub własnych niestandardowych animacji. Aby określić animację, za pomocą interfejsów API ActivityOptions utwórz obiekt Bundle, który możesz potem przekazać do dowolnej metody rozpoczynającej działanie, np. startActivity().

Klasa ActivityOptions zawiera inną metodę dla każdego typu animacji, który może być wyświetlany po otwarciu aktywności:

makeScaleUpAnimation()
Tworzy animację, która skaluje okno aktywności w górę od określonej pozycji początkowej na ekranie i o określonym rozmiarze początkowym. Będzie on używany na przykład podczas otwierania aplikacji na ekranie głównym Androida 4.1.
makeThumbnailScaleUpAnimation()
Tworzy animację, która skaluje okno aktywności w górę, zaczynając od określonej pozycji i od podanego obrazu miniatury. Na przykład okno Ostatnie aplikacje w Androidzie 4.1 używa go po powrocie do aplikacji.
makeCustomAnimation()
Tworzy animację zdefiniowaną przez Twoje zasoby: jedną określającą animację rozpoczynania działania i drugą dla zatrzymywanego działania.

Animator czasu

Nowy TimeAnimator ma prosty mechanizm wywołania zwrotnego z elementem TimeAnimator.TimeListener, który powiadamia Cię o każdej klatce animacji. W tym animatorze nie można ustawić czasu trwania, interpolacji ani wartości obiektu. Wywołanie zwrotne detektora otrzymuje informacje o każdej klatce, w tym łączny czas, który upłynął od poprzedniej klatki animacji.

Interfejs

Powiadomienia

W Androidzie 4.1 możesz tworzyć powiadomienia z większymi obszarami treści, podglądami dużych obrazów, wieloma przyciskami poleceń i konfigurowalnymi priorytetami.

Style powiadomień

Nowa metoda setStyle() umożliwia określenie jednego z 3 nowych stylów powiadomienia, z których każdy obejmuje większy obszar treści. Aby określić styl dla dużego regionu treści, przekaż setStyle() jeden z tych obiektów:

Notification.BigPictureStyle
Dotyczy powiadomień zawierających duży załącznik graficzny.
Notification.BigTextStyle
Dotyczy powiadomień, które zawierają dużo tekstu, np. jednego e-maila.
Notification.InboxStyle
Dotyczy powiadomień zawierających listę ciągów tekstowych, np. fragmentów wielu e-maili.
Działania powiadomień

Obecnie u dołu wiadomości z powiadomieniem można dodać maksymalnie 2 przyciski działań, niezależnie od tego, czy powiadomienie jest użyte w stylu normalnym, czy w większym.

Aby dodać przycisk polecenia, zadzwoń pod numer addAction(). Ta metoda przyjmuje 3 argumenty: rysowalny zasób ikony, tekst przycisku i obiekt PendingIntent określający działanie, które ma zostać wykonane.

Priorytety

Teraz możesz wskazać systemowi, jak ważne jest powiadomienie, aby wpłynąć na ich kolejność na liście. Aby to zrobić, ustaw priorytet na setPriority(). Możesz zaliczyć ten z 5 różnych poziomów priorytetu zdefiniowanych przez stałe PRIORITY_* w klasie Notification. Wartość domyślna to PRIORITY_DEFAULT. Są tu dwa poziomy wyższe i dwa poziomy niżej.

Powiadomienia o wysokim priorytecie to rzeczy, na które użytkownicy zwykle chcą szybko reagować. Mogą to być na przykład nowe wiadomości czatu, SMS-y lub przypomnienia o zbliżającym się wydarzeniu. Powiadomienia o niskim priorytecie to np. wygasłe wydarzenia w kalendarzu lub promocje aplikacji.

Elementy sterujące interfejsu systemu

Do Androida 4.0 (Ice Cream Sandwich) dodano nowe flagi kontrolujące widoczność elementów interfejsu systemu, np. aby przyciemnić wygląd paska systemowego lub całkowicie go zniknąć z telefonów. W Androidzie 4.1 pojawiły się kolejne flagi, które umożliwiają większą kontrolę nad wyglądem elementów interfejsu systemu i układu aktywności w odniesieniu do nich. Służą one do wywoływania funkcji setSystemUiVisibility() i przekazywania tych flag:

SYSTEM_UI_FLAG_FULLSCREEN
Ukrywa niekrytyczny interfejs systemu (np. pasek stanu). Jeśli aktywność korzysta z paska działań w trybie nakładki (po włączeniu android:windowActionBarOverlay), ta flaga także ukrywa pasek działań, wykorzystując skoordynowaną animację podczas zarówno ukrywania, jak i wyświetlania obu tych elementów.
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
Ustawia układ aktywności tak, aby używał tego samego obszaru ekranu, który jest dostępny po włączeniu SYSTEM_UI_FLAG_FULLSCREEN, nawet jeśli elementy interfejsu systemu są nadal widoczne. Chociaż części układu zostaną nałożone przez interfejs systemu, jest to przydatne, jeśli aplikacja często ukrywa lub wyświetla interfejs systemu za pomocą właściwości SYSTEM_UI_FLAG_FULLSCREEN, ponieważ zapobiega to dostosowaniu układu do nowych granic układu za każdym razem, gdy interfejs użytkownika się ukryje lub pojawi.
SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
Ustawia układ aktywności tak, aby używał tego samego obszaru ekranu, który jest dostępny po włączeniu SYSTEM_UI_FLAG_HIDE_NAVIGATION (dodanej w Androidzie 4.0), nawet jeśli elementy interfejsu systemu są nadal widoczne. Chociaż części układu są nałożone na pasek nawigacyjny, jest to przydatne, jeśli Twoja aplikacja często ukrywa się i wyświetla pasek nawigacyjny z elementem SYSTEM_UI_FLAG_HIDE_NAVIGATION. Unika on możliwości dostosowania układu do nowych granic układu za każdym razem, gdy pasek nawigacyjny się ukryje lub pojawi.
SYSTEM_UI_FLAG_LAYOUT_STABLE
Możesz dodać tę flagę, jeśli używasz SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN lub SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION, aby mieć pewność, że gdy wywołasz fitSystemWindows() w widoku, zdefiniowane granice pozostaną zgodne w odniesieniu do dostępnego miejsca na ekranie. Oznacza to, że po ustawieniu tej flagi fitSystemWindows() będzie zachowywać się tak, jakby widoczność elementów interfejsu systemu nie zmieniła się nawet wtedy, gdy ukryjesz wszystkie elementy interfejsu systemu.

Aby dowiedzieć się więcej o innych powiązanych flagach interfejsu systemu, poczytaj o tych dodanych w Androidzie 4.0.

Widoki zdalne

GridLayout i ViewStub to teraz widoki, których możesz używać w układach widżetów aplikacji oraz w układach niestandardowych powiadomień.

Rodziny czcionek

W Androidzie 4.1 pojawiło się kilka dodatkowych wersji stylu czcionki Roboto, co daje łącznie 10 odmian, z których mogą korzystać aplikacje. Twoje aplikacje mają teraz dostęp do pełnego zestawu wersji lekkich i skondensowanych.

Pełny zestaw dostępnych wersji czcionki Roboto:

  • Regularnie publikowane
  • Kursywa
  • Pogrubienie
  • Pogrubienie – kursywa
  • Jasny
  • Lekka kursywa
  • Zwykłe skondensowane
  • Skrócona kursywa
  • Skrócony, pogrubiony
  • Skrócona, pogrubiona kursywa

Możesz zastosować dowolny z nich z nowym atrybutem fontFamily w połączeniu z atrybutem textStyle.

Obsługiwane wartości pola fontFamily:

  • "sans-serif" dla zwykłej gry Roboto
  • "sans-serif-light" dla Roboto Light
  • "sans-serif-condensed" dla Roboto Condensed

Następnie możesz zastosować pogrubienie lub kursywę przy użyciu wartości textStyle "bold" i "italic". Możesz zastosować oba te elementy: android:textStyle="bold|italic".

Możesz też użyć aplikacji Typeface.create(). Przykład: Typeface.create("sans-serif-light", Typeface.NORMAL).

Struktura wprowadzania

Wiele urządzeń wejściowych

Nowa klasa InputManager umożliwia wysyłanie zapytań do zestawu urządzeń wejściowych, które są obecnie podłączone, i rejestrowanie jej w celu otrzymywania powiadomień o dodaniu, zmianie lub usunięciu nowego urządzenia. Jest to szczególnie przydatne, gdy tworzysz grę, w której może grać wielu graczy i chcesz się dowiedzieć, ile kontrolerów jest podłączonych i kiedy zmienia się liczba kontrolerów.

Możesz wysyłać zapytania dotyczące wszystkich podłączonych urządzeń wejściowych, wywołując stronę getInputDeviceIds(). Zwraca tablicę liczb całkowitych, z których każda jest identyfikatorem innego urządzenia wejściowego. Następnie możesz wywołać getInputDevice(), aby uzyskać InputDevice dla określonego identyfikatora urządzenia wejściowego.

Jeśli chcesz otrzymywać informacje, gdy nowe urządzenia wejściowe są podłączone, zmienione lub rozłączone, zaimplementuj interfejs InputManager.InputDeviceListener i zarejestruj go w usłudze registerInputDeviceListener().

Wibracje przy kontrolerach wejścia

Jeśli podłączone urządzenia wejściowe mają własne funkcje wibracji, możesz je teraz kontrolować za pomocą dotychczasowych interfejsów API Vibrator, wywołując getVibrator() w interfejsie InputDevice.

Uprawnienia

Oto nowe uprawnienia:

READ_EXTERNAL_STORAGE
Zapewnia chroniony dostęp z uprawnieniami do odczytu w pamięci zewnętrznej. W Androidzie 4.1 domyślnie wszystkie aplikacje nadal mają dostęp do odczytu. W przyszłej wersji to ustawienie zostanie zmienione i będzie wymagać, by aplikacje wyraźnie prosiły o dostęp do odczytu, korzystając z tego uprawnienia. Jeśli Twoja aplikacja prosi już o uprawnienia do zapisu, automatycznie uzyska też uprawnienia do odczytu. Jest dostępna nowa opcja dla programistów, która pozwala na włączenie ograniczenia dostępu do odczytu, dzięki czemu deweloperzy mogą testować swoje aplikacje pod kątem tego, jak Android będzie działać w przyszłości.
android.Manifest.permission.READ_USER_DICTIONARY
Umożliwia aplikacji odczytywanie słownika użytkownika. Powinno to być wymagane tylko w IME i edytorze słownika, np. w aplikacji Ustawienia.
READ_CALL_LOG
Umożliwia aplikacji odczyt rejestru połączeń systemu, który zawiera informacje o połączeniach przychodzących i wychodzących.
WRITE_CALL_LOG
Umożliwia aplikacji modyfikowanie rejestru połączeń systemowych zapisanego na telefonie
android.Manifest.permission.WRITE_USER_DICTIONARY
Zezwalaj aplikacji na zapisywanie słów w słowniku słów użytkownika.

Funkcje urządzenia

Android 4.1 zawiera nową deklarację funkcji dla urządzeń przeznaczonych do wyświetlania interfejsu na ekranie telewizora: FEATURE_TELEVISION. Aby zadeklarować, że aplikacja wymaga interfejsu telewizyjnego, zadeklaruj tę funkcję w pliku manifestu za pomocą elementu <uses-feature>:

<manifest ... >
    <uses-feature android:name="android.hardware.type.television"
                  android:required="true" />
    ...
</manifest>

Ta funkcja definiuje telewizor jako typowy telewizor w salonie: obraz jest wyświetlany na dużym ekranie, gdzie użytkownik jest z daleka, a główną formą wprowadzania danych jest pad kierunkowy, a przeważnie nie dotykowo ani za pomocą myszy/wskaźnika.