Interfejsy API Androida 4.0

Poziom API: 14

Android 4.0 (ICE_CREAM_SANDWICH) to główna wersja platformy, która dodaje szereg nowych funkcji dla użytkowników i deweloperów aplikacji. Oprócz wszystkich omówionych poniżej nowych funkcji i interfejsów API Android 4.0 to ważna platforma, ponieważ udostępnia szeroki zestaw interfejsów API i motywów holograficznych z Androida 3.x na mniejsze ekrany. Jako deweloper masz do dyspozycji pojedynczą platformę i ujednoliconą platformę interfejsu API, dzięki której możesz tworzyć i publikować aplikacje z użyciem jednego pliku APK zoptymalizowanego pod kątem telefonów, tabletów i innych urządzeń z tą samą wersją Androida – Androida 4.0 (poziom interfejsu API 14) lub nowszego.

Platforma Android 4.0 jest dostępna dla programistów jako komponent pakietu Android SDK, który można pobrać. Platforma do pobrania zawiera bibliotekę Androida i obraz systemu, a także zestaw skórek emulatorów. Aby zacząć programować lub testować Androida w wersji 4.0, pobierz platformę do swojego pakietu SDK za pomocą Menedżera pakietów Android SDK.

Omówienie interfejsu API

Sekcje poniżej zawierają omówienie techniczne nowych interfejsów API w Androidzie 4.0.

Interfejsy API społecznościowe w dostawcy kontaktów

Interfejsy API kontaktów zdefiniowane przez dostawcę ContactsContract zostały rozszerzone, aby obsługiwać nowe funkcje społecznościowe, takie jak profil osobisty właściciela urządzenia oraz możliwość zapraszania poszczególnych kontaktów do sieci społecznościowych zainstalowanych na urządzeniu.

Profil użytkownika

Android zawiera teraz profil osobisty reprezentujący właściciela urządzenia (zgodnie z definicją w tabeli ContactsContract.Profile). Aplikacje społecznościowe, które utrzymują tożsamość użytkownika, mogą współtworzyć dane profilowe użytkownika przez utworzenie nowego wpisu ContactsContract.RawContacts w elemencie ContactsContract.Profile. Oznacza to, że nieprzetworzone kontakty reprezentujące użytkownika urządzenia nie należą do tradycyjnej tabeli nieprzetworzonych kontaktów zdefiniowanej przez identyfikator URI ContactsContract.RawContacts. Należy dodać nieprzetworzony kontakt do profilu w tabeli CONTENT_RAW_CONTACTS_URI. Nieprzetworzone kontakty z tej tabeli są następnie agregowane w jednym widocznym dla użytkownika profilu o nazwie „Ja”.

Dodanie do profilu nowego nieprzetworzonego kontaktu wymaga uprawnienia android.Manifest.permission#WRITE_PROFILE. Podobnie, aby odczytać dane z tabeli profili, musisz poprosić o uprawnienie android.Manifest.permission#READ_PROFILE. Większość aplikacji nie powinna jednak odczytywać profilu użytkownika, nawet jeśli przekazują do niego dane. Odczytywanie profilu użytkownika to uprawnienie newralgiczne i należy oczekiwać, że użytkownicy będą sceptycznie nastawieni do aplikacji, które o nie proszą.

Zaproszenie do zamiaru

Działanie intencji INVITE_CONTACT umożliwia aplikacji wywołanie działania wskazującego, że użytkownik chce dodać kontakt do sieci społecznościowej. Aplikacja odbierająca dane z aplikacji używa jej, aby zaprosić określony kontakt do tej sieci społecznościowej. Większość aplikacji będzie otrzymywać po tej operacji. Na przykład wbudowana aplikacja Osoby wywołuje intencję zaproszenia, gdy użytkownik wybierze opcję „Dodaj połączenie” dla określonej aplikacji społecznościowej wymienionej w danych kontaktowych danej osoby.

Aby aplikacja była widoczna jako widoczna na liście „Dodaj połączenie”, musi udostępniać adapter synchronizacji, aby synchronizować informacje kontaktowe z sieci społecznościowej. Następnie musisz wskazać systemowi, że aplikacja odpowiada na intencję INVITE_CONTACT, dodając do jej pliku konfiguracji synchronizacji atrybut inviteContactActivity z pełną i jednoznaczną nazwą działania, które system powinien uruchomić podczas wysyłania intencji zaproszenia. Rozpoczęte działanie może następnie pobrać identyfikator URI odpowiedniego kontaktu z danych intencji i wykonać niezbędne działania w celu zaproszenia tego kontaktu do sieci lub dodania osoby do połączeń użytkownika.

Duże zdjęcia

Android obsługuje teraz zdjęcia kontaktów w wysokiej rozdzielczości. Teraz, gdy przekażesz zdjęcie do rekordu kontaktu, system przetworzy je jako miniaturę 96 x 96 (jak wcześniej) oraz „wyświetlane zdjęcie” 256 x 256, które jest zapisane w nowym magazynie zdjęć na podstawie plików (dokładne wymiary wybrane przez system mogą się w przyszłości różnić). Możesz dodać duże zdjęcie do kontaktu, umieszczając duże zdjęcie w zwykłej kolumnie PHOTO w wierszu danych, które system następnie przetworzy do odpowiedniej miniatury i wyświetli rekordy zdjęć.

Opinia na temat korzystania z kontaktów

Nowe interfejsy API ContactsContract.DataUsageFeedback ułatwiają śledzenie, jak często użytkownicy korzystają z określonych metod kontaktu z innymi osobami, np. jak często korzystają z poszczególnych numerów telefonów lub adresów e-mail. Te informacje poprawiają pozycję każdej z tych osób w rankingu dla każdej formy kontaktu i zapewniają lepsze sugestie kontaktu.

Dostawca kalendarza

Nowe interfejsy API Kalendarza umożliwiają odczytywanie, dodawanie, modyfikowanie i usuwanie kalendarzy, wydarzeń, uczestników, przypomnień i alertów przechowywanych przez dostawcę kalendarza.

Różne aplikacje i widżety mogą używać tych interfejsów API do odczytywania i modyfikowania wydarzeń w kalendarzu. Do najciekawszych zastosowań należą jednak adaptery synchronizacji, które synchronizują kalendarz użytkownika z innych usług kalendarza z dostawcą kalendarza w celu zapewnienia ujednoliconej lokalizacji dla wszystkich wydarzeń użytkownika. Na przykład wydarzenia z Kalendarza Google są synchronizowane z dostawcą kalendarza przez adapter synchronizacji Kalendarza Google, co umożliwia wyświetlanie tych wydarzeń we wbudowanej aplikacji Kalendarz na Androida.

Model danych kalendarzy i informacji związanych z wydarzeniami w dostawcy kalendarza jest definiowany przez CalendarContract. Wszystkie dane kalendarza użytkownika są przechowywane w szeregu tabel zdefiniowanych przez różne podklasy CalendarContract:

  • Tabela CalendarContract.Calendars zawiera informacje specyficzne dla kalendarza. Każdy wiersz w tej tabeli zawiera szczegółowe informacje na temat pojedynczego kalendarza, takie jak nazwa, kolor, informacje o synchronizacji itp.
  • Tabela CalendarContract.Events zawiera informacje dotyczące konkretnego zdarzenia. Każdy wiersz w tej tabeli zawiera informacje o pojedynczym wydarzeniu, np. tytuł, lokalizację, godzinę rozpoczęcia, godzinę zakończenia itd. Zdarzenie może wystąpić jednorazowo lub wielokrotnie. Uczestnicy, przypomnienia i rozszerzone właściwości są przechowywane w osobnych tabelach i używają _ID wydarzenia, aby połączyć je z wydarzeniem.
  • Tabela CalendarContract.Instances zawiera czas rozpoczęcia i zakończenia wystąpienia zdarzenia. Każdy wiersz w tej tabeli odpowiada jednemu wystąpieniu. W przypadku zdarzeń jednorazowych następuje mapowanie instancji jeden do jednego na zdarzenia. W przypadku wydarzeń cyklicznych automatycznie generujemy wiele wierszy odpowiadających wielokrotnym wystąpieniem danego wydarzenia.
  • Tabela CalendarContract.Attendees zawiera informacje o uczestniku lub gościu wydarzenia. Każdy wiersz odpowiada jednemu gościowi wydarzenia. Wskazuje on typ gościa i reakcję tej osoby na wydarzenie.
  • Tabela CalendarContract.Reminders zawiera dane alertów/powiadomień. Każdy wiersz odpowiada jednemu alertowi dotyczącemu zdarzenia. Wydarzenie może mieć kilka przypomnień. Liczba przypomnień na wydarzenie jest określana w polu MAX_REMINDERS, ustawianym przez adapter synchronizacji, do którego należy dany kalendarz. Przypomnienia są podawane w minutach przed zaplanowaniem wydarzenia i określają metodę alarmu, taką jak alert, e-mail lub SMS.
  • Tabela CalendarContract.ExtendedProperties zawiera nieprzejrzyste pola danych używane przez adapter synchronizacji. Dostawca nie wykonuje żadnych działań w odniesieniu do elementów w tej tabeli z wyjątkiem usunięcia ich, gdy powiązane z nimi zdarzenia zostaną skasowane.

Aby uzyskać dostęp do danych kalendarza użytkownika za pomocą dostawcy kalendarza, aplikacja musi poprosić o uprawnienie READ_CALENDAR (dostęp do odczytu) i WRITE_CALENDAR (uprawnienia do zapisu).

Intencja zdarzenia

Jeśli chcesz tylko dodać wydarzenie do kalendarza użytkownika, możesz użyć intencji ACTION_INSERT z danymi zdefiniowanymi przez Events.CONTENT_URI, aby uruchomić w aplikacji Kalendarz działanie tworzące nowe wydarzenia. Użycie intencji nie wymaga żadnych uprawnień. Możesz określić szczegóły zdarzenia za pomocą tych dodatków:

Dostawca poczty głosowej

Nowy dostawca poczty głosowej umożliwia aplikacjom dodawanie do urządzenia wiadomości poczty głosowej w celu przedstawienia wszystkich wiadomości głosowych użytkownika w formie jednej prezentacji. Na przykład użytkownik może korzystać z wielu źródeł poczty głosowej, takich jak m.in. u operatora komórkowego i w VoIP bądź w innych usługach głosowych. Te aplikacje mogą dodawać wiadomości głosowe do urządzenia za pomocą interfejsów API dostawcy poczty głosowej. Wbudowana aplikacja Telefon prezentuje użytkownikowi wszystkie wiadomości głosowe w formie ujednoliconej prezentacji. Mimo że systemowa aplikacja Telefon jest jedyną aplikacją, która może odczytywać wszystkie wiadomości poczty głosowej, każda aplikacja udostępniająca pocztę głosową może odczytać te wiadomości dodane do systemu (ale nie może odczytywać wiadomości głosowych z innych usług).

