Xử lý phần cứng TV

Phần cứng TV khác biệt đáng kể so với các thiết bị Android khác. TV không có một số tính năng phần cứng có trên các thiết bị Android khác, chẳng hạn như màn hình cảm ứng, máy ảnh và bộ thu GPS. TV cũng hoàn toàn phụ thuộc vào các thiết bị phần cứng phụ: để người dùng tương tác với các ứng dụng dành cho TV, họ phải sử dụng điều khiển từ xa hoặc tay điều khiển trò chơi. Khi tạo ứng dụng cho TV, bạn phải cân nhắc kỹ các giới hạn và yêu cầu về phần cứng khi hoạt động trên phần cứng TV.

Hướng dẫn này cho biết cách kiểm tra xem ứng dụng của bạn có đang chạy trên TV hay không và cách xử lý các tính năng phần cứng không được hỗ trợ. Để tìm hiểu về các phương thức nhập dữ liệu khác nhau, hãy xem phần Quản lý bộ điều khiển TV.

Kiểm tra xem có thiết bị TV không

Nếu đang tạo một ứng dụng hoạt động trên cả thiết bị TV và các thiết bị khác, thì bạn có thể cần kiểm tra loại thiết bị mà ứng dụng đang chạy và điều chỉnh hoạt động của ứng dụng. Ví dụ: nếu bạn có một ứng dụng có thể khởi động thông qua Intent, hãy kiểm tra các thuộc tính thiết bị để xác định xem nên bắt đầu một hoạt động hướng về TV hay một hoạt động trên điện thoại.

Bạn nên dùng phương thức PackageManager.hasSystemFeature() để xác định xem ứng dụng của mình có đang chạy trên thiết bị TV hay không để kiểm tra xem thiết bị có đang chạy ở chế độ TV hay không. Mã ví dụ sau đây hướng dẫn bạn cách kiểm tra xem ứng dụng của mình có đang chạy trên thiết bị TV hay không:

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

Xử lý các tính năng phần cứng không được hỗ trợ

Tuỳ thuộc vào thiết kế và chức năng của ứng dụng, bạn có thể khắc phục một số tính năng phần cứng không dùng được. Phần này thảo luận về những tính năng phần cứng thường không có trên TV, cách phát hiện những tính năng phần cứng bị thiếu và những lựa chọn thay thế được đề xuất cho những tính năng này.

Các tính năng phần cứng TV không được hỗ trợ

TV có mục đích khác với các thiết bị khác, vì vậy TV không có các tính năng phần cứng như các thiết bị chạy Android khác thường có. Vì lý do này, hệ thống Android không hỗ trợ các tính năng sau cho thiết bị TV:

Phần cứng Phần mô tả tính năng Android
Màn hình cảm ứng android.hardware.touchscreen
Trình mô phỏng màn hình cảm ứng android.hardware.faketouch
Điện thoại android.hardware.telephony
Camera android.hardware.camera
Giao tiếp phạm vi gần (NFC) android.hardware.nfc
GPS android.hardware.location.gps
Micrô android.hardware.microphone
Cảm biến android.hardware.sensor
Màn hình theo hướng dọc android.hardware.screen.portrait

Lưu ý: Một số bộ điều khiển TV có micrô, tính năng này không giống với tính năng phần cứng micrô được mô tả ở đây. Micrô của tay điều khiển được hỗ trợ đầy đủ.

Hãy xem Tài liệu tham khảo về tính năng để biết danh sách đầy đủ các tính năng, tính năng phụ và mã mô tả tương ứng.

Khai báo yêu cầu về phần cứng cho TV

Các ứng dụng Android có thể khai báo các yêu cầu về tính năng phần cứng trong tệp kê khai ứng dụng để giúp đảm bảo rằng những tính năng đó sẽ không được cài đặt trên những thiết bị không cung cấp những tính năng đó. Nếu bạn mở rộng một ứng dụng hiện có để sử dụng trên TV, hãy xem xét kỹ tệp kê khai của ứng dụng để xem có nội dung khai báo nào liên quan đến yêu cầu về phần cứng có thể ngăn việc cài đặt ứng dụng đó trên thiết bị TV hay không.

