Работа с телевизионным оборудованием

Аппаратное обеспечение телевизора существенно отличается от других устройств Android. Телевизоры не поддерживают некоторые аппаратные функции других устройств Android, такие как сенсорные экраны, камеры и GPS-приемники. Телевизоры также полностью зависят от дополнительных аппаратных устройств: чтобы пользователи могли взаимодействовать с телевизионными приложениями, им необходимо использовать пульт дистанционного управления или геймпад. (Чтобы узнать о различных методах ввода, см. «Управление ТВ-контроллерами ».)

При создании приложения для телевидения внимательно учитывайте аппаратные ограничения и требования к работе на оборудовании телевизора. Проверьте, работает ли ваше приложение на телевизоре и обрабатывает ли неподдерживаемые аппаратные функции.

Проверьте наличие ТВ-устройства

Если вы создаете приложение, которое работает как на телевизионных устройствах, так и на других устройствах, вам может потребоваться проверить, на каком устройстве работает ваше приложение, и настроить его работу. Например, если у вас есть приложение, которое можно запустить через Intent , проверьте свойства устройства, чтобы определить, следует ли запускать действие, ориентированное на телевизор, или действие на телефоне.

Рекомендуемый способ определить, работает ли ваше приложение на телевизионном устройстве, — использовать метод PackageManager.hasSystemFeature() , чтобы проверить, работает ли устройство в телевизионном режиме. В следующем примере кода показано, как проверить, работает ли ваше приложение на ТВ-устройстве:

Котлин

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")
}

Ява

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");
}

Обработка неподдерживаемых аппаратных функций

В зависимости от дизайна и функциональности вашего приложения вы можете обойти некоторые недоступные аппаратные функции. В этом разделе обсуждается, какие аппаратные функции обычно недоступны для телевизора, как обнаружить отсутствующие аппаратные функции и какие альтернативы предлагаются этим функциям.

Неподдерживаемые аппаратные функции телевизора

Телевизоры имеют другое назначение, чем другие устройства, поэтому у них нет аппаратных функций, которые часто есть у других устройств на базе Android. По этой причине система Android не поддерживает следующие функции телевизионного устройства:

Аппаратное обеспечение Дескриптор функции Android
Сенсорный экран android.hardware.touchscreen
Эмулятор сенсорного экрана android.hardware.faketouch
Телефония android.hardware.telephony
Камера android.hardware.camera
Связь ближнего радиуса действия (NFC) android.hardware.nfc
GPS android.hardware.location.gps
Микрофон android.hardware.microphone
Датчики android.hardware.sensor
Экран в портретной ориентации android.hardware.screen.portrait

Примечание. Некоторые ТВ-контроллеры оснащены микрофоном, который отличается от описанной здесь аппаратной функции микрофона. Микрофон контроллера полностью поддерживается.

Полный список функций, подфункций и их дескрипторов см. в справочнике по функциям .

Объявить требования к оборудованию для телевизора

Приложения Android могут объявлять требования к аппаратным функциям в манифесте приложения, чтобы гарантировать, что они не будут установлены на устройствах, которые не предоставляют эти функции. Если вы расширяете существующее приложение для использования на телевизоре, внимательно просмотрите манифест вашего приложения на предмет любых заявлений о требованиях к оборудованию, которые могут помешать его установке на ТВ-устройстве.

Если ваше приложение использует аппаратные функции, такие как сенсорный экран или камера, которые недоступны на телевизоре, но может работать без использования этих функций, измените манифест вашего приложения, указав, что эти функции не требуются. В следующем фрагменте кода манифеста показано, как объявить, что вашему приложению не требуются аппаратные функции, недоступные на телевизионных устройствах, но используются эти функции на устройствах, не являющихся телевизионными устройствами:

<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"/>

Примечание. Некоторые функции имеют подфункции, например android.hardware.camera.front , как описано в Справочнике функций . Обязательно отметьте все подфункции, также используемые в вашем приложении, как required="false" .

Все приложения, предназначенные для использования на телевизионных устройствах, должны заявить, что функция сенсорного экрана не требуется, как описано в разделе Начало работы с телевизионными приложениями . Если ваше приложение обычно использует одну или несколько функций, не поддерживаемых телевизионными устройствами, измените настройку атрибута android:required на false для этих функций в вашем манифесте.

Внимание! Объявление аппаратной функции необходимой, установив для нее значение true не позволит вашему приложению устанавливаться на телевизионные устройства или появляться в средстве запуска на главном экране Android TV.

Помните о разрешениях, которые подразумевают аппаратные функции

Некоторые декларации uses-permission подразумевают аппаратные функции . Такое поведение означает, что запрос некоторых разрешений в манифесте вашего приложения может исключить установку и использование вашего приложения на телевизионных устройствах. Следующие часто запрашиваемые разрешения создают неявные требования к аппаратным функциям:

Разрешение Подразумеваемая аппаратная функция
RECORD_AUDIO android.hardware.microphone
CAMERA android.hardware.camera и
android.hardware.camera.autofocus
ACCESS_COARSE_LOCATION

android.hardware.location

android.hardware.location.network (только целевой уровень API 20 или ниже)

ACCESS_FINE_LOCATION

android.hardware.location

android.hardware.location.gps (только целевой уровень API 20 или ниже)

ACCESS_WIFI_STATE
CHANGE_WIFI_STATE

android.hardware.wifi

Некоторые телевизионные устройства имеют только подключение к Ethernet.

Полный список запросов разрешений, которые подразумевают требования к аппаратным функциям, см. в руководстве uses-feature . Если ваше приложение запрашивает одну из ранее перечисленных функций, включите в манифест декларацию об uses-feature подразумеваемой аппаратной функции, указывающую, что она не требуется. android:required="false" .

Примечание. Если ваше приложение предназначено для Android 5.0 (уровень API 21) или выше и использует разрешение ACCESS_COARSE_LOCATION или ACCESS_FINE_LOCATION , пользователи все равно смогут установить ваше приложение на ТВ-устройство, даже если на ТВ-устройстве нет сетевой карты или GPS-приемника. .

После того как вы сделаете аппаратные функции необязательными для вашего приложения, вы должны проверить доступность этих функций во время выполнения, а затем настроить поведение вашего приложения. В следующем разделе обсуждается, как проверить аппаратные функции, и предлагаются некоторые подходы к изменению поведения вашего приложения.

Дополнительные сведения о фильтрации и объявлении функций в манифесте см. в руководстве uses-feature .

Проверьте аппаратные функции

Платформа Android может сообщить вам, недоступны ли аппаратные функции на устройстве, на котором работает ваше приложение. Используйте метод hasSystemFeature(String) для проверки определенных функций во время выполнения. Этот метод принимает один строковый аргумент, указывающий функцию, которую вы хотите проверить.

В следующем примере кода показано, как определить доступность аппаратных функций во время выполнения:

Котлин

// 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.")
}

Ява

// 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.");
}

Сенсорный экран

Поскольку большинство телевизоров не имеют сенсорных экранов, Android не поддерживает взаимодействие с сенсорным экраном для телевизионных устройств. Кроме того, использование сенсорного экрана несовместимо с условиями просмотра, когда пользователь сидит на расстоянии 10 футов от дисплея. Убедитесь, что ваши элементы пользовательского интерфейса и текст не требуют и не подразумевают использование сенсорного экрана.

Для телевизионных устройств разработайте приложение так, чтобы оно поддерживало навигацию с помощью крестовины на пульте дистанционного управления телевизора. Дополнительную информацию о правильной поддержке навигации с помощью элементов управления, удобных для телевизора, см. в разделе ТВ-навигация .

Камера

Хотя в телевизоре обычно нет камеры, вы все равно можете установить на телевизор приложение, связанное с фотографией. Например, если у вас есть приложение, которое снимает, просматривает и редактирует фотографии, вы можете отключить его функцию съемки изображений для телевизоров и при этом разрешить пользователям просматривать и даже редактировать фотографии. Если вы решите разрешить работу приложения, связанного с камерой, на телевизоре, добавьте следующее объявление функции в манифест приложения:

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

Если вы разрешаете своему приложению работать без камеры, добавьте в свое приложение код, который определяет, доступна ли функция камеры, и вносит коррективы в работу вашего приложения. В следующем примере кода показано, как обнаружить наличие камеры:

Котлин

// 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.")
}

Ява

// 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

Телевизоры являются стационарными устройствами, предназначенными для использования внутри помещений, и не имеют встроенных приемников системы глобального позиционирования (GPS). Если ваше приложение использует информацию о местоположении, вы все равно можете разрешить пользователям искать местоположение или использовать статический поставщик местоположения, например почтовый индекс, настроенный во время настройки ТВ-устройства.

Котлин

// 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
        }

Ява

// 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);
}

Пауза воспроизведения в режиме низкого энергопотребления

Некоторые телевизионные устройства поддерживают режим пониженного энергопотребления, когда пользователь выключает устройство. Вместо выключения устройство отключает дисплей и продолжает работу Android TV в фоновом режиме. В этом режиме вывод звука по-прежнему включен, поэтому остановите любой воспроизводимый в данный момент контент, когда устройство находится в режиме низкого энергопотребления.

Чтобы избежать воспроизведения в режиме низкого энергопотребления, переопределите onStop() и остановите любой воспроизводимый в данный момент контент:

Котлин

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

Ява

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

Когда пользователь снова включает питание, вызывается onStart() , если ваше приложение является активным приложением переднего плана. Дополнительные сведения о запуске и остановке действия см. в разделе Жизненный цикл действия .