Interfejsy API obecnie nie pozwalają aplikacjom innych firm na odczytywanie całej poczty głosowej z systemu, dlatego jedynymi aplikacjami innych firm, które powinny korzystać z interfejsów API poczty głosowej, są te aplikacje, które dostarczają użytkownikom pocztę głosową.

Klasa VoicemailContract określa dostawcę treści dla usługi Provder poczty głosowej. Podklasy VoicemailContract.Voicemails i VoicemailContract.Status zawierają tabele, w których aplikacje mogą wstawiać dane poczty głosowej, aby przechowywać je na urządzeniu. Przykład aplikacji dostawcy poczty głosowej znajdziesz w prezentacji dostawcy poczty głosowej.

Multimedia

Android 4.0 dodaje kilka nowych interfejsów API dla aplikacji, które wchodzą w interakcję z multimediami, takimi jak zdjęcia, filmy czy muzyka.

Efekty multimedialne

Nowa platforma efektów multimedialnych umożliwia stosowanie w obrazach i filmach różnych efektów wizualnych. Na przykład efekty graficzne pozwalają łatwo usunąć efekt czerwonych oczu, zmienić tryb szarości, dostosować jasność, nasycenie, obrócić lub zastosować efekt rybiego oka. System wykonuje wszystkie przetwarzanie efektów na GPU, aby uzyskać maksymalną wydajność.

Aby uzyskać maksymalną wydajność, efekty są stosowane bezpośrednio do tekstur OpenGL, dlatego aplikacja musi mieć prawidłowy kontekst OpenGL, zanim będzie mogła korzystać z interfejsów API efektów. Tekstury, do których stosujesz efekty, mogą pochodzić z map bitowych, filmów, a nawet z kamery. Istnieją jednak pewne ograniczenia, które muszą spełniać tekstury:

  1. Muszą być powiązane z obrazem tekstury GL_TEXTURE_2D
  2. Muszą one zawierać co najmniej 1 poziom mipmap

Obiekt Effect definiuje jeden efekt multimedialny, który możesz zastosować do ramki obrazu. Podstawowy przepływ pracy do utworzenia Effect to:

  1. Wywołaj aplikację EffectContext.createWithCurrentGlContext() z kontekstu OpenGL ES 2.0.
  2. Użyj zwróconego EffectContext, aby wywołać metodę EffectContext.getFactory(), która zwraca wystąpienie EffectFactory.
  3. Wywołaj createEffect(), przekazując do niego nazwę efektu z metody @link android.media.effect.EffectFactory}, np. EFFECT_FISHEYE lub EFFECT_VIGNETTE.

Parametry efektu możesz dostosować, wywołując setParameter() i przekazując nazwę parametru oraz jego wartość. Każdy rodzaj efektu akceptuje różne parametry, które są udokumentowane wraz z nazwą efektu. Na przykład EFFECT_FISHEYE zawiera jeden parametr scale zniekształcenia.

Aby zastosować efekt na teksturę, wywołaj funkcję apply() w metodzie Effect i przekaż teksturę wejściową, jej szerokość i wysokość oraz teksturę wyjściową. Tekstura wejściowa musi być powiązana z obrazem tekstury GL_TEXTURE_2D (zwykle odbywa się to przez wywołanie funkcji glTexImage2D()). Możesz podać wiele poziomów mipmap. Jeśli tekstura wyjściowa nie została powiązana z obrazem o teksturze, zostanie automatycznie związana z efektem jako GL_TEXTURE_2D i jednym poziomem mipmamy (0), który będzie miał taki sam rozmiar jak dane wejściowe.

Wszystkie efekty wymienione w sekcji EffectFactory będą obsługiwane. Jednak niektóre dodatkowe efekty z bibliotek zewnętrznych nie są obsługiwane przez wszystkie urządzenia, więc najpierw musisz sprawdzić, czy pożądany efekt z biblioteki zewnętrznej jest obsługiwany, wywołując metodę isEffectSupported().

Klient zdalnego sterowania

Nowy RemoteControlClient umożliwia odtwarzaczam multimediów włączanie elementów sterujących odtwarzaniem z klientów zdalnych, takich jak ekran blokady urządzenia. Odtwarzacze mogą też pokazywać informacje o aktualnie odtwarzanych multimediach na pilocie, np. informacje o utworach i okładkach albumów.

Aby włączyć klienty zdalnego sterowania na potrzeby odtwarzacza multimediów, utwórz instancję RemoteControlClient za pomocą jej konstruktora, przesyłając do niego obiekt PendingIntent, który rozgłasza ACTION_MEDIA_BUTTON. Intencja musi też zadeklarować w aplikacji jawny komponent BroadcastReceiver, który obsługuje zdarzenie ACTION_MEDIA_BUTTON.

Aby zadeklarować, które wejścia sterowania multimediami obsługuje Twój odtwarzacz, musisz wywołać setTransportControlFlags() w RemoteControlClient, przekazując zestaw flag FLAG_KEY_MEDIA_*, np. FLAG_KEY_MEDIA_PREVIOUS i FLAG_KEY_MEDIA_NEXT.

Następnie musisz zarejestrować dokument RemoteControlClient, przekazując go do MediaManager.registerRemoteControlClient(). Po zarejestrowaniu odbiornik transmisji zadeklarowany podczas tworzenia instancji RemoteControlClient będzie otrzymywać zdarzenia ACTION_MEDIA_BUTTON po naciśnięciu przycisku na pilocie. Otrzymywana intencja zawiera: KeyEvent dla naciśniętego klucza mediów, który można pobrać z intencji za pomocą getParcelableExtra(Intent.EXTRA_KEY_EVENT).

Aby na pilocie wyświetlać informacje o odtwarzanym multimediów, wywołaj funkcję editMetaData() i dodaj metadane do zwróconego elementu RemoteControlClient.MetadataEditor. Możesz dostarczyć bitmapę dla grafiki multimedialnej, informacje liczbowe, takie jak czas między zdarzeniami, oraz informacje tekstowe, takie jak tytuł utworu. Informacje o dostępnych kluczach znajdziesz w flagach METADATA_KEY_* w MediaMetadataRetriever.

Przykładową implementację znajdziesz w artykule Losowy odtwarzacz muzyki. Zawiera on funkcje zgodności, które umożliwiają działanie zdalnego sterowania na urządzeniach z Androidem 4.0 przy jednoczesnym dalszym obsłudze urządzeń z Androidem 2.1.

Odtwarzacze multimediów

  • Strumieniowe przesyłanie multimediów online z usługi MediaPlayer wymaga teraz uprawnienia INTERNET. Jeśli odtwarzasz treści z internetu za pomocą usługi MediaPlayer, dodaj do pliku manifestu uprawnienie INTERNET. W przeciwnym razie odtwarzanie multimediów nie będzie działać na Androidzie 4.0.
  • setSurface() umożliwia zdefiniowanie elementu Surface, który będzie działać jako ujście wideo.
  • setDataSource() umożliwia wysyłanie razem z żądaniem dodatkowych nagłówków HTTP, które mogą być przydatne w przypadku transmisji na żywo przez HTTP(S).
  • Transmisja na żywo przez HTTP(S) respektuje teraz pliki cookie HTTP w żądaniach

Typy multimediów

Android 4.0 obsługuje następujące funkcje:

  • Protokół transmisji na żywo HTTP/HTTPS w wersji 3
  • Kodowanie dźwięku ADTS AAC
  • Obrazy w WebP
  • Matroska – wideo

Więcej informacji znajdziesz w sekcji Obsługiwane formaty multimediów.

Aparat

Klasa Camera zawiera teraz interfejsy API do wykrywania twarzy oraz sterowania obszarem ostrości i pomiarem.

Wykrywanie twarzy

Aplikacje z aparatem mogą teraz zwiększyć swoje możliwości dzięki interfejsom API wykrywania twarzy na Androida, które wykrywają nie tylko twarz osoby, ale również jej określone cechy, np. oczy i usta.

Aby wykrywać twarze w aplikacji aparatu, musisz zarejestrować urządzenie Camera.FaceDetectionListener, dzwoniąc pod numer setFaceDetectionListener(). Następnie możesz uruchomić powierzchnię aparatu i zacząć wykrywać twarze, dzwoniąc pod numer startFaceDetection().

Gdy system wykryje co najmniej 1 twarz w scenie kamery, wywołuje wywołanie zwrotne onFaceDetection() w implementacji Camera.FaceDetectionListener, która obejmuje m.in. tablicę obiektów Camera.Face.

Wystąpienie klasy Camera.Face zawiera różne informacje o wykrytej twarzy, w tym:

  • Element Rect, który określa granice twarzy względem bieżącego pola widzenia kamery
  • Liczba całkowita z zakresu od 1 do 100, która wskazuje, z jaką pewnością system jest twarzą
  • Unikalny identyfikator umożliwiający śledzenie wielu twarzy
  • Kilka obiektów Point wskazujących, gdzie znajdują się oczy i usta

Uwaga: wykrywanie twarzy może nie być obsługiwane na niektórych urządzeniach, więc aby to sprawdzić, wywołaj funkcję getMaxNumDetectedFaces() i upewnij się, że zwracana wartość jest większa niż zero. Poza tym niektóre urządzenia mogą nie obsługiwać identyfikacji oczu i ust. W takim przypadku te pola w obiekcie Camera.Face będą miały wartość null.

Obszary docelowe i pomiarowe

Aplikacje aparatu mogą teraz kontrolować obszary używane przez aparat do ustawiania ostrości, pomiaru balansu bieli i automatycznej ekspozycji. Obie funkcje korzystają z nowej klasy Camera.Area do określania obszaru bieżącego widoku kamery, który powinien być ostrości lub pomiarem. Wystąpienie klasy Camera.Area określa granice obszaru za pomocą znacznika Rect i jego wagę za pomocą liczby całkowitej.

Przed ustawieniem obszaru ostrości lub pomiaru musisz najpierw wywołać metodę getMaxNumFocusAreas() lub getMaxNumMeteringAreas(). Jeśli te wartości zwracają wartość zero, urządzenie nie obsługuje odpowiedniej funkcji.

