Obsługa sprzętu telewizyjnego

Telewizor znacznie różni się od innych urządzeń z Androidem. Telewizory nie zawierają niektórych funkcji sprzętowych dostępnych w innych urządzeniach z Androidem, takich jak ekrany dotykowe, aparaty fotograficzne i odbiorniki GPS. Telewizory są też całkowicie zależne od dodatkowego sprzętu: aby użytkownicy mogli korzystać z aplikacji na telewizory, muszą używać pilota lub pada do gier. Tworząc aplikację na telewizor, musisz uważnie wziąć pod uwagę ograniczenia sprzętowe i wymagania dotyczące działania na telewizorze.

Z tego przewodnika dowiesz się, jak sprawdzić, czy aplikacja działa na telewizorze, i jak obsługiwać nieobsługiwane funkcje sprzętowe. Aby poznać różne metody wprowadzania, przeczytaj artykuł Zarządzanie kontrolerami TV.

Sprawdzanie telewizora

Jeśli tworzysz aplikację, która działa zarówno na telewizorach, jak i innych urządzeniach, być może musisz sprawdzić, na jakim urządzeniu działa, i dostosować jej działanie. Jeśli na przykład masz aplikację, którą można uruchamiać za pomocą interfejsu Intent, sprawdź właściwości urządzenia, by określić, czy chcesz uruchomić aktywność związaną z telewizorem czy telefonem.

Zalecanym sposobem na sprawdzenie, czy aplikacja działa na telewizorze, jest użycie metody PackageManager.hasSystemFeature() do sprawdzenia, czy urządzenie działa w trybie telewizora. Ten przykładowy kod pokazuje, jak sprawdzić, czy aplikacja działa na telewizorze:

Kotlin

const val TAG = "DeviceTypeRuntimeCheck"

val isTelevision = packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
if (isTelevision) {
    Log.d(TAG, "Running on a TV Device")
} else {
    Log.d(TAG, "Running on a non-TV Device")
}

Java

public static final String TAG = "DeviceTypeRuntimeCheck";

boolean isTelevision = getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
if (isTelevision) {
    Log.d(TAG, "Running on a TV Device");
} else {
    Log.d(TAG, "Running on a non-TV Device");
}

Obsługa nieobsługiwanych funkcji sprzętowych

W zależności od projektu i funkcjonalności aplikacji możesz obejść problem z niedostępnością niektórych funkcji sprzętowych. W tej sekcji omawiamy, jakie funkcje sprzętowe zwykle są niedostępne na telewizorze, jak wykryć brakujące funkcje sprzętowe i jakie alternatywy sugerujemy dla tych funkcji.

Nieobsługiwane funkcje sprzętowe telewizora

Telewizory mają inne przeznaczenie niż inne urządzenia, więc nie mają funkcji sprzętowych, które często mają inne urządzenia z Androidem. Z tego powodu system Android nie obsługuje tych funkcji telewizora:

Sprzęt Deskryptor funkcji Androida
Ekran dotykowy android.hardware.touchscreen
Emulator ekranu dotykowego android.hardware.faketouch
Telefonia android.hardware.telephony
Aparat android.hardware.camera
Komunikacja Near Field Communication (NFC) android.hardware.nfc
GPS android.hardware.location.gps
Mikrofon android.hardware.microphone
Czujniki android.hardware.sensor
Ekran w orientacji pionowej android.hardware.screen.portrait

Uwaga: niektóre kontrolery telewizyjne są wyposażone w mikrofon. Różni się on od opisanej tutaj funkcji sprzętowej mikrofonu. Mikrofon kontrolera jest w pełni obsługiwany.

Pełną listę funkcji, podfunkcji i ich deskryptorów znajdziesz w dokumentacji funkcji.

Deklarowanie wymagań sprzętowych dotyczących telewizora

Aplikacje na Androida mogą deklarować wymagania dotyczące funkcji sprzętowych w manifeście, aby mieć pewność, że nie są instalowane na urządzeniach, które nie mają tych funkcji. Jeśli udostępniasz istniejącą aplikację na telewizory, dokładnie sprawdź w jej pliku manifestu pod kątem deklaracji wymagań sprzętowych, które mogą uniemożliwiać jej zainstalowanie na telewizorze.

Jeśli Twoja aplikacja korzysta z funkcji sprzętowych takich jak ekran dotykowy lub aparat, które nie są dostępne na telewizorze, ale może działać bez tych funkcji, zmodyfikuj plik manifestu aplikacji, aby wskazać, że funkcje te nie są wymagane. Ten fragment kodu manifestu pokazuje, jak zadeklarować, że aplikacja nie wymaga funkcji sprzętowych, które są niedostępne na telewizorach, ale korzysta z nich na urządzeniach innych niż telewizor:

<uses-feature android:name="android.hardware.touchscreen"
        android:required="false"/>
<uses-feature android:name="android.hardware.faketouch"
        android:required="false"/>