Nếu ứng dụng của bạn dùng các tính năng phần cứng như màn hình cảm ứng hoặc máy ảnh không có trên TV, nhưng ứng dụng có thể hoạt động mà không cần dùng những tính năng đó, hãy sửa đổi tệp kê khai của ứng dụng để cho biết rằng những tính năng này là không bắt buộc. Đoạn mã tệp kê khai sau đây minh hoạ cách khai báo rằng ứng dụng của bạn không yêu cầu những tính năng phần cứng không có trên thiết bị TV, nhưng sử dụng những tính năng đó trên các thiết bị không phải TV:

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

Lưu ý: Một số tính năng có các tính năng phụ, chẳng hạn như android.hardware.camera.front, như mô tả trong Tài liệu tham khảo về tính năng. Hãy nhớ đánh dấu mọi tính năng phụ cũng được sử dụng trong ứng dụng của bạn là required="false".

Mọi ứng dụng dùng trên thiết bị TV đều phải khai báo rằng tính năng màn hình cảm ứng là không bắt buộc, như mô tả trong bài viết Làm quen với ứng dụng dành cho TV. Nếu ứng dụng của bạn thường sử dụng một hoặc nhiều tính năng mà thiết bị TV không hỗ trợ, hãy thay đổi chế độ cài đặt thuộc tính android:required thành false cho các tính năng đó trong tệp kê khai.

Thận trọng: Việc khai báo một tính năng phần cứng theo yêu cầu bằng cách đặt giá trị của tính năng đó thành true sẽ ngăn việc cài đặt ứng dụng của bạn trên các thiết bị TV hoặc xuất hiện trong trình chạy màn hình chính của Android TV.

Lưu ý đến các quyền ngụ ý về tính năng phần cứng

Một số uses-permission khai báo tệp kê khai chỉ đơn thuần là các tính năng phần cứng. Hành vi này có nghĩa là việc yêu cầu một số quyền trong tệp kê khai ứng dụng có thể ngăn việc cài đặt và sử dụng ứng dụng của bạn trên các thiết bị TV. Các quyền thường được yêu cầu sau đây tạo ra một yêu cầu ngầm ẩn về tính năng phần cứng:

Quyền Tính năng phần cứng ngụ ý
RECORD_AUDIO android.hardware.microphone
CAMERA android.hardware.camera
android.hardware.camera.autofocus
ACCESS_COARSE_LOCATION

android.hardware.location

android.hardware.location.network (chỉ dành cho API cấp 20 trở xuống)

ACCESS_FINE_LOCATION

android.hardware.location

android.hardware.location.gps (chỉ dành cho API cấp 20 trở xuống)

ACCESS_WIFI_STATE
CHANGE_WIFI_STATE

android.hardware.wifi

Một số thiết bị TV chỉ có kết nối Ethernet.

Để xem danh sách đầy đủ các yêu cầu cấp quyền ngụ ý yêu cầu về tính năng phần cứng, hãy xem hướng dẫn về uses-feature. Nếu ứng dụng yêu cầu một trong các tính năng nêu trên, hãy thêm nội dung khai báo uses-feature vào tệp kê khai cho tính năng phần cứng ngụ ý cho biết tính năng đó không bắt buộc. android:required="false".

Lưu ý: Nếu ứng dụng của bạn nhắm đến Android 5.0 (API cấp 21) trở lên và sử dụng quyền ACCESS_COARSE_LOCATION hoặc ACCESS_FINE_LOCATION, thì người dùng vẫn có thể cài đặt ứng dụng của bạn trên thiết bị TV, ngay cả khi thiết bị TV không có thẻ mạng hoặc bộ thu GPS.

Sau khi đưa các tính năng phần cứng vào ứng dụng ở chế độ không bắt buộc, bạn phải kiểm tra xem có các tính năng đó hay không trong thời gian chạy rồi điều chỉnh hành vi của ứng dụng. Phần tiếp theo sẽ thảo luận về cách kiểm tra các tính năng phần cứng và đề xuất một số phương pháp để thay đổi hành vi của ứng dụng.