Aby określić, którego obszaru chcesz użyć, po prostu wywołaj setFocusAreas() lub setMeteringAreas(). Każdy z nich wybiera List z Camera.Area obiektów, które wskazują obszary wymagające ostrości lub pomiaru. Możesz np. zaimplementować funkcję, która umożliwia ustawianie obszaru ostrości przez dotknięcie obszaru podglądu, który można następnie przetłumaczyć na obiekt Camera.Area i poprosić aparat o ustawienie ostrości na tym obszarze. Ostrość lub ekspozycja w tym obszarze będą stale aktualizowane wraz ze zmianą sceny w danym obszarze.

Ciągły autofokus zdjęć

Podczas robienia zdjęć możesz teraz włączyć ciągłe automatyczne ustawianie ostrości (CAF). Aby włączyć CAF w aplikacji aparatu, przekaż kod FOCUS_MODE_CONTINUOUS_PICTURE do: setFocusMode(). Aby zrobić zdjęcie, zadzwoń pod numer autoFocus(). Camera.AutoFocusCallback natychmiast otrzymuje wywołanie zwrotne, które wskazuje, czy udało się osiągnąć cel. Aby wznowić CAF po otrzymaniu wywołania zwrotnego, musisz wywołać metodę cancelAutoFocus().

Uwaga: ciągły autofokus jest obsługiwany również podczas nagrywania filmu za pomocą funkcji FOCUS_MODE_CONTINUOUS_VIDEO, która została dodana do interfejsu API poziomu 9.

Inne funkcje aparatu

  • Podczas nagrywania filmu możesz teraz zadzwonić do: takePicture(), aby zapisać zdjęcie bez przerywania sesji wideo. Zanim to zrobisz, wywołaj metodę isVideoSnapshotSupported(), by mieć pewność, że sprzęt ją obsługuje.
  • Aby zapobiec zmianie tych właściwości, możesz teraz zablokować automatyczną ekspozycję i balans bieli za pomocą setAutoExposureLock() i setAutoWhiteBalanceLock().
  • Możesz teraz zadzwonić pod numer setDisplayOrientation(), gdy działa podgląd kamery. Wcześniej można było wywołać ją tylko przed wyświetleniem podglądu, ale teraz możesz w każdej chwili zmienić orientację.

Intencje dotyczące transmisji z kamery

  • Camera.ACTION_NEW_PICTURE: oznacza, że użytkownik zrobił nowe zdjęcie. Wbudowana aplikacja Aparat wywołuje tę transmisję po zrobieniu zdjęcia. Aplikacje aparatów innych firm również powinny rozgłaszać ten zamiar po zrobieniu zdjęcia.
  • Camera.ACTION_NEW_VIDEO: oznacza, że użytkownik nagrał nowy film. Wbudowana aplikacja Aparat wywołuje tę transmisję po nagraniu filmu. Aplikacje aparatów innych firm również powinny rozgłaszać ten zamiar po nagraniu filmu.

Android Beam (przesyłanie NDEF przez NFC)

Android Beam to nowa funkcja NFC, która umożliwia wysyłanie komunikatów NDEF z jednego urządzenia na drugie (proces ten nosi też nazwę „NDEF Push”). Przesyłanie danych rozpoczyna się, gdy 2 urządzenia z Androidem obsługujące Android Beam znajdują się w niewielkiej odległości (ok. 4 cm), zazwyczaj stykają się plecy. Dane w wiadomości NDEF mogą zawierać dowolne informacje, które chcesz udostępniać między urządzeniami. Na przykład aplikacja Osoby udostępnia kontakty, YouTube udostępnia filmy, a przeglądarka udostępnia adresy URL przy użyciu Android Beam.

Aby przesyłać dane między urządzeniami przy użyciu Android Beam, musisz utworzyć obiekt NdefMessage zawierający informacje, które chcesz udostępniać, gdy aktywność działa na pierwszym planie. Następnie musisz przekazać obiekt NdefMessage do systemu na jeden z dwóch sposobów:

  • Określ pojedynczą wartość NdefMessage do wypchnięcia w trakcie aktywności:

    Zadzwoń pod numer setNdefPushMessage() w dowolnym momencie, aby ustawić wiadomość, którą chcesz wysłać. Możesz na przykład wywołać tę metodę i przekazać ją jako NdefMessage podczas metody onCreate() aktywności. Od tego momentu, gdy Android Beam zostanie aktywowany przy użyciu innego urządzenia, gdy aktywność będzie widoczna na pierwszym planie, system wyśle do niego NdefMessage.

  • Określ NdefMessage do przeniesienia w momencie zainicjowania Android Beam:

    Wdróż NfcAdapter.CreateNdefMessageCallback, w którym implementacja metody createNdefMessage() zwraca wartość NdefMessage, którą chcesz wysłać. Następnie przekaż implementację NfcAdapter.CreateNdefMessageCallback do setNdefPushMessageCallback().

    W takim przypadku, gdy Android Beam zostanie aktywowany przy użyciu innego urządzenia, gdy Twoja aktywność będzie widoczna na pierwszym planie, system wywoła funkcję createNdefMessage(), by pobrać NdefMessage, które chcesz wysłać. Dzięki temu możesz zdefiniować, by wiadomość NdefMessage wyświetlała się dopiero po zainicjowaniu Android Beam, na wypadek, gdyby treść wiadomości mogła się zmieniać w trakcie działania.

Jeśli chcesz uruchomić określony kod po tym, jak system dostarczy wiadomość NDEF na inne urządzenie, możesz zaimplementować NfcAdapter.OnNdefPushCompleteCallback i ustawić go za pomocą setNdefPushCompleteCallback(). Po dostarczeniu wiadomości system wywoła metodę onNdefPushComplete().

Na urządzeniu odbierającym system wysyła komunikaty NDEF Push w podobny sposób jak zwykłe tagi NFC. System wywołuje intencję z działaniem ACTION_NDEF_DISCOVERED w celu uruchomienia działania. Może to być adres URL lub typ MIME ustawiony zgodnie z pierwszym działaniem NdefRecord w NdefMessage. W przypadku aktywności, na którą chcesz odpowiedzieć, możesz zadeklarować filtry intencji dla adresów URL lub typów MIME istotnych dla Twojej aplikacji. Więcej informacji o wysyłaniu tagów znajdziesz w przewodniku dla programistów NFC.

Jeśli chcesz, aby obiekt NdefMessage zawierał identyfikator URI, możesz użyć wygodnej metody createUri, aby utworzyć nowy obiekt NdefRecord na podstawie ciągu znaków lub obiektu Uri. Jeśli identyfikator URI ma specjalny format, który aplikacja ma również odbierać w trakcie zdarzenia Android Beam, utwórz filtr intencji dla działania, korzystając z tego samego schematu URI, co pozwoli odbierać przychodzące komunikaty NDEF.

Aby zagwarantować, że aplikacja obsługuje przychodzącą wiadomość NDEF, przekaż w interfejsie NdefMessage rekord aplikacji na Androida, nawet jeśli inne aplikacje odfiltrowują to samo działanie intencji. Rekord aplikacji na Androida możesz utworzyć, wywołując createApplicationRecord() i przekazując do niego nazwę pakietu aplikacji. Gdy drugie urządzenie odbiera komunikat NDEF z rekordem aplikacji, a wiele aplikacji zawiera działania obsługujące określone intencje, system zawsze dostarcza komunikat do działania w aplikacji (na podstawie pasującego rekordu aplikacji). Jeśli na urządzeniu docelowym nie jest zainstalowana Twoja aplikacja, system użyje rekordu aplikacji na Androida do uruchomienia Google Play i przeniesienia użytkownika do aplikacji w celu jej zainstalowania.

Jeśli aplikacja nie używa interfejsów API NFC do przesyłania komunikatów NDEF w trybie push, Android ma zachowanie domyślne: gdy aplikacja działa na pierwszym planie na jednym urządzeniu, a funkcja Android Beam zostaje wywołana z innego urządzenia z Androidem, drugie urządzenie otrzymuje komunikat NDEF z rekordem aplikacji na Androida identyfikującym aplikację. Jeśli na urządzeniu docelowym jest zainstalowana aplikacja, system ją uruchamia. Jeśli nie jest zainstalowana, Google Play otwiera aplikację i przenosi użytkownika do niej, by ją zainstalować.

Więcej informacji o Android Beam i innych funkcjach NFC znajdziesz w przewodniku dla programistów Podstawy komunikacji NFC. Przykładowy kod z użyciem Android Beam znajdziesz w prezentacji Android Beam.

Sieć Wi-Fi P2P

Android obsługuje teraz połączenia peer-to-peer (P2P) między urządzeniami z Androidem a innymi typami urządzeń (zgodnie z programem certyfikacji Wi-Fi DirectTM stowarzyszenia Wi-Fi Alliance) bez połączenia z internetem i hotspotem. Platforma Android udostępnia zestaw interfejsów API sieci Wi-Fi, które pozwalają wykrywać inne urządzenia i łączyć się z nimi, gdy każde z nich obsługuje Wi-Fi P2P, a następnie komunikować się przez szybkie łącze o dużej odległości niż w przypadku połączenia Bluetooth.

Nowy pakiet android.net.wifi.p2p zawiera wszystkie interfejsy API umożliwiające nawiązywanie połączeń peer-to-peer przez Wi-Fi. Podstawowe zajęcia, na których musisz pracować, to WifiP2pManager. Możesz je ukończyć, dzwoniąc pod numer getSystemService(WIFI_P2P_SERVICE). WifiP2pManager zawiera interfejsy API, które umożliwiają:

  • Zainicjuj aplikację do połączeń P2P, wywołując initialize()
  • Odkryj urządzenia w pobliżu, dzwoniąc pod numer discoverPeers()
  • Aby nawiązać połączenie P2P, zadzwoń pod numer connect()
  • oraz inne informacje.

Potrzebne są również dodatkowe interfejsy i klasy, na przykład:

  • Interfejs WifiP2pManager.ActionListener umożliwia odbieranie wywołań zwrotnych, gdy operacja, na przykład znalezienie sieci równorzędnych lub nawiązanie z nimi połączenia, zakończy się powodzeniem lub niepowodzeniem.
  • WifiP2pManager.PeerListListener umożliwia otrzymywanie informacji o wykrytych elementach równorzędnych. Wywołanie zwrotne udostępnia obiekt WifiP2pDeviceList, z którego możesz pobrać obiekt WifiP2pDevice dla każdego urządzenia w zasięgu i uzyskać takie informacje, jak nazwa, adres, typ urządzenia, obsługiwane konfiguracje WPS itp.
  • Interfejs WifiP2pManager.GroupInfoListener umożliwia otrzymywanie informacji o grupie P2P. Wywołanie zwrotne udostępnia obiekt WifiP2pGroup, który udostępnia informacje o grupie, takie jak właściciel, nazwa sieci i hasło.
  • Interfejs WifiP2pManager.ConnectionInfoListener umożliwia otrzymywanie informacji o bieżącym połączeniu. Wywołanie zwrotne udostępnia obiekt WifiP2pInfo z informacjami o tym, czy grupa została utworzona i kto jest jej właścicielem.