<uses-feature android:name="android.hardware.telephony"
        android:required="false"/>
<uses-feature android:name="android.hardware.camera"
        android:required="false"/>
<uses-feature android:name="android.hardware.nfc"
        android:required="false"/>
<uses-feature android:name="android.hardware.location.gps"
        android:required="false"/>
<uses-feature android:name="android.hardware.microphone"
        android:required="false"/>
<uses-feature android:name="android.hardware.sensor"
        android:required="false"/>
<!-- Some TV devices have an ethernet connection only -->
<uses-feature android:name="android.hardware.wifi"
        android:required="false"/>

Uwaga: niektóre funkcje mają podfunkcje, takie jak android.hardware.camera.front, jak opisano w dokumentacji funkcji. Pamiętaj, aby oznaczyć wszystkie podfunkcje używane również w aplikacji jako required="false".

Wszystkie aplikacje przeznaczone na telewizory muszą zadeklarować, że funkcja ekranu dotykowego nie jest wymagana. Więcej informacji znajdziesz w sekcji Pierwsze kroki z aplikacjami na telewizory. Jeśli Twoja aplikacja zwykle używa co najmniej jednej funkcji nieobsługiwanych przez telewizory, zmień ustawienie atrybutu android:required na false dla tych funkcji w pliku manifestu.

Uwaga: zadeklarowanie funkcji sprzętowej jako wymaganej przez ustawienie jej wartości na true uniemożliwia instalowanie aplikacji na telewizorach i wyświetlanie jej w programie uruchamiającym na ekranie głównym Androida TV.

Pamiętaj o uprawnieniach, które sugerują funkcje sprzętowe

Niektóre deklaracje w pliku manifestu uses-permission mają zastosowanie funkcji sprzętowych. Oznacza to, że wysłanie prośby o niektóre uprawnienia w manifeście aplikacji może uniemożliwić jej instalowanie i używanie na telewizorach. Poniższe często wymagane uprawnienia tworzą niejawne wymaganie dotyczące funkcji sprzętowych:

Uprawnienia Domniemana funkcja sprzętowa
RECORD_AUDIO android.hardware.microphone
CAMERA android.hardware.camera i
android.hardware.camera.autofocus
ACCESS_COARSE_LOCATION

android.hardware.location

android.hardware.location.network (tylko docelowy poziom interfejsu API na poziomie 20 lub niższym)

ACCESS_FINE_LOCATION

android.hardware.location

android.hardware.location.gps (tylko docelowy poziom interfejsu API na poziomie 20 lub niższym)

ACCESS_WIFI_STATE
CHANGE_WIFI_STATE

android.hardware.wifi

Niektóre telewizory mają połączenie tylko Ethernet.

Pełną listę próśb o uprawnienia, które sugerują konieczność korzystania z funkcji sprzętowych, znajdziesz w przewodniku uses-feature. Jeśli Twoja aplikacja żąda jednej z wymienionych wcześniej funkcji, umieść w pliku manifestu deklarację uses-feature dotyczącą domniemanej funkcji sprzętowej, która wskazuje, że nie jest ona wymagana. android:required="false".

Uwaga: jeśli Twoja aplikacja jest kierowana na Androida 5.0 (poziom interfejsu API 21) lub nowszego i korzysta z uprawnienia ACCESS_COARSE_LOCATION lub ACCESS_FINE_LOCATION, użytkownicy mogą ją zainstalować na telewizorze, nawet jeśli telewizor nie ma karty sieciowej ani odbiornika GPS.

Gdy włączysz w aplikacji funkcje sprzętowe, musisz sprawdzić ich dostępność w czasie działania, a potem dostosować działanie aplikacji. W następnej sekcji opisujemy, jak sprawdzić funkcje sprzętowe, i podpowiadamy, jak zmienić działanie aplikacji.

Więcej informacji o filtrowaniu i deklarowaniu funkcji w pliku manifestu znajdziesz w przewodniku dotyczącym uses-feature.

Sprawdź dostępne funkcje sprzętowe

Platforma Android informuje, czy funkcje sprzętowe nie są dostępne na urządzeniu, na którym działa Twoja aplikacja. Aby sprawdzać określone funkcje w czasie działania, używaj metody hasSystemFeature(String). Ta metoda przyjmuje pojedynczy argument ciągu określający cechę, którą chcesz sprawdzić.

Ten przykładowy kod pokazuje, jak wykrywać dostępność funkcji sprzętu w czasie działania:

Kotlin

// Check whether the telephony hardware feature is available.
if (packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
    Log.d("HardwareFeatureTest", "Device can make phone calls")
}

// Check whether android.hardware.touchscreen feature is available.
if (packageManager.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)) {
    Log.d("HardwareFeatureTest", "Device has a touchscreen.")
}

Java

// Check whether the telephony hardware feature is available.
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
    Log.d("HardwareFeatureTest", "Device can make phone calls");
}

