Poziom interfejsu API: 16
Android 4.1 (JELLY_BEAN
) to rozwinięcie platformy, które zapewnia większą wydajność i wygodę użytkowników. Dodaje nowe funkcje dla użytkowników i programistów. W tym dokumencie przedstawiamy najważniejsze i najprzydatniejsze nowe interfejsy API dla deweloperów aplikacji.
Jako deweloper aplikacji możesz pobrać Androida 4.1 w postaci obrazu systemu w Menedżerze pakietu SDK, aby uruchomić go w emulatorze Androida. Możesz też skompilować aplikację na platformie SDK. Aby skompilować i przetestować aplikację na Androidzie 4.1, jak najszybciej pobierz obraz systemu i platformę.
Aby lepiej zoptymalizować aplikację pod kątem urządzeń z Androidem 4.1, ustaw targetSdkVersion
na "16"
, zainstaluj ją na obrazie systemu Android 4.1, przetestuj aplikację, a potem opublikuj aktualizację z tą zmianą.
Możesz używać interfejsów API w Androidzie 4.1, a zarazem obsługiwać starsze wersje, dodając do kodu warunki, które sprawdzają poziom interfejsu API systemu przed wykonaniem interfejsów API nieobsługiwanych przez minSdkVersion
.
Aby dowiedzieć się więcej o zachowaniu zgodności wstecznej, przeczytaj artykuł Tworzenie interfejsów użytkownika zgodnych wstecznie.
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 w tagu <service>
podasz wartość android:isolatedProcess="true"
, usługa Service
będzie działać w ramach własnego izolowanego procesu identyfikatora użytkownika, który nie ma żadnych 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 przed wywołaniem przez system funkcji onLowMemory()
.
Nowa metoda getMyMemoryState(ActivityManager.RunningAppProcessInfo)
umożliwia odzyskiwanie ogólnego stanu pamięci.
Dostawcy treści
Nowa metoda acquireUnstableContentProviderClient()
umożliwia dostęp do ContentProviderClient
, który może być „niestabilny”, co oznacza, że aplikacja nie ulegnie awarii, jeśli dostawca treści przestanie działać. Jest to przydatne, gdy korzystasz z usług dostawców treści w osobnej aplikacji.
Animowane tapety
Nowy protokół intencji, który umożliwia bezpośrednie uruchamianie podglądu animowanej tapety, dzięki czemu możesz ułatwić użytkownikom wybór animowanej tapety bez konieczności opuszczania aplikacji i poruszania się za pomocą selektora tapety głównej.
Aby uruchomić selektor animowanej tapety, wywołaj funkcję startActivity()
z parametrem Intent
, używając ACTION_CHANGE_LIVE_WALLPAPER
i dodatkowego parametru, który określa animowaną tapetę ComponentName
jako ciąg znaków w EXTRA_LIVE_WALLPAPER_COMPONENT
.
Nawigacja po stosie aplikacji
Android 4.1 ułatwia wdrożenie prawidłowych wzorców projektowania nawigacji w górę.
Wystarczy, że dodasz android:parentActivityName
do każdego elementu <activity>
w pliku manifestu. System używa tych informacji, aby otworzyć odpowiednią aktywność, gdy użytkownik naciśnie przycisk W górę na pasku czynności (jednocześnie kończąc bieżącą aktywność). Jeśli więc zadeklarujesz android:parentActivityName
dla każdej aktywności, nie będziesz już potrzebować metody onOptionsItemSelected()
do obsługi zdarzeń kliknięcia ikony aplikacji na pasku czynności – system będzie teraz obsługiwać to zdarzenie i wznawiać lub tworzyć odpowiednią aktywność.
Jest to szczególnie przydatne w sytuacjach, gdy użytkownik uruchamia jedną z działań aplikacji za pomocą „głębokiego” zamiaru, np. z powiadomienia lub z innej aplikacji (jak opisano w przewodniku po projektowaniu dotyczącym przechodzenia między aplikacjami). Gdy użytkownik w ten sposób wejdzie w Twoją aktywność, aplikacja może nie mieć domyślnie dostępnej grupy aktywności, którą można wznowić po przejściu w górę. Jednak gdy podasz atrybut android:parentActivityName
dla swoich aktywności, system rozpozna, czy aplikacja zawiera już podzbiór aktywności nadrzędnych. Jeśli nie, utworzy syntetyczny podzbiór zawierający wszystkie aktywności nadrzędne.
Uwaga: gdy użytkownik wywoła w aplikacji głęboką aktywność i utworzy nowe zadanie dla aplikacji, system wstawia do tego zadania stos aktywności nadrzędnych. Dlatego naciśnięcie przycisku Wstecz powoduje przejście do poprzedniego zestawu aktywności nadrzędnych.
Gdy system tworzy dla aplikacji syntetyczną warstwę z powrotem, tworzy podstawowy Intent
, aby utworzyć nowy egzemplarz każdej nadrzędnej aktywności. W przypadku aktywności nadrzędnych nie ma zapisanego stanu, jak w przypadku zwykłej nawigacji użytkownika przez poszczególne aktywności. Jeśli którakolwiek z rodzicielskich aktywności wyświetla interfejs zależny od kontekstu użytkownika, te informacje kontekstowe będą brakować. Należy je przekazać, gdy użytkownik przejdzie wstecz przez stos. Jeśli na przykład użytkownik przegląda album w aplikacji muzycznej, przewinięcie w górę może przenieść go do aktywności, która zawiera listę wszystkich albumów w wybranym gatunku muzycznym. W tym przypadku, jeśli musisz utworzyć grupę, musisz poinformować główną aktywność, do jakiego gatunku należy bieżący album, aby mogła wyświetlić odpowiednią listę, tak jakby użytkownik faktycznie pochodził z tej aktywności. Aby przekazać takie informacje syntetycznemu rodzicowi aktywności, musisz zastąpić metodę onPrepareNavigateUpTaskStack()
. Dzięki temu otrzymasz obiekt TaskStackBuilder
utworzony przez system w celu zsyntetyzowania działań rodzica. Element TaskStackBuilder
zawiera obiekty Intent
, których system używa do tworzenia każdej aktywności nadrzędnej. W implementacji onPrepareNavigateUpTaskStack()
możesz zmodyfikować odpowiednie elementy Intent
, aby dodać dodatkowe dane, których aktywność nadrzędna może używać do określania odpowiedniego kontekstu i wyświetlania odpowiedniego interfejsu.
Gdy system tworzy TaskStackBuilder
, dodaje obiekty Intent
, które są używane do tworzenia aktywności nadrzędnych, w ich logicznej kolejności, zaczynając od szczytu drzewa aktywności. Ostatni element Intent
dodany do tablicy wewnętrznej jest bezpośrednim rodzicem bieżącej aktywności. Jeśli chcesz zmodyfikować element Intent
dla rodzica aktywności, najpierw określ długość tablicy za pomocą funkcji getIntentCount()
i przekaż tę wartość do funkcji editIntentAt()
.
Jeśli struktura aplikacji jest bardziej złożona, możesz skorzystać z kilku innych interfejsów API, które umożliwiają zarządzanie zachowaniem nawigacji w górę i pełne dostosowanie syntetycznego stosu wstecz. Interfejsy API, które dają Ci dodatkową kontrolę, to między innymi:
onNavigateUp()
- Zastąp to ustawienie, aby wykonać niestandardową czynność, gdy użytkownik naciśnie przycisk w górę.
navigateUpTo(Intent)
- Wywołaj tę funkcję, aby zakończyć bieżącą aktywność i przejść do aktywności wskazanej przez podany
Intent
. Jeśli aktywność istnieje w grupie aktywności na drugim planie, ale nie jest najbliższym elementem nadrzędnym, wszystkie inne aktywności między bieżącą aktywnością a aktywizacją określoną za pomocą inencji również się kończą. getParentActivityIntent()
- Wywołaj tę funkcję, aby uzyskać
Intent
, która uruchomi nadrzędny obiekt logiczny dla bieżącej aktywności. shouldUpRecreateTask(Intent)
- Wywołaj tę funkcję, aby zapytać, czy trzeba utworzyć syntetyczny stos wsteczny, aby przejść wyżej. Zwraca wartość „prawda”, jeśli należy utworzyć syntetyczny stos, lub wartość „fałsz”, jeśli odpowiedni stos już istnieje.
finishAffinity()
- Wywołaj tę czynność, aby zakończyć bieżącą aktywność i wszystkie działania nadrzędne z tą samą koligacją zadań, które są połączone z bieżącą aktywnością.
Jeśli zastąpisz domyślne zachowania, takie jak
onNavigateUp()
, wywołaj tę metodę podczas tworzenia syntetycznego stosu wstecznego po przejściu w górę. onCreateNavigateUpTaskStack
- Zastąp to ustawienie, jeśli chcesz w pełni kontrolować sposób tworzenia stosu zadań syntetycznych. Jeśli chcesz tylko dodać dodatkowe dane do intencji dla ścieżki wstecznej, zamiast tego zastąpij
onPrepareNavigateUpTaskStack()
Większość aplikacji nie musi jednak korzystać z tych interfejsów API ani implementować interfejsu onPrepareNavigateUpTaskStack()
. Aby uzyskać prawidłowe działanie, wystarczy dodać android:parentActivityName
do każdego elementu <activity>
.
Multimedia
Kodeki multimediów
Klasa MediaCodec
umożliwia dostęp do kodeków multimediów niskopoziomowych do kodowania i dekodowania multimediów. Możesz utworzyć instancję MediaCodec
, wywołując funkcję createEncoderByType()
, aby zakodować multimedia, lub funkcję createDecoderByType()
, aby je zdekodować. Każda z tych metod przyjmuje typ MIME dla typu mediów, które chcesz zakodować lub zdekodować, np. "video/3gpp"
lub "audio/vorbis"
.
Po utworzeniu instancji MediaCodec
możesz wywołać funkcję configure()
, aby określić właściwości takie jak format multimediów lub czy zawartość jest zaszyfrowana.
Po utworzeniu MediaCodec
dalsza część procesu jest taka sama, niezależnie od tego, czy kodujesz, czy dekodujesz multimedia. Najpierw wywołaj funkcję getInputBuffers()
, aby uzyskać tablicę obiektów wejściowych ByteBuffer
, a potem funkcję getOutputBuffers()
, aby uzyskać tablicę wyjściowych obiektów ByteBuffer
.
Gdy będziesz gotowy 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 podania źródła multimediów. Po wypełnieniu zasobu ByteBuffer
za pomocą multimediów źródłowych zwalniasz własność bufora, wywołując funkcję queueInputBuffer()
.
Podobnie w przypadku bufora wyjściowego wywołaj funkcję dequeueOutputBuffer()
, aby uzyskać pozycję indeksu w strukturze danych ByteBuffer
, w której otrzymasz wyniki. Po odczytaniu danych wyjściowych z polecenia ByteBuffer
zwalniasz prawo własności, wywołując polecenie releaseOutputBuffer()
.
Za pomocą interfejsu queueSecureInputBuffer()
możesz obsługiwać zaszyfrowane dane multimedialne w kodekiach, zamiast zwykłego interfejsu queueInputBuffer()
.MediaCrypto
Więcej informacji na temat korzystania z kodeków znajdziesz w dokumentacji MediaCodec
.
Nagrywaj dźwięk we właściwym momencie
Nowa metoda startRecording()
umożliwia rozpoczęcie nagrywania dźwięku na podstawie sygnału określonego przez MediaSyncEvent
.
Parametr MediaSyncEvent
określa sesję audio (np. zdefiniowaną przez parametr MediaPlayer
), która po zakończeniu uruchamia nagrywanie dźwięku. Możesz na przykład użyć tej funkcji, aby odtworzyć sygnał dźwiękowy, który wskazuje początek sesji nagrywania, a nagranie rozpocznie się automatycznie, dzięki czemu nie musisz ręcznie synchronizować sygnału i początku nagrania.
ścieżki tekstowe zsynchronizowane z obrazem,
MediaPlayer
obsługuje teraz ścieżki tekstowe w zakresie i poza zakresem.
Ścieżki tekstowe w paśmie są ścieżkami tekstowymi w źródle multimediów MP4 lub 3GPP. Ścieżki tekstowe spoza kanału można dodawać jako zewnętrzne źródło tekstowe za pomocą metody addTimedTextSource()
. Po dodaniu wszystkich zewnętrznych źródeł napisów należy wywołać funkcję getTrackInfo()
, aby uzyskać zaktualizowaną listę wszystkich dostępnych napisów w źródle danych.
Aby ustawić ścieżkę do użycia w MediaPlayer
, musisz wywołać funkcję selectTrack()
, podając indeks pozycji ścieżki, której chcesz użyć.
Aby otrzymać powiadomienie, gdy ścieżka tekstowa będzie gotowa do odtwarzania, zaimplementuj interfejs MediaPlayer.OnTimedTextListener
i przekaż go do setOnTimedTextListener()
.
Efekty dźwiękowe
Klasa AudioEffect
obsługuje teraz dodatkowe typy wstępnego przetwarzania dźwięku podczas jego rejestrowania:
- Akustyczny reduktor echa (AEC) z funkcją
AcousticEchoCanceler
usuwa sygnał odbierany od strony zdalnej z przechwyconego sygnału audio. - Automatyczna kontrola wzmocnienia (AGC) z użyciem
AutomaticGainControl
automatycznie normalizuje sygnał wyjściowy. - Reduktor szumów (NS) z
NoiseSuppressor
usuwa szum w tle z nagrywanego sygnału.
Te efekty wstępnego przetwarzania możesz stosować do dźwięku zarejestrowanego za pomocą urządzenia AudioRecord
, korzystając z jednej z podklas AudioEffect
.
Uwaga: nie ma gwarancji, że wszystkie urządzenia będą obsługiwać te efekty, dlatego zawsze należy najpierw sprawdzić dostępność, wywołując funkcję isAvailable()
w odpowiedniej klasie efektów dźwiękowych.
Odtwarzanie bez przerw
Teraz możesz odtwarzać bez przerwy 2 osobne obiekty MediaPlayer
. W dowolnym momencie przed zakończeniem pierwszego MediaPlayer
wywołania setNextMediaPlayer()
i Android próbują uruchomić drugi odtwarzacz w momencie, gdy pierwszy przestanie działać.
Aparat
Ruch autofokusu
Nowy interfejs Camera.AutoFocusMoveCallback
umożliwia słuchanie zmian w ruchu automatycznego fokusa. Możesz zarejestrować interfejs w usłudze setAutoFocusMoveCallback()
. Gdy aparat będzie w trybie ciągłego autofokusa (FOCUS_MODE_CONTINUOUS_VIDEO
lub FOCUS_MODE_CONTINUOUS_PICTURE
), otrzymasz wywołanie funkcji onAutoFocusMoving()
, które informuje, czy autofokus zaczął się poruszać, czy przestał.
Dźwięki aparatu
Klasa MediaActionSound
udostępnia prosty zestaw interfejsów API do generowania standardowych dźwięków aparatu lub innych działań związanych z multimediami. Należy używać tych interfejsów API, aby odtwarzać odpowiedni dźwięk podczas tworzenia niestandardowej kamery do zdjęć lub filmów.
Aby odtworzyć dźwięk, po prostu utwórz instancję obiektu MediaActionSound
, wywołaj metodę load()
, aby wstępnie załadować żądany dźwięk, a potem w odpowiednim momencie wywołaj metodę play()
.
Łączność
Android Beam
Android BeamTM obsługuje teraz przesyłanie dużych ładunków przez Bluetooth. Gdy definiujesz dane do przesłania za pomocą nowej metody setBeamPushUris()
lub nowego interfejsu wywołania zwrotnego NfcAdapter.CreateBeamUrisCallback
, Android przekazuje dane do Bluetootha lub innego środka transportu, by przyspieszyć transfer. Jest to szczególnie przydatne w przypadku dużych ładunków, takich jak obrazy i pliki audio. Nie wymaga widocznego parowania urządzeń. Aby korzystać z przesyłania przez Bluetooth, nie musisz nic robić w swojej aplikacji.
Metoda setBeamPushUris()
pobiera tablicę obiektów Uri
, które określają dane, które chcesz przenieść z aplikacji. Możesz też wdrożyć interfejs NfcAdapter.CreateBeamUrisCallback
, który możesz określić dla swojej aktywności, wywołując funkcję setBeamPushUrisCallback()
.
Gdy używasz interfejsu wywołania zwrotnego, system wywołuje metodę createBeamUris()
interfejsu, gdy użytkownik wykona udostępnianie za pomocą Android Beam, aby umożliwić zdefiniowanie identyfikatorów URI do udostępniania w momencie udostępniania.
Jest to przydatne, jeśli URI do udostępnienia mogą się różnić w zależności od kontekstu użytkownika w ramach aktywności, podczas gdy wywołanie setBeamPushUris()
jest przydatne, gdy URI do udostępnienia są niezmienne i można je bezpiecznie zdefiniować z wyprzedzeniem.
Wykrywanie usług sieciowych
Android 4.1 obsługuje wykrywanie usług na podstawie multicastu DNS, co umożliwia znajdowanie i nawiązywanie połączenia z usługami oferowanymi przez urządzenia partnerskie przez Wi-Fi, takimi jak urządzenia mobilne, drukarki, kamery, odtwarzacze multimedialne i inne urządzenia zarejestrowane w sieci lokalnej.
Nowy pakiet android.net.nsd
zawiera nowe interfejsy API, które umożliwiają nadawanie usług w sieci lokalnej, wykrywanie lokalnych urządzeń w sieci i łączenie się z nimi.
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 zaimplementować funkcję NsdManager.RegistrationListener
i przekazać ją do registerService()
za pomocą NsdServiceInfo
.
Aby wykrywać usługi w sieci, zaimplementuj NsdManager.DiscoveryListener
i prześlij go do discoverServices()
.
Gdy usługa NsdManager.DiscoveryListener
otrzyma wywołania zwrotne dotyczące znalezionych usług, musisz rozwiązać usługę, wywołując funkcję resolveService()
, przekazując jej implementację funkcji NsdManager.ResolveListener
, która odbiera obiekt NsdServiceInfo
zawierający informacje o odkrytej usłudze, co umożliwia zainicjowanie połączenia.
Wykrywanie usług P2P w sieci Wi-Fi
Interfejsy API sieci Wi-Fi P2P zostały ulepszone w Androidzie 4.1, aby obsługiwały wykrywanie usług przed powiązaniem w WifiP2pManager
. Dzięki temu możesz wykrywać i filtrować urządzenia w pobliżu według usług korzystających z Wi-Fi P2P przed połączeniem się z jednym z nich. Funkcja wykrywania usług sieciowych pozwala natomiast wykryć usługę w dostępnej sieci (np. lokalnej sieci Wi-Fi).
Aby transmitować przez Wi-Fi aplikację jako usługę, dzięki czemu inne urządzenia mogły ją wykryć i połączyć, wywołaj addLocalService()
za pomocą obiektu WifiP2pServiceInfo
opisującego usługi aplikacji.
Aby rozpocząć wyszukiwanie urządzeń w pobliżu przez Wi-Fi, musisz najpierw zdecydować, czy chcesz komunikować się za pomocą Bonjour czy UPnP. Aby korzystać z Bonjour, najpierw skonfiguruj odsłuchiwanie wywołań zwrotnych za pomocą funkcji setDnsSdResponseListeners()
, która przyjmuje zarówno argument WifiP2pManager.DnsSdServiceResponseListener
, jak i WifiP2pManager.DnsSdTxtRecordListener
. Aby użyć Upnp, wywołaj funkcję setUpnpServiceResponseListener()
, która przyjmuje parametr WifiP2pManager.UpnpServiceResponseListener
.
Zanim zaczniesz wykrywać usługi na urządzeniach lokalnych, musisz też zadzwonić pod numer addServiceRequest()
. Gdy przekazana do tej metody usługa WifiP2pManager.ActionListener
otrzyma połączenie zwrotne, możesz rozpocząć wyszukiwanie usług na urządzeniach lokalnych, wywołując funkcję discoverServices()
.
Gdy wykryjemy usługi lokalne, skontaktujemy się z Tobą przez WifiP2pManager.DnsSdServiceResponseListener
lub WifiP2pManager.UpnpServiceResponseListener
, w zależności od tego, czy zarejestrowałeś/zarejestrowałaś się do korzystania z Bonjour czy Upnp. W obu przypadkach wywołanie zwraca obiekt WifiP2pDevice
reprezentujący urządzenie partnera.
Wykorzystanie sieci
Nowa metoda isActiveNetworkMetered()
pozwala sprawdzić, czy urządzenie jest obecnie połączone z siecią z limitem danych. Sprawdzanie tego stanu przed przeprowadzeniem intensywnych transakcji sieciowych pozwala zarządzać wykorzystaniem danych, które może kosztować użytkowników pieniądze, oraz podejmować świadome decyzje dotyczące tego, czy przeprowadzić transakcje teraz, czy później (np. gdy urządzenie połączy się z Wi-Fi).
Ułatwienia dostępu
Interfejsy API usług ułatwień dostępu
W Androidzie 4.1 znacznie zwiększyliśmy zasięg interfejsów API usług ułatwień dostępu. Pozwala teraz tworzyć usługi, które monitorują więcej zdarzeń wejściowych, takich jak złożone gesty, i reagują na nie (np. złożone gesty za pomocą funkcji onGesture()
) i inne zdarzenia wejściowe przez dodanie do klas AccessibilityEvent
, AccessibilityNodeInfo
i AccessibilityRecord
.
Usługi dostępności mogą też wykonywać działania w imieniu użytkownika, takie jak klikanie, przewijanie i przechodzenie przez tekst za pomocą performAction
i setMovementGranularities
. Metoda performGlobalAction()
umożliwia też usługom wykonywanie działań takich jak Wstecz i Ekran główny oraz otwieranie ostatnich aplikacji i powiadomień.
Spersonalizowana nawigacja po aplikacji
Podczas tworzenia aplikacji na Androida możesz teraz dostosować schematy nawigacji, znajdując elementy, które można zaznaczyć i widżety wejściowe za pomocą funkcji findFocus()
i focusSearch()
, oraz ustawić fokus za pomocą setAccessibilityFocused()
.
Dostępniejsze widżety
Nowa klasa android.view.accessibility.AccessibilityNodeProvider
umożliwia wyświetlanie złożonych widoków niestandardowych usługom ułatwień dostępu, aby mogły one prezentować informacje w bardziej przystępny sposób. android.view.accessibility.AccessibilityNodeProvider
umożliwia użytkownikowi wyświetlanie za pomocą widżetu z zaawansowanymi treściami, takimi jak siatka kalendarza, logicznej struktury semantycznej usług ułatwień dostępu, która jest całkowicie oddzielona od struktury układu widżetu. Ta struktura semantyczna umożliwia usługom ułatwień prezentowanie bardziej przydatnego modelu interakcji użytkownikom niedowidzącym.
Kopiowanie i wklejanie
Kopiuj i wklej z intencjami
Teraz możesz powiązać obiekt ClipData
z obiektem Intent
za pomocą metody setClipData()
.
Jest to szczególnie przydatne, gdy używasz intencji do przenoszenia wielu adresów URI content:
do innej aplikacji, na przykład podczas udostępniania wielu dokumentów. Identyfikatory URI content:
podane w ten sposób uwzględniają również flagi intencji i zapewniają uprawnienia do odczytu lub zapisu, co pozwala przyznać dostęp do wielu identyfikatorów URI w intencji. Gdy uruchamiasz intencję ACTION_SEND
lub ACTION_SEND_MULTIPLE
, podane w niej identyfikatory URI są automatycznie propagowane do usługi 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 HTML lub stylizowanych ciągów tekstowych na Androida). Do elementu ClipData
możesz dodać tekst w stylu HTML za pomocą elementu newHtmlText()
.
Renderscript
Funkcja obliczeniowa Renderscript została ulepszona o te funkcje:
- Obsługa wielu jąder w ramach jednego skryptu.
- Obsługa odczytu z alokacji z filtrowanymi próbnikami z Compute w nowym interfejsie skryptu API
rsSample
. - Obsługa różnych poziomów dokładności FP w
#pragma
. - Obsługa zapytań o dodatkowe informacje z obiektów RS z wykorzystaniem skryptu obliczeniowego.
- Liczne usprawnienia działania.
Dostępne są też nowe pragmatyki, które umożliwiają określenie precyzji zmiennoprzecinkowej wymaganej przez Renderscripts. Umożliwia to włączenie operacji typu NEON, takich jak szybkie operacje wektorowe na procesorze, które nie byłyby możliwe w ramach pełnego standardu IEEE 754-2008.
Uwaga: eksperymentalny silnik graficzny Renderscript został wycofany.
Animacja
Animacje uruchamiania aktywności
Teraz możesz uruchomić Activity
, używając animacji powiększenia lub własnych animacji. Aby określić animację, użyj interfejsów API ActivityOptions
do utworzenia Bundle
, który potem możesz przekazać do dowolnej metody rozpoczynającej działanie, np. startActivity()
.
Klasa ActivityOptions
zawiera inną metodę dla każdego typu animacji, który możesz pokazywać przy otwieraniu aktywności:
makeScaleUpAnimation()
- Tworzy animację, która powiększa okno aktywności od określonej pozycji początkowej na ekranie i od określonego początkowego rozmiaru. Na przykład ekran główny w Androidzie 4.1 używa tego podczas otwierania aplikacji.
makeThumbnailScaleUpAnimation()
- Tworzy animację, która powiększa okno aktywności, zaczynając od określonej pozycji i podawanego obrazu miniatury. Na przykład okno Ostatnie aplikacje w Androidzie 4.1 używa tej funkcji podczas powrotu do aplikacji.
makeCustomAnimation()
- Tworzy animację zdefiniowaną przez Twoje zasoby: jedną, która definiuje animację otwarcia, a drugą dla zatrzymanego działania.
Czas animator
Nowa funkcja TimeAnimator
zapewnia prosty mechanizm wywołania TimeAnimator.TimeListener
, który powiadamia Cię o każdej klatce animacji. Ten animator nie ma ustawień czasu trwania, interpolacji ani wartości obiektu. Wywołanie zwrotne detektora otrzymuje informacje o każdej klatce, w tym całkowity czas, który upłynął, oraz czas, który upłynął od ostatniej 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 działań i konfigurowanym priorytetem.
Style powiadomień
Nowa metoda setStyle()
umożliwia określenie jednego z 3 nowych stylów powiadomienia, z których każdy oferuje większy obszar treści. Aby określić styl dużego obszaru treści, prześlij setStyle()
jeden z tych obiektów:
Notification.BigPictureStyle
- W przypadku powiadomień z dużym załącznikiem w postaci obrazu.
Notification.BigTextStyle
- W przypadku powiadomień zawierających dużo tekstu, np. e-maila.
Notification.InboxStyle
- W przypadku powiadomień zawierających listę ciągów tekstowych, np. fragmenty z wielu e-maili.
Działania powiadomień
U dołu wiadomości z powiadomieniem mogą być teraz wyświetlane maksymalnie 2 przyciski polecenia – niezależnie od tego, czy jest to styl zwykły czy większy.
Aby dodać przycisk działania, wywołaj funkcję addAction()
. Ta metoda przyjmuje 3 argumenty: zasób do rysowania ikony, tekst przycisku i wartość PendingIntent
definiującą działanie do wykonania.
Priorytety
Możesz teraz zasugerować systemowi, jak ważne jest powiadomienie, aby wpływać na jego kolejność na liście, ustawiając priorytet za pomocą setPriority()
. Możesz podać jeden z 5 różnych poziomów priorytetu zdefiniowanych za pomocą stałych PRIORITY_*
w klasie Notification
. Wartość domyślna to PRIORITY_DEFAULT
, a dostępne są 2 poziomy wyższe i 2 poziomy niższe.
Powiadomienia o wysokim priorytecie to te, na które użytkownicy zazwyczaj chcą szybko odpowiadać, takie jak nowa wiadomość błyskawiczna, wiadomość tekstowa czy przypomnienie o zbliżającym się wydarzeniu. Powiadomienia o niskim priorytecie to np. wygasłe wydarzenia w kalendarzu czy promocje aplikacji.
Elementy sterujące interfejsu systemu
W Androidzie 4.0 (Ice Cream Sandwich) dodano nowe flagi, które umożliwiają kontrolowanie widoczności elementów interfejsu użytkownika systemu, np. przyciemnianie paska systemu lub całkowite ukrywanie go na telefonach.
W Androidzie 4.1 pojawiło się kilka kolejnych flag, które dają większą kontrolę nad wyglądem elementów interfejsu systemu oraz układem działań względem nich, wywołując setSystemUiVisibility()
i przekazując te flagi:
SYSTEM_UI_FLAG_FULLSCREEN
- Ukrywa niekrytyczny interfejs systemu (np. pasek stanu).
Jeśli Twoja aktywność używa paska czynności w trybie nakładki (poprzez włączenie
android:windowActionBarOverlay
), flaga ta powoduje też ukrycie paska czynności. Robi to za pomocą skoordynowanej animacji, która powoduje ukrycie i wyświetlenie obu elementów. SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- Ustawia układ aktywności tak, aby używać tej samej części ekranu, która jest dostępna, gdy włączysz
SYSTEM_UI_FLAG_FULLSCREEN
, nawet jeśli elementy interfejsu użytkownika systemu są nadal widoczne. Części układu będą nakładać się na interfejs systemowy, ale ta opcja jest przydatna, jeśli aplikacja często chowa i wyświetla interfejs systemowy za pomocąSYSTEM_UI_FLAG_FULLSCREEN
, ponieważ zapobiega dostosowywaniu układu do nowych ograniczeń układu za każdym razem, gdy interfejs systemowy się wyświetla lub chowa. SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- Ustawia układ aktywności tak, aby używać tej samej części ekranu, która jest dostępna, gdy włączysz
SYSTEM_UI_FLAG_HIDE_NAVIGATION
(dodano w Androidzie 4.0), nawet jeśli elementy interfejsu użytkownika systemu są nadal widoczne. Części układu będą nakładać się na pasek nawigacji, ale ta opcja jest przydatna, jeśli aplikacja często chowa i wyświetla pasek nawigacji za pomocąSYSTEM_UI_FLAG_HIDE_NAVIGATION
, ponieważ zapobiega dostosowywaniu układu do nowych ograniczeń układu za każdym razem, gdy pasek nawigacji znika lub pojawia się. SYSTEM_UI_FLAG_LAYOUT_STABLE
- Możesz dodać tę flagę, jeśli używasz
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
lubSYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
, aby mieć pewność, że gdy wywołasz funkcjęfitSystemWindows()
w widoku, zdefiniowane granice pozostaną spójne z dostępną przestrzenią na ekranie. Oznacza to, że po ustawieniu tego parametrufitSystemWindows()
będzie zachowywać się tak, jakby widoczność elementów interfejsu systemu nie uległa zmianie, nawet jeśli ukryjesz cały interfejs systemu.
Więcej informacji o flagach interfejsu użytkownika związanych z tym tematem znajdziesz w artykule o flagach dodanych w Androidzie 4.0.
Widoki zdalne
Widoki GridLayout
i ViewStub
można teraz usuwać, dzięki czemu możesz używać ich w układach widżetów aplikacji i niestandardowych układów powiadomień.
Rodziny czcionek
Android 4.1 zawiera kilka dodatkowych wariantów czcionki Roboto, w których sumie jest ich 10. Wszystkie można używać w aplikacjach. Twoje aplikacje mają teraz dostęp do pełnego zestawu wersji uproszczonych i skompresowanych.
Pełny zestaw dostępnych wariantów czcionek Roboto to:
- regularne
- Kursywa
- Pogrubienie
- Pogrubiona kursywa
- Jasny
- Kursywa lekka
- Wąski standardowy
- Kursywa skondensowana
- Pogrubienie wąskie
- Pogrubiona kursywa skondensowana
Możesz zastosować dowolny z tych atrybutów za pomocą nowego atrybutu fontFamily
w połączeniu z atrybutem textStyle
.
Obsługiwane wartości atrybutu fontFamily
to:
"sans-serif"
w przypadku zwykłej czcionki Roboto"sans-serif-light"
dla Roboto Light"sans-serif-condensed"
dla Roboto Condensed
Następnie możesz zastosować pogrubienie lub kursywę w przypadku wartości textStyle
"bold"
i "italic"
. Możesz zastosować obie metody: android:textStyle="bold|italic"
.
Możesz też użyć narzędzia Typeface.create()
.
Na przykład: Typeface.create("sans-serif-light", Typeface.NORMAL)
.
Platforma danych wejściowych
Wiele urządzeń wejściowych
Nowa klasa InputManager
umożliwia wysyłanie zapytań do zestawu urządzeń wejściowych, które są aktualnie połączone, oraz rejestrowanie powiadomień o dodaniu, zmianie lub usunięciu nowego urządzenia. Jest to szczególnie przydatne, jeśli tworzysz grę, która obsługuje wielu graczy, i chcesz wykrywać, ile kontrolerów jest połączonych oraz kiedy zmienia się ich liczba.
Możesz wysyłać zapytania do wszystkich urządzeń wejściowych, które są połączone z urządzeniem, wywołując getInputDeviceIds()
. Zwraca tablicę liczb całkowitych, z których każda stanowi identyfikator innego urządzenia wejściowego. Następnie możesz wywołać funkcję getInputDevice()
, aby uzyskać InputDevice
dla określonego identyfikatora urządzenia wejściowego.
Jeśli chcesz otrzymywać informacje o podłączeniu, zmianie lub odłączeniu nowych urządzeń wejściowych, zaimplementuj interfejs InputManager.InputDeviceListener
i zarejestruj go za pomocą registerInputDeviceListener()
.
Wibracje w przypadku urządzeń sterujących
Jeśli podłączone urządzenia wejściowe mają własne funkcje wibracji, możesz nimi sterować za pomocą istniejących interfejsów API Vibrator
. Wystarczy, że wywołasz getVibrator()
na urządzeniu InputDevice
.
Uprawnienia
Oto nowe uprawnienia:
READ_EXTERNAL_STORAGE
- Zapewnia chroniony dostęp tylko do odczytu do pamięci zewnętrznej. Domyślnie na Androidzie 4.1 wszystkie aplikacje nadal mają dostęp do odczytu. W przyszłej wersji zmienimy to, aby wymagać, aby aplikacje wyraźnie prosiły o dostęp do odczytu przy użyciu tego uprawnienia. Jeśli Twoja aplikacja już prosi o uprawnienia do zapisu, automatycznie otrzyma te uprawnienia również w trybie odczytu. Dostępna jest nowa opcja dla deweloperów, która umożliwia włączenie ograniczenia dostępu do odczytu, aby mogli oni testować swoje aplikacje pod kątem zachowania Androida w przyszłości.
- android.Manifest.permission.READ_USER_DICTIONARY
- Zezwala aplikacji na odczytywanie słownika użytkownika. Wymaganie to powinno dotyczyć tylko IME lub edytora słownika, takiego jak aplikacja Ustawienia.
READ_CALL_LOG
- Zezwala aplikacji na odczytywanie systemowego rejestru połączeń, który zawiera informacje o połączeniach przychodzących i wychodzących.
WRITE_CALL_LOG
- Pozwala aplikacji modyfikować rejestr połączeń systemu zapisany na telefonie
- android.Manifest.permission.WRITE_USER_DICTIONARY
- Zezwala aplikacji na zapisywanie danych w słowniku użytkownika.
Funkcje urządzenia
Android 4.1 zawiera nową deklarację funkcji w przypadku 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: wyświetlany na dużym ekranie, gdy użytkownik siedzi daleko, a dominująca forma wprowadzania danych jest podobna do krzyżaka, a nie dotykowa lub za pomocą myszki/wskaźnika.