Aby korzystać z interfejsów Wi-Fi API P2P, aplikacja musi prosić użytkownika o następujące uprawnienia:

  • ACCESS_WIFI_STATE
  • CHANGE_WIFI_STATE
  • INTERNET (chociaż aplikacja nie łączy się technicznie z internetem, komunikowanie się z peerami P2P Wi-Fi za pomocą standardowych gniazd Java wymaga uprawnień internetowych).

System Android transmituje też kilka różnych działań podczas niektórych zdarzeń P2P w sieci Wi-Fi:

Więcej informacji znajdziesz w dokumentacji WifiP2pManager. Zobacz też przykładową aplikację Wi-Fi P2P Demo.

Urządzenia Bluetooth Health

Android obsługuje teraz urządzenia Bluetooth Health Profile, dzięki czemu możesz tworzyć aplikacje, które przez Bluetooth komunikują się z urządzeniami obsługującymi tę funkcję, takimi jak pulsometr, mierniki krwi, termometry i wagi.

Podobnie jak w przypadku zwykłych zestawów słuchawkowych i urządzeń z profilem A2DP, aby nawiązać połączenie z obiektem profilu serwera proxy, musisz wywołać getProfileProxy() za pomocą profilu BluetoothProfile.ServiceListener i HEALTH.

Po pozyskaniu serwera proxy profilu zdrowia (obiektu BluetoothHealth) do łączenia się ze sparowanymi urządzeniami zdrowotnymi i komunikacji z nimi można używać tych nowych klas Bluetooth:

  • BluetoothHealthCallback: aby otrzymywać aktualne informacje o zmianach stanu rejestracji aplikacji i kanału Bluetooth, musisz rozszerzyć tę klasę i zaimplementować metody wywołania zwrotnego.
  • BluetoothHealthAppConfiguration: w trakcie wywołań zwrotnych do BluetoothHealthCallback otrzymasz instancję tego obiektu, która podaje informacje o konfiguracji dostępnego urządzenia Bluetooth do zarządzania stanem danych. Czynności te są wymagane do wykonywania różnych operacji, takich jak inicjowanie i kończenie połączeń z interfejsami API BluetoothHealth.

Więcej informacji o korzystaniu z profilu stanu Bluetooth znajdziesz w dokumentacji urządzenia BluetoothHealth.

Ułatwienia dostępu

Android 4.0 ułatwia dostęp dla użytkowników z wadami wzroku dzięki nowemu trybowi Czytanie po dotknięciu i rozszerzonym interfejsom API, które pozwalają podać więcej informacji o oglądaniu materiałów lub rozwijać zaawansowane usługi ułatwień dostępu.

Tryb czytania po dotknięciu

Użytkownicy z wadą wzroku mogą teraz przeglądać ekran, dotykając i przeciągając palcem po nim, aby usłyszeć głosowe opisy treści. Tryb czytania dotykiem działa jak wirtualny kursor, więc umożliwia czytnikom ekranu identyfikowanie tekstu opisowego w taki sam sposób, w jaki czytniki ekranu korzystają z pada kierunkowego lub kulki. Odczytują one informacje dostarczone przez android:contentDescription i setContentDescription() po symulowanym zdarzeniu „najechania”. Pamiętaj więc, aby dodać opisowy tekst dotyczący widoków w aplikacji, zwłaszcza ImageButton, EditText i ImageView oraz w innych widżetach, które nie zawsze zawierają opis.

Ułatwienia dostępu w widokach

Aby wzbogacić informacje dostępne dla usług ułatwień dostępu, takich jak czytniki ekranu, możesz zaimplementować w niestandardowych komponentach View nowe metody wywołań zwrotnych zdarzeń związanych z ułatwieniami dostępu.

Pamiętaj, że w Androidzie 4.0 działanie metody sendAccessibilityEvent() uległo zmianie. Tak jak w poprzedniej wersji Androida, gdy użytkownik włączy na urządzeniu usługi ułatwień dostępu i zostanie zarejestrowane zdarzenie wejściowe, takie jak kliknięcie lub najechanie kursorem, odpowiedni widok zostanie powiadomiony z wywołaniem sendAccessibilityEvent(). Wcześniej wdrożenie sendAccessibilityEvent() inicjowało obiekt AccessibilityEvent i wysyłał go do AccessibilityManager. Nowe zachowanie obejmuje dodatkowe metody wywołania zwrotnego, które umożliwiają widokowi i jego elementom nadrzędnym dodanie do zdarzenia dodatkowych informacji kontekstowych:

  1. Po wywołaniu metody sendAccessibilityEvent() i sendAccessibilityEventUnchecked() używają metody onInitializeAccessibilityEvent().

    W niestandardowych implementacjach View warto zaimplementować metodę onInitializeAccessibilityEvent(), aby dołączyć dodatkowe informacje o ułatwieniach dostępu do obiektu AccessibilityEvent, ale też wywołać superimplementację w celu przekazania informacji domyślnych, takich jak standardowy opis treści czy indeks elementu. Nie należy jednak dodawać dodatkowego tekstu w wywołaniu zwrotnym, ponieważ ma to miejsce w następnej kolejności.

  2. Jeśli to zdarzenie należy do jednego z kilku typów, które po zainicjowaniu należy wypełnić informacjami tekstowymi, widok otrzyma wywołanie dispatchPopulateAccessibilityEvent(), które zwrócą uwagę na wywołanie zwrotne onPopulateAccessibilityEvent().

    Niestandardowe implementacje View powinny zwykle implementować tag onPopulateAccessibilityEvent(), aby dodać dodatkową treść tekstową do elementu AccessibilityEvent, jeśli brakuje tekstu android:contentDescription lub jest on niewystarczający. Aby dodać więcej tekstu do elementu AccessibilityEvent, zadzwoń pod numer getText().add().

  3. W tym momencie obiekt View przekazuje zdarzenie wyżej w hierarchii widoków, wywołując metodę requestSendAccessibilityEvent() w widoku nadrzędnym. Każdy widok nadrzędny może uzupełnić informacje o ułatwieniach dostępu, dodając element AccessibilityRecord, aż osiągnie widok główny, który wysyła zdarzenie do interfejsu AccessibilityManager za pomocą atrybutu sendAccessibilityEvent().

Oprócz nowych metod opisanych powyżej, które są przydatne przy rozszerzaniu klasy View, możesz też przechwytywać te wywołania zwrotne zdarzenia w dowolnym elemencie View, stosując rozszerzenie AccessibilityDelegate i ustawiając go w widoku danych za pomocą właściwości setAccessibilityDelegate(). Gdy to zrobisz, każda metoda ułatwień dostępu w widoku będzie odkładać wywołanie do odpowiedniej metody w obiekcie delegata. Jeśli np. widok otrzyma wywołanie onPopulateAccessibilityEvent(), przekazuje je do tej samej metody w elemencie View.AccessibilityDelegate. Wszystkie metody, których nie obsługuje osoba, której przekazano dostęp, są przywracane do widoku i wykonywane domyślnie. Dzięki temu możesz zastąpić tylko metody niezbędne dla danego widoku bez rozszerzania klasy View.

Jeśli chcesz zachować zgodność z wersjami Androida starszymi niż 4.0, a jednocześnie obsługiwać nowe interfejsy API ułatwień dostępu, możesz to zrobić za pomocą najnowszej biblioteki pomocy dotyczącej wersji 4 (w pakiecie zgodności, r4) przy użyciu zestawu klas narzędzi, które udostępniają nowe interfejsy API ułatwień dostępu w zgodnym wstecznie projekcie.

Usługi ułatwień dostępu

Jeśli tworzysz usługę ułatwień dostępu, informacje o różnych zdarzeniach związanych z ułatwieniami dostępu są znacznie rozszerzone, by umożliwić użytkownikom bardziej zaawansowane przekazywanie opinii. Zdarzenia są generowane na podstawie struktury widoku, co zapewnia lepszy kontekst i umożliwia usługom ułatwień dostępu przeglądanie hierarchii widoków w celu uzyskania dodatkowych informacji o widoku i okazywania szczególnych przypadków.

Jeśli opracowujesz usługę ułatwień dostępu (np. czytnik ekranu), możesz uzyskać dostęp do dodatkowych informacji o treści i przeglądać hierarchie widoków, korzystając z tej procedury:

  1. Po otrzymaniu od aplikacji polecenia AccessibilityEvent wywołaj AccessibilityEvent.getRecord(), aby pobrać określony AccessibilityRecord (do zdarzenia może być podłączonych kilka rekordów).
  2. Z AccessibilityEvent lub z pojedynczego AccessibilityRecord możesz wywołać getSource(), aby pobrać obiekt AccessibilityNodeInfo.

    AccessibilityNodeInfo reprezentuje pojedynczy węzeł z zawartością okna w formacie, który umożliwia wysyłanie do niego zapytań o ułatwienia dostępu. Obiekt AccessibilityNodeInfo zwrócony z metody AccessibilityEvent opisuje źródło zdarzenia, a źródło z elementu AccessibilityRecord opisuje jego poprzednika.

  3. Dzięki AccessibilityNodeInfo możesz uzyskiwać informacje na jego temat, wywoływać metodę getParent() lub getChild(), aby przeglądać hierarchię widoków danych, a nawet dodawać do węzła widoki podrzędne.

Aby aplikacja mogła opublikować się w systemie jako usługa ułatwień dostępu, musi zadeklarować plik konfiguracji XML odpowiadający atrybutowi AccessibilityServiceInfo. Więcej informacji o tworzeniu usługi ułatwień dostępu znajdziesz w sekcjach AccessibilityService i SERVICE_META_DATA, w których znajdziesz informacje o konfiguracji XML.

Inne interfejsy API ułatwień dostępu

Jeśli chcesz poznać stan ułatwień dostępu urządzenia, AccessibilityManager ma kilka nowych interfejsów API, takich jak:

Usługi sprawdzania pisowni

Nowa platforma sprawdzania pisowni umożliwia aplikacjom tworzenie modułów sprawdzania pisowni w sposób podobny do metody wprowadzania (IME). Aby utworzyć nowy moduł sprawdzania pisowni, musisz wdrożyć usługę, która rozszerza klasę SpellCheckerService i rozszerza klasę SpellCheckerService.Session o sugestie pisowni na podstawie tekstu dostarczanego przez metody wywołania zwrotnego interfejsu. W metodach wywołań zwrotnych SpellCheckerService.Session musisz zwracać sugestie pisowni jako obiekty SuggestionsInfo.