// Check whether android.hardware.touchscreen feature is available.
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)) {
    Log.d("HardwareFeatureTest", "Device has a touchscreen.");
}

Ekran dotykowy

Ponieważ większość telewizorów nie ma ekranów dotykowych, Android nie obsługuje ich obsługi za pomocą ekranu dotykowego. Co więcej, korzystanie z ekranu dotykowego jest niezgodne z środowiskiem, w którym użytkownik siedzi 3 metry od ekranu. Upewnij się, że elementy interfejsu i tekst nie wymagają ani nie sugerują używania ekranu dotykowego.

W przypadku telewizorów zaprojektuj aplikację tak, aby obsługiwała nawigację przy użyciu pada kierunkowego (pada kierunkowego) na pilocie do telewizora. Więcej informacji o prawidłowej obsłudze nawigacji przy użyciu elementów sterujących wyświetlaniem w telewizji znajdziesz w artykule o nawigacji przy użyciu telewizora.

Aparat

Mimo że telewizor zazwyczaj nie ma aparatu, wciąż możesz udostępnić na nim aplikację związaną z fotografią. Jeśli na przykład masz aplikację, która wykonuje, wyświetla i edytuje zdjęcia, możesz wyłączyć tę funkcję na telewizorach, ale pozostawić użytkownikom możliwość oglądania i edytowania zdjęć. Jeśli chcesz włączyć działanie aplikacji związanej z aparatem na telewizorze, dodaj do pliku manifestu aplikacji tę deklarację funkcji:

<uses-feature android:name="android.hardware.camera" android:required="false" />

Jeśli włączysz aplikację do działania bez kamery, dodaj do niej kod, który będzie wykrywał, czy ta funkcja jest dostępna, i dostosowuje jej działanie. Z poniższego przykładu kodu dowiesz się, jak wykryć obecność kamery:

Kotlin

// Check whether the camera hardware feature is available.
if (packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
    Log.d("Camera test", "Camera available!")
} else {
    Log.d("Camera test", "No camera available. View and edit features only.")
}

Java

// Check whether the camera hardware feature is available.
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
    Log.d("Camera test", "Camera available!");
} else {
    Log.d("Camera test", "No camera available. View and edit features only.");
}

GPS

Telewizory to urządzenia stacjonarne działające wewnątrz budynków, które nie mają wbudowanego odbiornika GPS. Jeśli Twoja aplikacja korzysta z informacji o lokalizacji, możesz zezwolić użytkownikom na jej wyszukiwanie lub korzystać z usług statycznego dostawcy lokalizacji, np. kodu pocztowego skonfigurowanego podczas konfigurowania telewizora.

Kotlin

// Request a static location from the location manager.
val locationManager = this.getSystemService(Context.LOCATION_SERVICE) as LocationManager
val location: Location = locationManager.getLastKnownLocation("static")

// Attempt to get postal code from the static location object.
val geocoder = Geocoder(this)
val address: Address? =
        try {
            geocoder.getFromLocation(location.latitude, location.longitude, 1)[0]
                    .apply {
                        Log.d(TAG, postalCode)
                    }
        } catch (e: IOException) {
            Log.e(TAG, "Geocoder error", e)
            null
        }

Java

// Request a static location from the location manager.
LocationManager locationManager = (LocationManager) this.getSystemService(
        Context.LOCATION_SERVICE);
Location location = locationManager.getLastKnownLocation("static");

// Attempt to get postal code from the static location object.
Geocoder geocoder = new Geocoder(this);
Address address = null;
try {
  address = geocoder.getFromLocation(location.getLatitude(),
          location.getLongitude(), 1).get(0);
  Log.d("Postal code", address.getPostalCode());

} catch (IOException e) {
  Log.e(TAG, "Geocoder error", e);
}

Wstrzymaj odtwarzanie w trybie oszczędzania energii

Niektóre telewizory obsługują tryb oszczędzania energii po wyłączeniu urządzenia. Zamiast wyłączać wyświetlacz, Android TV działa w tle. Wyjście audio wciąż działa w tym trybie, więc gdy urządzenie działa w trybie oszczędzania energii, zatrzymaj wszystkie aktualnie odtwarzane treści.

Aby uniknąć odtwarzania w trybie oszczędzania energii, zastąp onStop() i zatrzymaj wszystkie aktualnie odtwarzane treści:

Kotlin

override fun onStop() {
    // App-specific method to stop playback.
    stopPlayback()
    super.onStop()
}

Java

@Override
public void onStop() {
  // App-specific method to stop playback.
  stopPlayback();
  super.onStop();
}

Gdy użytkownik ponownie włączy zasilanie, aplikacja onStart() zostanie wywołana, jeśli jest ona aktywną aplikacją na pierwszym planie. Więcej informacji o uruchamianiu i zatrzymywaniu aktywności znajdziesz w artykule Cykl życia aktywności.