Để biết thêm thông tin về cách lọc và khai báo các tính năng trong tệp kê khai, hãy xem hướng dẫn về uses-feature.

Kiểm tra các tính năng phần cứng

Khung Android có thể cho bạn biết liệu các tính năng phần cứng không có trên thiết bị mà ứng dụng của bạn đang chạy hay không. Sử dụng phương thức hasSystemFeature(String) để kiểm tra các tính năng cụ thể trong thời gian chạy. Phương thức này sẽ lấy một đối số chuỗi chỉ định tính năng mà bạn muốn kiểm tra.

Mã ví dụ sau đây minh hoạ cách phát hiện khả năng sử dụng các tính năng phần cứng trong thời gian chạy:

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

Màn hình cảm ứng

Vì hầu hết TV không có màn hình cảm ứng, nên Android không hỗ trợ tương tác trên màn hình cảm ứng cho các thiết bị TV. Hơn nữa, việc sử dụng màn hình cảm ứng sẽ không phù hợp với môi trường xem khi người dùng ngồi cách màn hình khoảng 3 mét. Đảm bảo rằng văn bản và các thành phần trên giao diện người dùng không yêu cầu hoặc ngụ ý việc sử dụng màn hình cảm ứng.

Đối với thiết bị TV, hãy thiết kế ứng dụng để hỗ trợ chỉ đường bằng bàn phím di chuyển (D-pad) trên điều khiển từ xa của TV. Để biết thêm thông tin về cách hỗ trợ đúng cách tính năng điều hướng bằng các nút điều khiển phù hợp với TV, hãy xem nội dung Điều hướng trên TV.

Camera

Mặc dù TV thường không có camera, nhưng bạn vẫn có thể cung cấp ứng dụng liên quan đến nhiếp ảnh trên TV. Ví dụ: nếu có một ứng dụng chụp ảnh, xem và chỉnh sửa ảnh, bạn có thể tắt chức năng chụp ảnh của ứng dụng đó cho TV, nhưng người dùng vẫn có thể xem và thậm chí chỉnh sửa ảnh. Nếu bạn quyết định cho phép ứng dụng liên quan đến máy ảnh hoạt động trên TV, hãy thêm nội dung khai báo tính năng sau đây cho tệp kê khai ứng dụng:

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

Nếu bạn cho phép ứng dụng chạy mà không cần máy ảnh, hãy thêm mã vào ứng dụng để phát hiện xem tính năng máy ảnh có dùng được hay không và điều chỉnh hoạt động của ứng dụng. Ví dụ về mã sau đây minh hoạ cách phát hiện sự hiện diện của máy ảnh:

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

TV là thiết bị cố định, trong nhà và không có bộ thu hệ thống định vị toàn cầu (GPS) tích hợp. Nếu ứng dụng của bạn sử dụng thông tin vị trí, bạn vẫn có thể cho phép người dùng tìm kiếm một vị trí hoặc sử dụng một nhà cung cấp vị trí tĩnh, chẳng hạn như mã bưu chính được định cấu hình trong quá trình thiết lập thiết bị TV.

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

Tạm dừng phát trong chế độ tiết kiệm pin

Một số thiết bị TV hỗ trợ chế độ tiết kiệm pin khi người dùng tắt thiết bị. Thay vì tắt, thiết bị sẽ tắt màn hình và giữ cho Android TV chạy trong nền. Đầu ra âm thanh vẫn sẽ bật ở chế độ này. Vì vậy, hãy dừng mọi nội dung đang phát khi thiết bị ở chế độ tiết kiệm pin.

Để tránh phát khi ở chế độ tiết kiệm pin, hãy ghi đè onStop() và dừng mọi nội dung đang phát:

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

Khi người dùng bật lại nguồn, onStart() sẽ được gọi nếu ứng dụng của bạn là ứng dụng đang hoạt động trên nền trước. Để biết thêm thông tin về cách bắt đầu và dừng một hoạt động, hãy xem phần Vòng đời hoạt động.