Aplikacje z usługą sprawdzania pisowni muszą zadeklarować uprawnienie BIND_TEXT_SERVICE zgodnie z wymaganiami tej usługi. Usługa musi też zadeklarować filtr intencji z <action android:name="android.service.textservice.SpellCheckerService" /> jako działanie intencji i powinna zawierać element <meta-data>, który deklaruje informacje o konfiguracji na potrzeby sprawdzania pisowni.

Przykładowe fragmenty kodu znajdziesz w przykładowej aplikacji Usługa sprawdzania pisowni i Klienta sprawdzania pisowni.

Mechanizmy zamiany tekstu na mowę

Interfejsy API zamiany tekstu na mowę (TTS) Androida zostały znacznie rozszerzone, aby ułatwić aplikacjom wdrożenie niestandardowych silników zamiany tekstu na mowę. Aplikacje, które chcą korzystać z mechanizmu przetwarzania tekstu na mowę, mają kilka nowych interfejsów API do wyboru silnika.

Korzystanie z mechanizmów zamiany tekstu na mowę

W poprzednich wersjach Androida można było używać klasy TextToSpeech do wykonywania operacji zamiany tekstu na mowę (TTS) za pomocą udostępnianego przez system mechanizmu zamiany tekstu na mowę lub konfigurować silnik niestandardowy za pomocą setEngineByPackageName(). W Androidzie 4.0 metoda setEngineByPackageName() została wycofana i możesz teraz wskazać wyszukiwarkę do użycia z nowym konstruktorem TextToSpeech, który akceptuje nazwę pakietu mechanizmu przekształcania tekstu na mowę.

Możesz też wysyłać zapytania o dostępne silniki zamiany tekstu na mowę za pomocą getEngines(). Ta metoda zwraca listę obiektów TextToSpeech.EngineInfo, które zawierają metadane, takie jak ikona, etykieta i nazwa pakietu wyszukiwarki.

Tworzenie silników zamiany tekstu na mowę

Wcześniej wyszukiwarki niestandardowe wymagały, by wyszukiwarka była tworzona przy użyciu nieudokumentowanego natywnego pliku nagłówka. Android 4.0 udostępnia kompletny zestaw podstawowych interfejsów API do tworzenia silników zamiany tekstu na mowę.

Konfiguracja podstawowa wymaga implementacji TextToSpeechService odpowiadającej intencji INTENT_ACTION_TTS_SERVICE. Mechanizm działania mechanizmu TTS ma miejsce podczas wywołania zwrotnego onSynthesizeText() w usłudze rozszerzającej zakres TextToSpeechService. System dostarcza tę metodę 2 obiekty:

  • SynthesisRequest: zawiera różne dane, w tym tekst do syntezy, język, szybkość mowy i ton głosu.
  • SynthesisCallback: to interfejs, za pomocą którego mechanizm przetwarzania tekstu na mowę dostarcza wynikowe dane dotyczące mowy jako strumieniowy dźwięk. Najpierw silnik musi wywołać metodę start(), by wskazać, że jest gotowy do odtwarzania dźwięku, a potem wywołać metodę audioAvailable(), przesyłając dane audio w buforze bajtów. Gdy silnik przekaże cały dźwięk przez bufor, wywołaj done().

Platforma obsługuje już prawdziwy interfejs API do tworzenia silników zamiany tekstu na mowę, więc wycofaliśmy obsługę implementacji kodu natywnego. Poszukaj posta na blogu na temat warstwy zgodności, której możesz użyć do konwertowania starych mechanizmów przetwarzania tekstu na mowę do nowej platformy.

Przykładowy mechanizm zamiany tekstu na mowę korzystający z nowych interfejsów API znajdziesz w przykładowej aplikacji Text to Speech Engine.

Wykorzystanie sieci

Android 4.0 zapewnia użytkownikom dokładne informacje o ilości danych przesyłanych przez aplikacje. Aplikacja Ustawienia zawiera elementy sterujące, które pozwalają użytkownikom zarządzać limitami korzystania z danych w sieci, a nawet wyłączają użycie danych w tle przez poszczególne aplikacje. Aby uniknąć wyłączenia przez użytkowników dostępu aplikacji do danych w tle, musisz opracować strategie efektywnego wykorzystania połączenia danych i dostosować wykorzystanie w zależności od typu dostępnego połączenia.

Jeśli aplikacja umożliwia wykonywanie wielu transakcji sieciowych, należy udostępnić ustawienia użytkownika, które pozwolą użytkownikom kontrolować nawyki związane z danymi. Mogą na przykład określić, jak często aplikacja synchronizuje dane, czy ma przesyłać/pobierać dane tylko przez Wi-Fi, czy używać transmisji danych podczas korzystania z roamingu, itp. Mając do nich dostęp, użytkownicy z większym prawdopodobieństwem wyłączą dostęp aplikacji do danych, kiedy zbliżą się do swojego limitu, ponieważ będą mogli precyzyjnie kontrolować, jaka ilość danych zbliży się do limitu. Jeśli określisz działanie związane z preferencjami dla tych ustawień, w deklaracji w pliku manifestu uwzględnij filtr intencji dla działania ACTION_MANAGE_NETWORK_USAGE. Na przykład:

<activity android:name="DataPreferences" android:label="@string/title_preferences">
    <intent-filter>
       <action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
       <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Ten filtr intencji informuje system, że to właśnie ona kontroluje użycie danych przez aplikację. Dzięki temu, gdy użytkownik sprawdzi w aplikacji Ustawienia, ile danych wykorzystuje aplikacja, pojawi się przycisk „Wyświetl ustawienia aplikacji”, który uruchamia działanie ustawienia. Dzięki temu użytkownik może określić, ile danych zużywa aplikacja.

Pamiętaj też, że funkcja getBackgroundDataSetting() jest teraz wycofana i zawsze zwraca wartość prawda – zamiast niej użyj parametru getActiveNetworkInfo(). Zanim spróbujesz jakiekolwiek transakcje sieciowe, musisz zawsze wywołać metodę getActiveNetworkInfo(), by uzyskać NetworkInfo reprezentujący bieżącą sieć, i zapytać isConnected(), by sprawdzić, czy urządzenie ma połączenie. Następnie możesz sprawdzić inne właściwości połączenia, takie jak to, czy urządzenie jest w roamingu lub czy jest połączone z Wi-Fi.

Firma

Android 4.0 rozszerza możliwości aplikacji biznesowych o następujące funkcje.

Usługi VPN

Nowy VpnService pozwala aplikacjom na tworzenie własnych sieci VPN (wirtualnej sieci prywatnej) działającej jako Service. Usługa VPN tworzy interfejs sieci wirtualnej z własnymi regułami adresu i routingu oraz wykonuje wszystkie odczyty i zapisy za pomocą deskryptora plików.

Aby utworzyć usługę VPN, użyj polecenia VpnService.Builder, które pozwala określić m.in. adres sieciowy, serwer DNS i trasę sieci. Po zakończeniu możesz utworzyć interfejs, wywołując metodę establish(), która zwraca błąd ParcelFileDescriptor.

Usługa VPN może przechwytywać pakiety, co wpływa na bezpieczeństwo. Jeśli więc wdrożysz VpnService, Twoja usługa musi wymagać uprawnienia BIND_VPN_SERVICE, aby mieć pewność, że tylko system może się z nim powiązać (tylko system otrzymał to uprawnienie – aplikacje nie mogą o niego poprosić). Aby korzystać z Twojej usługi VPN, użytkownicy muszą ręcznie włączyć ją w ustawieniach systemu.

Zasady dotyczące urządzeń

Aplikacje do zarządzania ograniczeniami urządzeń mogą teraz wyłączać kamerę za pomocą właściwości setCameraDisabled() i USES_POLICY_DISABLE_CAMERA (stosowanej z elementem <disable-camera /> w pliku konfiguracji zasad).

Zarządzanie certyfikatami

Nowa klasa KeyChain udostępnia interfejsy API, które umożliwiają importowanie certyfikatów i dostęp do nich w magazynie kluczy systemowych. Certyfikaty upraszczają instalację zarówno certyfikatów klienta (w celu weryfikacji tożsamości użytkownika), jak i certyfikatów urzędów certyfikacji (do weryfikacji tożsamości serwera). Aplikacje, takie jak przeglądarki i klienty poczty e-mail, mogą uzyskiwać dostęp do zainstalowanych certyfikatów w celu uwierzytelniania użytkowników na serwerach. Więcej informacji znajdziesz w dokumentacji KeyChain.

Czujniki urządzenia

W Androidzie 4.0 dodaliśmy dwa nowe typy czujników:

  • TYPE_AMBIENT_TEMPERATURE: czujnik temperatury, który przekazuje temperaturę otoczenia (pokojową) w stopniach Celsjusza.
  • TYPE_RELATIVE_HUMIDITY: czujnik wilgotności, który określa względną wilgotność otoczenia (w pomieszczeniu) wyrażoną w procentach.

Jeśli urządzenie ma zarówno czujniki TYPE_AMBIENT_TEMPERATURE, jak i TYPE_RELATIVE_HUMIDITY, możesz ich używać do obliczania punktu rosy i wilgotności bezwzględnej.

Poprzedni czujnik temperatury, TYPE_TEMPERATURE, został wycofany. Należy zamiast tego użyć czujnika TYPE_AMBIENT_TEMPERATURE.

Poza tym 3 syntetyczne czujniki w Androidzie zostały znaczne udoskonalone, dzięki czemu mają teraz mniejsze opóźnienie i płynniejsze działanie. Są to czujniki grawitacji (TYPE_GRAVITY), czujnika wektorowego ruchu obrotowego (TYPE_ROTATION_VECTOR) i czujnika przyspieszenia liniowego (TYPE_LINEAR_ACCELERATION). Ulepszone czujniki wykorzystują czujniki żyroskopu, aby zwiększyć dokładność pomiarów, więc są one widoczne tylko w urządzeniach z żyroskopem.

Pasek działań

Zaktualizowano ActionBar, aby umożliwić obsługę kilku nowych zachowań. Co najważniejsze, system płynnie zarządza rozmiarem i konfiguracją paska działań działającym na mniejszych ekranach, zapewniając użytkownikom optymalny komfort na każdym ekranie. Na przykład, gdy ekran jest wąski (np. telefon jest w orientacji pionowej), karty nawigacyjne na pasku działań są wyświetlane na „pasku skumulowanym” bezpośrednio pod głównym paskiem działań. Możesz też włączyć „podzielony pasek działań”, który na wąskim ekranie umieszcza wszystkie działania na oddzielnym pasku u dołu ekranu.

Podział paska działań

Jeśli pasek działań zawiera kilka działań, niektóre z nich mogą nie zmieścić się na wąskim ekranie, dlatego system doda ich więcej do rozszerzonego menu. Android 4.0 umożliwia jednak włączenie „podzielonego paska działań”, dzięki czemu na ekranie będzie pojawiać się więcej działań na osobnym pasku u dołu ekranu. Aby włączyć podzielony pasek działań, dodaj android:uiOptions z "splitActionBarWhenNarrow" do tagu <application> lub poszczególnych tagów <activity> w pliku manifestu. Po włączeniu tej opcji na wąskim ekranie system doda dodatkowy pasek na wszystkie działania (na pasku głównych działań nie pojawią się żadne działania).

Jeśli chcesz korzystać z kart nawigacyjnych udostępnianych przez interfejsy API ActionBar.Tab, ale nie potrzebujesz głównego paska działań u góry (chcesz wyświetlać tylko karty u góry), włącz podzielony pasek działań w sposób opisany powyżej i wywołaj setDisplayShowHomeEnabled(false), aby wyłączyć ikonę aplikacji na pasku działań. Na głównym pasku działań nie zostało już nic i znikniesz. Pozostało tylko karty nawigacyjne u góry i działania na dole ekranu.

Style paska działań

Jeśli chcesz zastosować styl niestandardowy do paska działań, możesz użyć nowych właściwości stylu backgroundStacked i backgroundSplit, aby zastosować styl rysowany w tle lub kolor odpowiednio do paska skumulowanego i podzielonego paska. Te style można też ustawić w czasie działania za pomocą setStackedBackgroundDrawable() i setSplitBackgroundDrawable().

Dostawca działania

Nowa klasa ActionProvider umożliwia utworzenie specjalistycznego modułu obsługi elementów działań. Dostawca działań może zdefiniować widok działania, domyślne zachowanie działania oraz menu podrzędne dla każdego działania, z którym jest ono powiązane. Jeśli chcesz utworzyć działanie, które charakteryzuje się dynamicznymi zachowaniami (takimi jak zmienny widok działania, działanie domyślne lub menu podrzędne), dobrym rozwiązaniem jest rozszerzenie ActionProvider, które pozwala utworzyć komponent wielokrotnego użytku zamiast obsługi różnych przekształceń elementów działania we fragmencie lub aktywności.

Na przykład ShareActionProvider jest rozszerzeniem ActionProvider, które umożliwia udostępnianie akcji na pasku działań. Zamiast tradycyjnego działania, które wywołuje intencję ACTION_SEND, możesz użyć tego dostawcy działań, aby wyświetlić widok działania z listą aplikacji, które obsługują intencję ACTION_SEND. Gdy użytkownik wybiera aplikację, której ma używać działanie, ShareActionProvider pamięta ten wybór i udostępnia ją w widoku działania, aby umożliwić szybszy dostęp do udostępniania tej aplikacji.

Aby zadeklarować dostawcę działania dla danego działania, podaj atrybut android:actionProviderClass w elemencie <item> w menu opcji aktywności, podając nazwę klasy dostawcy jako wartość. Na przykład:

<item android:id="@+id/menu_share"
      android:title="Share"
      android:showAsAction="ifRoom"
      android:actionProviderClass="android.widget.ShareActionProvider" />

W metodzie wywołania zwrotnego onCreateOptionsMenu() Twojej aktywności pobierz instancję dostawcy działania z pozycji menu i ustaw zamiar:

Kotlin

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.options, menu)
    val shareActionProvider = menu.findItem(R.id.menu_share)?.actionProvider as? ShareActionProvider
    // Set the share intent of the share action provider.
    shareActionProvider?.setShareIntent(createShareIntent())
    ...
    return super.onCreateOptionsMenu(menu)
}

Java

public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.options, menu);
    ShareActionProvider shareActionProvider =
          (ShareActionProvider) menu.findItem(R.id.menu_share).getActionProvider();
    // Set the share intent of the share action provider.
    shareActionProvider.setShareIntent(createShareIntent());
    ...
    return super.onCreateOptionsMenu(menu);
}

Przykład użycia dyrektywy ShareActionProvider znajdziesz w sekcji ActionBarShareActionProviderActivity w ApiDemos.

Zwijane widoki działań

Działania, które udostępniają widok, mogą się teraz przełączać między stanem widoku działania a stanem standardowego działania. Wcześniej tylko SearchView obsługiwał zwijanie, gdy był używany jako widok działań. Teraz możesz dodać widok działania dla dowolnego działania i przełączać się między stanem rozwiniętym (widok czynności) a zwiniętym (element działania jest widoczny).

Aby zadeklarować, że działanie zawierające widok działania jest zwijane, umieść flagę “collapseActionView" w atrybucie android:showAsAction elementu <item> w pliku XML menu.

Aby otrzymywać wywołania zwrotne, gdy widok działań przełącza się między rozwiniętym a zwiniętym, zarejestruj wystąpienie elementu MenuItem.OnActionExpandListener z odpowiednią wartością MenuItem, wywołując metodę setOnActionExpandListener(). Zwykle należy to zrobić podczas wywołania zwrotnego onCreateOptionsMenu().

Aby sterować widokiem działań zwijanych, możesz wywoływać metody collapseActionView() i expandActionView() w odpowiednich parametrach MenuItem.

Tworząc widok działań niestandardowych, możesz też wdrożyć nowy interfejs CollapsibleActionView, by otrzymywać wywołania zwrotne, gdy widok jest rozwinięty lub zwinięty.

Inne interfejsy API paska działań

  • setHomeButtonEnabled() pozwala określić, czy ikona/logo ma służyć jako przycisk do nawigacji na stronę główną czy jako przycisk „w górę” (użyj wartości „true”, by pełnić rolę przycisku).
  • Zmienne setIcon() i setLogo() umożliwiają definiowanie ikony lub logo na pasku działań w czasie działania.
  • Fragment.setMenuVisibility() umożliwia włączenie lub wyłączenie widoczności opcji menu opcji zadeklarowanych przez fragment. Jest to przydatne, jeśli fragment został dodany do działania, ale nie jest widoczny, dlatego pozycje menu powinny być ukryte.
  • FragmentManager.invalidateOptionsMenu() umożliwia unieważnienie menu opcji aktywności w różnych stanach cyklu życia fragmentu, w których użycie równoważnej metody z Activity może być niedostępne.

Interfejs użytkownika i widoki

W Androidzie 4.0 pojawiły się różne nowe widoki i inne komponenty interfejsu.

Układ siatki

GridLayout to nowa grupa widoków, która umieszcza widoki podrzędne w prostokątnej siatce. W przeciwieństwie do TableLayout tabela GridLayout opiera się na płaskiej hierarchii i nie korzysta z widoków pośrednich, takich jak wiersze tabeli, do określania struktury. Zamiast tego elementy podrzędne określają, które wiersze i kolumny powinny się znajdować (komórki mogą obejmować wiele wierszy lub kolumn). Domyślnie elementy podrzędne są układane po kolei w wierszach i kolumnach siatki. Orientacja GridLayout określa, czy sekwencyjne elementy podrzędne są domyślnie rozmieszczone poziomo czy pionowo. Odstęp między elementami podrzędnymi możesz określić za pomocą wystąpień nowego widoku Space lub za pomocą odpowiednich parametrów marginesów w elementach podrzędnych.

Przykłady użycia GridLayout znajdziesz w sekcji ApiDemos.

Widok tekstury

TextureView to nowy widok, który umożliwia wyświetlanie strumienia treści, np. filmu lub sceny OpenGL. Mimo że TextureView jest podobny do SurfaceView, TextureView wyróżnia się tym, że zachowuje się jak zwykły widok – nie tworzy osobnego okna, więc możesz go traktować jak każdy inny obiekt View. Możesz na przykład zastosować przekształcenia, animować je za pomocą funkcji ViewPropertyAnimator lub dostosować jej przezroczystość za pomocą funkcji setAlpha().

Pamiętaj, że TextureView działa tylko w okresie z akceleracją sprzętową.

Więcej informacji znajdziesz w dokumentacji TextureView.

Przełącz widżet

Nowy widżet Switch to przełącznik dwustanowy, który użytkownicy mogą przeciągać w jedną lub na drugą stronę (albo po prostu kliknąć), aby przełączać się między 2 stanami.

Za pomocą atrybutów android:textOn i android:textOff możesz określić tekst, który będzie widoczny na przełączniku, gdy jest on włączony lub wyłączony. Atrybut android:text umożliwia też umieszczenie etykiety obok przełącznika.

Przykładowy przykład korzystania z przełączników znajdziesz w pliku układu switches.xml i odpowiedniej aktywności Switches .

W Androidzie 3.0 wprowadzono funkcję PopupMenu, która umożliwia tworzenie krótkich menu kontekstowych, które wyświetlają się w określonym przez Ciebie punkcie zakotwiczenia (zwykle w miejscu wybranego elementu). Android 4.0 rozszerza PopupMenu o kilka przydatnych funkcji:

  • Możesz teraz łatwo powiększać zawartość wyskakującego menu z zasobu menu XML za pomocą inflate(), przekazując do niego identyfikator zasobu menu.
  • Możesz też utworzyć PopupMenu.OnDismissListener, który będzie otrzymywać wywołanie zwrotne po zamknięciu menu.

Ustawienia

Nowa klasa abstrakcyjna TwoStatePreference jest podstawą preferencji, które udostępniają opcję wyboru 2 stanów. Nowy SwitchPreference to rozszerzenie TwoStatePreference, które udostępnia widżet Switch w widoku ustawień, umożliwiając użytkownikom włączanie i wyłączanie ustawienia bez konieczności otwierania dodatkowego ekranu lub okna ustawień. Na przykład aplikacja Ustawienia używa urządzenia SwitchPreference do obsługi ustawień Wi-Fi i Bluetootha.

Motywy systemowe

Domyślnym motywem dla wszystkich aplikacji kierowanych na Androida 4.0 (po ustawieniu w targetSdkVersion lub minSdkVersion wartości “14" lub nowszej) jest teraz motyw „domyślne źródło urządzenia”: Theme.DeviceDefault. Może to być ciemny motyw Holo lub inny ciemny motyw zdefiniowany przez konkretne urządzenie.

Motywy z rodziny Theme.Holo na pewno nie będą się zmieniać między urządzeniami, jeśli korzystasz z tej samej wersji Androida. Jeśli wyraźnie zastosujesz do aktywności dowolny z motywów Theme.Holo, możesz mieć pewność, że nie zmienią się one postaci na różnych urządzeniach w ramach tej samej wersji platformy.

Jeśli chcesz, aby aplikacja pasowała do ogólnego motywu urządzenia (np. gdy różni producenci OEM dostarczają różne domyślne motywy dla systemu), musisz wyraźnie zastosować motywy z rodziny Theme.DeviceDefault.

Przycisk menu opcji

Począwszy od systemu Android 4.0 będzie można zauważyć, że w telefonach nie jest już wymagany przycisk sprzętowy menu. Nie musisz się tym jednak przejmować, jeśli w istniejącej aplikacji masz dostępne menu opcji i spodziewasz się przycisku Menu. Aby upewnić się, że istniejące aplikacje działają zgodnie z oczekiwaniami, system udostępnia przycisk menu ekranowego w przypadku aplikacji, które zostały zaprojektowane z myślą o starszych wersjach Androida.

Aby zadbać o wygodę użytkowników, nowe i zaktualizowane aplikacje powinny zamiast tego używać interfejsu ActionBar, aby umożliwiać dostęp do pozycji menu, i ustawiać targetSdkVersion na "14". Pozwoli to korzystać z najnowszych domyślnych działań platformy.

Elementy sterujące widocznością interfejsu systemu

Od początku korzystania z Androida system zarządzał komponentem interfejsu znanym jako pasek stanu, który znajduje się u góry telefonów i przekazuje informacje takie jak sygnał operatora, godzina, powiadomienia itd. W Androidzie 3.0 dodaliśmy pasek systemowy dla tabletów, który znajduje się u dołu ekranu i zawiera elementy sterujące nawigacją (Ekran główny, Wstecz itd.) oraz interfejs elementów, które zwykle pojawiają się na pasku stanu. W Androidzie 4.0 system ten udostępnia nowy typ interfejsu użytkownika – pasek nawigacyjny. Pasek nawigacyjny można uznać za dostrojoną wersję paska systemowego, zaprojektowany z myślą o słuchawkach – zawiera elementy sterujące nawigacją dla urządzeń, które nie mają sprzętowych odpowiedników do nawigacji, ale nie zawiera interfejsu powiadomień i ustawień na pasku systemowym. Dlatego też urządzenie z paskiem nawigacyjnym ma również pasek stanu u góry.

Obecnie można ukryć pasek stanu telefonów za pomocą flagi FLAG_FULLSCREEN. W Androidzie 4.0 interfejsy API sterujące widocznością paska systemu zostały zaktualizowane, by lepiej odzwierciedlały jego działanie:

  • Flaga SYSTEM_UI_FLAG_LOW_PROFILE zastępuje flagę STATUS_BAR_HIDDEN. Po ustawieniu ta flaga włącza tryb „niskiego profilu” na pasku systemowym lub pasku nawigacyjnym. Przyciski nawigacyjne są przyciemnione, a inne elementy na pasku systemowym również są ukryte. Po włączeniu tej opcji możesz tworzyć bardziej wciągające gry, nie rozpraszając uwagi przycisków nawigacyjnych w systemie.
  • Flaga SYSTEM_UI_FLAG_VISIBLE zastępuje flagę STATUS_BAR_VISIBLE, żądając, aby pasek systemu lub pasek nawigacyjny były widoczne.
  • SYSTEM_UI_FLAG_HIDE_NAVIGATION to nowa flaga, która prosi o całkowite ukrycie paska nawigacyjnego. Pamiętaj, że działa to tylko w przypadku paska nawigacyjnego używanego w niektórych telefonach (nie ukrywa paska systemowego na tabletach). Pasek nawigacyjny wraca do widoku, gdy tylko system otrzyma dane wejściowe od użytkownika. Ten tryb przydaje się przede wszystkim podczas odtwarzania filmów i w innych sytuacjach, w których potrzebny jest cały ekran, ale nie wymaga wprowadzania danych przez użytkownika.

Każdą z tych flag możesz ustawić na pasku systemu i na pasku nawigacyjnym, wywołując setSystemUiVisibility() w dowolnym widoku aktywności. Menedżer okien łączy (LUB) wszystkie flagi ze wszystkich widoków w oknie i stosuje je w interfejsie systemu, o ile tylko okno jest zaznaczone. Gdy okno przestanie działać (użytkownik wychodzi z aplikacji lub pojawi się okno), flagi przestają działać. Podobnie, jeśli usuniesz te widoki z hierarchii widoków, ich flagi przestaną być stosowane.

Aby synchronizować inne zdarzenia w aktywności ze zmianami widoczności w interfejsie systemu (np. ukryć pasek działań lub inne elementy interfejsu, gdy interfejs systemu się ukryje), zarejestruj View.OnSystemUiVisibilityChangeListener, aby otrzymywać powiadomienia o zmianie widoczności paska systemowego lub paska nawigacyjnego.

W klasie OverscanActivity znajdziesz prezentację różnych opcji interfejsu systemu.

Struktura wprowadzania

Android 4.0 obsługuje zdarzenia po najechaniu kursorem oraz nowe zdarzenia związane z rysikiem i przyciskiem myszy.

Zdarzenia najechania

Klasa View obsługuje teraz zdarzenia „najechanie”, które umożliwiają atrakcyjniejsze interakcje za pomocą urządzeń śledzących (takich jak mysz lub inne urządzenia obsługujące kursor na ekranie).

Aby otrzymywać zdarzenia najechania kursorem w danym widoku, wdróż View.OnHoverListener i zarejestruj go za pomocą setOnHoverListener(). Gdy w widoku pojawi się zdarzenie najechania kursorem, odbiornik otrzyma wywołanie onHover(), które dostarczy element View, który odebrał to zdarzenie, oraz MotionEvent opisujący rodzaj tego zdarzenia. Możliwe jest jedno z tych zdarzeń najechania kursorem:

Funkcja View.OnHoverListener powinna zwracać wartość „prawda” z pola onHover(), jeśli obsługuje zdarzenie najechania kursorem. Jeśli detektor zwróci wartość false (fałsz), zdarzenie najechania kursorem zostanie wysłane do widoku nadrzędnego w zwykły sposób.

Jeśli Twoja aplikacja korzysta z przycisków lub innych widżetów, które zmieniają swój wygląd w zależności od bieżącego stanu, możesz teraz użyć atrybutu android:state_hovered na liście stanów, które można rysować, aby udostępnić inne tło, które można rysować po najechaniu kursorem na widok.

Prezentację nowych zdarzeń najechania kursorem znajdziesz w klasie Hover w interfejsie API.

Zdarzenia dotyczące rysika i przycisku myszy

Android udostępnia teraz interfejsy API do odbierania danych wejściowych z urządzenia wejściowego rysika, takiego jak urządzenie peryferyjne tabletu lub urządzenia peryferyjnego z rysikiem.

Wprowadzanie rysikiem działa podobnie do dotyku lub myszy. Gdy rysik dotyka wyświetlacza, aplikacje odbierają zdarzenia dotknięcia tak samo jak wtedy, gdy dotyka wyświetlacza palcem. Gdy rysik jest ustawiony nad digitalizacją, aplikacje odbierają zdarzenia najechania tak samo, jak wtedy, gdy przesuwasz kursor myszy po wyświetlaczu, gdy nie są naciśnięte żadne przyciski.

Aplikacja może rozróżniać dane za pomocą palca, myszy, rysika i gumki, wysyłając zapytanie getToolType() o „typ narzędzia” powiązany z każdym wskaźnikiem w funkcji MotionEvent. Obecnie zdefiniowane typy narzędzi to: TOOL_TYPE_UNKNOWN, TOOL_TYPE_FINGER, TOOL_TYPE_MOUSE, TOOL_TYPE_STYLUS i TOOL_TYPE_ERASER. Zapytanie o typ narzędzia oznacza, że aplikacja może obsługiwać dane rysikiem w inny sposób – np. przy użyciu palca czy myszy.

Aplikacja może też sprawdzać, które przyciski myszy lub rysika zostały naciśnięte, wysyłając zapytanie o stan przycisku MotionEvent za pomocą metody getButtonState(). Aktualnie zdefiniowane stany przycisku to: BUTTON_PRIMARY, BUTTON_SECONDARY, BUTTON_TERTIARY, BUTTON_BACK i BUTTON_FORWARD. Dla wygody przyciski myszy w przód i w tył są automatycznie mapowane na klawisze KEYCODE_BACK i KEYCODE_FORWARD. Aplikacja może obsługiwać te klawisze, aby umożliwić nawigację wstecz i do przodu za pomocą przycisków myszy.

Oprócz dokładnego pomiaru pozycji i ciśnienia kontaktu niektóre urządzenia wejściowe rysika raportują też odległość między końcówką rysika a digitalizacją, kąt nachylenia rysika oraz kąt orientacji rysika. Aplikacja może wysyłać zapytania o te informacje za pomocą polecenia getAxisValue() z kodami osi AXIS_DISTANCE, AXIS_TILT i AXIS_ORIENTATION.

Demonstracja typów narzędzi, stanów przycisków i nowych kodów osi znajdziesz w klasie TouchPaint w ApiDemos.

Właściwości

Nowa klasa Property zapewnia szybki, skuteczny i łatwy sposób określania właściwości w dowolnym obiekcie, który umożliwia obiektom wywołującym ogólnie ustawianie/pobieranie wartości obiektów docelowych. Umożliwia też przekazywanie odwołań do pól i metod oraz umożliwia kodowi ustawianie/pobieranie wartości właściwości bez poznania szczegółów pól/metod.

Jeśli na przykład chcesz ustawić wartość pola bar w obiekcie foo, wykonaj to wcześniej:

Kotlin

foo.bar = value

Java

foo.bar = value;

Jeśli chcesz wywołać metodę ustawiającą dla bazowego pola prywatnego bar, wykonaj te czynności:

Kotlin

foo.setBar(value)

Java

foo.setBar(value);

Jeśli jednak chcesz ominąć instancję foo i mieć inny kod ustawiony na wartość bar, tak naprawdę nie ma możliwości, aby to zrobić przed Androidem 4.0.

Za pomocą klasy Property możesz zadeklarować obiekt Property BAR w klasie Foo, aby ustawić to pole w instancji foo klasy Foo w ten sposób:

Kotlin

BAR.set(foo, value)

Java

BAR.set(foo, value);

Klasa View korzysta teraz z klasy Property, aby umożliwić konfigurowanie różnych pól, takich jak właściwości przekształcenia dodane w Androidzie 3.0 (ROTATION, ROTATION_X, TRANSLATION_X itd.).

Klasa ObjectAnimator korzysta też z klasy Property, dzięki czemu można utworzyć ObjectAnimator z klasą Property, która jest szybsza, bardziej wydajna i bezpieczniejsza dla wpisywania niż metoda oparta na ciągach znaków.

Akceleracja sprzętowa

Począwszy od Androida 4.0 akceleracja sprzętowa we wszystkich oknach jest domyślnie włączona, jeśli aplikacja ma ustawioną wartość targetSdkVersion lub minSdkVersion na “14" lub wyższą. akceleracja sprzętowa zapewnia zwykle płynniejsze animacje, płynniejsze przewijanie, większą wydajność i lepsze reagowanie na interakcje użytkownika.

W razie potrzeby możesz ręcznie wyłączyć akcelerację sprzętową za pomocą atrybutu hardwareAccelerated dla poszczególnych elementów <activity> lub elementu <application>. Możesz też wyłączyć akcelerację sprzętową w poszczególnych widokach, wywołując metodę setLayerType(LAYER_TYPE_SOFTWARE).

Więcej informacji o akceleracji sprzętowej, w tym listę nieobsługiwanych operacji rysowania, znajdziesz w dokumencie Akceleracja sprzętowa.

Zmiany w JNI

W poprzednich wersjach Androida odwołania lokalne JNI nie były uchwytami pośrednimi. Android używał wskaźników bezpośrednich. Nie było to problemem, o ile sieć odpadów nie przenosiła obiektów, ale wydawało się, że zadziałało, ponieważ umożliwił pisanie nieprawidłowego kodu. W Androidzie 4.0 system wykrywa te błędy, korzystając z odwołań pośrednich.

Informacje o lokalnych plikach referencyjnych JNI znajdziesz w sekcji „Lokalne i globalne materiały referencyjne” we wskazówkach dotyczących JNI. W Androidzie 4.0 funkcja CheckJNI została udoskonalona pod kątem wykrywania tych błędów. Na blogu dla deweloperów aplikacji na Androida znajdziesz posta, w którym przedstawimy typowe błędy w odwołaniach JNI i sposoby ich naprawy.

Ta zmiana w implementacji JNI ma wpływ tylko na aplikacje kierowane na Androida 4.0. W tym celu należy ustawić dla parametru targetSdkVersion lub minSdkVersion wartość “14" lub wyższą. Jeśli ustawisz mniejszą wartość tych atrybutów, lokalne odwołania JNI będą działać tak samo jak w poprzednich wersjach.

WebKit,

  • WebKit zaktualizowany do wersji 534.30
  • Obsługa czcionek indyjskich (dewanagari, bengalski i tamilski, w tym obsługa złożonych znaków niezbędna do łączenia glifów) w WebView i wbudowanej przeglądarce
  • Obsługa czcionek etiopskich, gruzińskich i ormiańskich w WebView i wbudowanej przeglądarce
  • Obsługa WebDriver ułatwia testowanie aplikacji, które korzystają z WebView

Przeglądarka w systemie Android

Aplikacja Internet dodaje następujące funkcje do obsługi aplikacji internetowych:

Uprawnienia

Oto nowe uprawnienia:

Funkcje urządzenia

Oto nowe funkcje urządzenia:

Szczegółowe informacje o wszystkich zmianach w interfejsach API w Androidzie 4.0 (poziom API 14) znajdziesz w raporcie Różnice w interfejsie API.

Poprzednie interfejsy API

Oprócz powyższych funkcji Android 4.0 w naturalny sposób obsługuje wszystkie interfejsy API z poprzednich wersji. Platforma Android 3.x jest dostępna wyłącznie na urządzenia z dużym ekranem, więc jeśli tworzysz głównie aplikacje na telefony, możesz nie wiedzieć o wszystkich interfejsach API, które zostały dodane do Androida w tych najnowszych wersjach.

Oto kilka najważniejszych interfejsów API, które są obecnie dostępne również w telefonach:

Android 3.0
  • Fragment: komponent platformy, który pozwala rozdzielić poszczególne elementy aktywności na osobne moduły, które definiują własny interfejs i cykl życia. Zapoznaj się z przewodnikiem dla programistów Fragmenty.
  • ActionBar: zamiennik tradycyjnego paska tytułu u góry okna aktywności. Zawiera logo aplikacji w lewym rogu i zapewnia nowy interfejs dla elementów menu. Zapoznaj się z przewodnikiem dla programistów dotyczącym paska działań.
  • Loader: komponent platformy, który umożliwia asynchroniczne ładowanie danych w połączeniu z komponentami interfejsu w celu dynamicznego wczytywania danych bez blokowania głównego wątku. Zapoznaj się z przewodnikiem dla programistów Loaders.
  • Schowek systemowy: aplikacje mogą kopiować i wklejać dane (oprócz samego tekstu) do schowka w całym systemie i wklejać je z niego. Przycinane dane mogą mieć postać zwykłego tekstu, identyfikatora URI lub intencji. Zapoznaj się z przewodnikiem dla programistów dotyczącym kopiowania i wklejania.
  • Przeciągnij i upuść: zestaw interfejsów API wbudowanych w platformę widoku, który ułatwia wykonywanie operacji przeciągania i upuszczania. Zapoznaj się z przewodnikiem dla programistów dotyczącym przeciągania i upuszczania.
  • Całkowicie nowa, elastyczna platforma animacji umożliwia animowanie dowolnych właściwości dowolnego obiektu (View, Drawable, Fragment, Object lub cokolwiek innego) oraz definiowanie takich aspektów animacji, jak czas trwania, interpolacja, powtarzanie i inne. Dzięki nowej platformie funkcje animacji na Androidzie są prostsze niż kiedykolwiek wcześniej. Zapoznaj się z przewodnikiem dla programistów dotyczącym animacji właściwości.
  • Renderowanie i obliczenia oparte na RenderScript: RenderScript oferuje wysoką wydajność renderowania i obliczania grafiki 3D na poziomie natywnym, który jest pisany w języku C (standard C99). Zapewnia on wydajność, jakiej oczekuje się od środowiska natywnego, a jednocześnie można go przenosić między różnymi procesorami i układami GPU. Zapoznaj się z przewodnikiem dla programistów RenderScript.
  • Grafika 2D z akceleracją sprzętową: teraz możesz włączyć w swojej aplikacji mechanizm renderowania OpenGL, ustawiając w elemencie <application> elementu <application> lub w poszczególnych elementach <activity> parametr {android:hardwareAccelerated="true"}. Zapewnia to płynniejsze animacje, płynniejsze przewijanie, większą wydajność i lepsze reagowanie na interakcje użytkowników.

    Uwaga: jeśli ustawisz minSdkVersion lub targetSdkVersion aplikacji na "14" lub wyższą, akceleracja sprzętowa będzie domyślnie włączona.

  • I wiele innych. Więcej informacji znajdziesz w uwagach na temat platformy Androida 3.0.
Android 3.1
  • Interfejsy API USB: nowe zaawansowane interfejsy API do integracji podłączonych urządzeń peryferyjnych z aplikacjami na Androida. Interfejsy API opierają się na stosie USB i wbudowanych w platformie usług. Obejmuje to obsługę interakcji z hostem USB i urządzeniami. Zobacz przewodnik dla programistów hosta i akcesorium USB.
  • Interfejsy API MTP/PTP: aplikacje mogą wchodzić w bezpośrednią interakcję z podłączonymi kamerami i innymi urządzeniami PTP, aby otrzymywać powiadomienia o podłączeniu i usuwaniu urządzeń, zarządzać plikami i pamięcią na tych urządzeniach oraz przenosić pliki i metadane na nie i z niego. Interfejs MTP API implementuje podzbiór specyfikacji PTP (Picture Transfer Protocol) specyfikacji MTP (Media Transfer Protocol). Wyświetl dokumentację android.mtp.
  • Interfejsy API RTP: Android udostępnia interfejs API wbudowanemu stosowi RTP (Real-time Transport Protocol), którego aplikacje mogą używać do zarządzania interaktywnym strumieniem danych na żądanie. W szczególności aplikacje umożliwiające korzystanie z VOIP, funkcji push, rozmów wideo oraz strumieniowania dźwięku mogą używać tego interfejsu API do inicjowania sesji oraz przesyłania i odbierania strumieni danych w dowolnej dostępnej sieci. Zobacz dokumentację android.net.rtp.
  • Obsługa joysticków i innych ogólnych funkcji wprowadzania ruchu.
  • Więcej informacji o nowych interfejsach API znajdziesz w uwagach na temat platformy Androida 3.1.
Android 3.2
  • Nowe ekrany obsługują interfejsy API, które dają Ci większą kontrolę nad wyświetlaniem aplikacji na ekranach o różnych rozmiarach. Interfejs API rozszerza obecny model obsługi ekranu o możliwość precyzyjnego kierowania określonych zakresów rozmiarów ekranów według wymiarów mierzonych w niezależnych od gęstości jednostkach (np. 600 dp lub 720 dp) zamiast na podstawie ogólnych rozmiarów ekranu (takich jak duży lub bardzo duży). Jest to ważne na przykład, ponieważ pozwala odróżnić urządzenie 5-calowe od 7-calowego, które zwykle są łączone jako „duże” ekrany. Przeczytaj post na blogu New Tools for Managing Screen sizes (Nowe narzędzia do zarządzania rozmiarami ekranu).
  • Nowe stałe dla parametru <uses-feature> do deklarowania wymagań dotyczących orientacji poziomej lub pionowej.
  • Konfiguracja „rozmiaru ekranu” urządzenia zmienia się teraz podczas zmiany orientacji ekranu. Jeśli Twoja aplikacja jest kierowana na interfejs API na poziomie 13 lub wyższym, musisz wprowadzić zmianę w konfiguracji "screenSize", jeśli chcesz też uwzględnić zmianę w konfiguracji "orientation". Więcej informacji znajdziesz w sekcji android:configChanges.
  • Informacje o innych nowych interfejsach API znajdziesz w sekcji poświęconej platformie Androida 3.2.

Poziom API

Interfejs API Androida 4.0 ma przypisany identyfikator w liczbie całkowitej (14) przechowywany w samym systemie. Ten identyfikator, nazywany „poziomem interfejsu API”, pozwala systemowi prawidłowo określić, czy aplikacja jest z nim zgodna, zanim ją zainstalujesz.

Aby skorzystać z interfejsów API wprowadzonych w Androidzie 4.0, musisz skompilować aplikację na platformę Androida, która obsługuje interfejs API na poziomie 14 lub wyższym. W zależności od potrzeb może być też konieczne dodanie atrybutu android:minSdkVersion="14" do elementu <uses-sdk>.

Więcej informacji znajdziesz w artykule Co to jest poziom interfejsu API.