จัดการฮาร์ดแวร์ทีวี

ฮาร์ดแวร์ของทีวีแตกต่างจากอุปกรณ์ Android อื่นๆ อย่างมาก ทีวีไม่มีฟีเจอร์ฮาร์ดแวร์บางอย่างที่พบในอุปกรณ์ Android อื่นๆ เช่น หน้าจอสัมผัส กล้อง และเครื่องรับสัญญาณ GPS นอกจากนี้ ทีวียังต้องพึ่งพาอุปกรณ์ฮาร์ดแวร์รองอย่างสมบูรณ์: ผู้ใช้ต้องใช้รีโมตคอนโทรลหรือเกมแพดเพื่อโต้ตอบกับแอปทีวี (ดูข้อมูลเกี่ยวกับ วิธีการป้อนข้อมูลต่างๆ ได้ที่หัวข้อจัดการตัวควบคุมทีวี)

เมื่อสร้างแอปสำหรับทีวี ให้พิจารณาข้อจำกัดและข้อกำหนดด้านฮาร์ดแวร์ของ การทำงานบนฮาร์ดแวร์ของทีวีอย่างรอบคอบ ตรวจสอบว่าแอปทำงานบนทีวีหรือไม่ และจัดการฟีเจอร์ฮาร์ดแวร์ที่ไม่รองรับ

ตรวจสอบอุปกรณ์ทีวี

หากคุณกำลังสร้างแอปที่ทำงานได้ทั้งบนอุปกรณ์ทีวีและอุปกรณ์อื่นๆ คุณอาจต้อง ตรวจสอบว่าแอปทำงานบนอุปกรณ์ประเภทใดและปรับการทำงานของแอป สำหรับ ตัวอย่างเช่น หากคุณมีแอปที่เริ่มทำงานผ่าน Intent, ให้ตรวจสอบพร็อพเพอร์ตี้ของอุปกรณ์เพื่อพิจารณาว่าจะเริ่มกิจกรรมที่เน้นทีวี หรือกิจกรรมของโทรศัพท์

วิธีที่แนะนำในการตรวจสอบว่าแอปทำงานบนอุปกรณ์ทีวีหรือไม่คือการใช้เมธอด PackageManager.hasSystemFeature เพื่อตรวจสอบ ว่าอุปกรณ์ทำงานในโหมดโทรทัศน์หรือไม่ ตัวอย่างโค้ดต่อไปนี้แสดงวิธีตรวจสอบว่า แอปทำงานบนอุปกรณ์ทีวีหรือไม่

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

จัดการฟีเจอร์ฮาร์ดแวร์ที่ไม่รองรับ

คุณอาจสามารถหลีกเลี่ยงการใช้ฟีเจอร์ฮาร์ดแวร์บางอย่างที่ไม่พร้อมใช้งานได้ ทั้งนี้ขึ้นอยู่กับการออกแบบและฟังก์ชันการทำงานของแอป ส่วนนี้จะอธิบายฟีเจอร์ฮาร์ดแวร์ที่โดยทั่วไปแล้วทีวีไม่รองรับ วิธีตรวจหาฟีเจอร์ฮาร์ดแวร์ที่ขาดหายไป และทางเลือกที่แนะนำสำหรับฟีเจอร์เหล่านี้

ฟีเจอร์ฮาร์ดแวร์ของทีวีที่ไม่รองรับ

ทีวีมีวัตถุประสงค์ในการใช้งานที่แตกต่างจากอุปกรณ์อื่นๆ จึงไม่มีฟีเจอร์ฮาร์ดแวร์ที่ อุปกรณ์อื่นๆ ที่ใช้พลังงานจาก Android มักจะมี ด้วยเหตุนี้ ระบบ Android จึงไม่รองรับ ฟีเจอร์ต่อไปนี้สำหรับอุปกรณ์ทีวี

ฮาร์ดแวร์ ข้อบ่งชี้ฟีเจอร์ของ Android
หน้าจอสัมผัส android.hardware.touchscreen
โปรแกรมจำลองหน้าจอสัมผัส android.hardware.faketouch
โทรศัพท์ android.hardware.telephony
กล้อง android.hardware.camera
Near Field Communications (NFC) android.hardware.nfc
GPS android.hardware.location.gps
ไมโครโฟน android.hardware.microphone
เซ็นเซอร์ android.hardware.sensor
หน้าจอในแนวตั้ง android.hardware.screen.portrait

หมายเหตุ: ตัวควบคุมทีวีบางตัวมีไมโครโฟน ซึ่ง ไม่เหมือนกับฟีเจอร์ฮาร์ดแวร์ไมโครโฟนที่อธิบายไว้ที่นี่ ระบบรองรับไมโครโฟนของตัวควบคุมอย่างเต็มที่

ดูรายการฟีเจอร์ ฟีเจอร์ย่อย และข้อบ่งชี้ทั้งหมดได้ที่ข้อมูลอ้างอิงฟีเจอร์

ประกาศข้อกำหนดด้านฮาร์ดแวร์สำหรับทีวี

แอป Android สามารถประกาศข้อกำหนดด้านฟีเจอร์ฮาร์ดแวร์ในไฟล์ Manifest ของแอปเพื่อช่วยให้มั่นใจ ว่าจะไม่ติดตั้งในอุปกรณ์ที่ไม่มีฟีเจอร์เหล่านั้น หากคุณกำลังขยายแอปที่มีอยู่ เพื่อใช้บนทีวี โปรดตรวจสอบไฟล์ Manifest ของแอปอย่างละเอียดเพื่อดูการประกาศข้อกำหนดด้านฮาร์ดแวร์ ที่อาจป้องกันไม่ให้ติดตั้งแอปในอุปกรณ์ทีวี

หากแอปของคุณใช้ฟีเจอร์ฮาร์ดแวร์ เช่น หน้าจอสัมผัสหรือกล้อง ซึ่งไม่มีใน ทีวี แต่แอปสามารถทำงานได้โดยไม่ต้องใช้ฟีเจอร์เหล่านั้น ให้แก้ไขไฟล์ Manifest ของแอปเพื่อ ระบุว่าไม่จำเป็นต้องใช้ฟีเจอร์เหล่านี้ ข้อมูลโค้ด Manifest ต่อไปนี้ แสดงวิธีประกาศว่าแอปของคุณไม่จำเป็นต้องใช้ฟีเจอร์ฮาร์ดแวร์ที่ไม่มี ในอุปกรณ์ทีวี แต่ใช้ฟีเจอร์เหล่านั้นในอุปกรณ์ที่ไม่ใช่ทีวี

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

แอปทั้งหมดที่ตั้งใจให้ใช้ในอุปกรณ์ทีวีต้องประกาศว่าไม่จำเป็นต้องใช้ฟีเจอร์หน้าจอสัมผัส ตามที่อธิบายไว้ในหัวข้อเริ่มต้นใช้งาน แอปทีวี หากแอปของคุณปกติใช้ฟีเจอร์อย่างน้อย 1 รายการที่อุปกรณ์ทีวีไม่รองรับ ให้เปลี่ยนการตั้งค่าแอตทริบิวต์ android:required เป็น false สำหรับฟีเจอร์เหล่านั้นในไฟล์ Manifest

ข้อควรระวัง: การประกาศฟีเจอร์ฮาร์ดแวร์ว่าจำเป็นโดยตั้งค่า เป็น true จะป้องกันไม่ให้ติดตั้งแอปในอุปกรณ์ทีวี หรือปรากฏใน Launcher ของหน้าจอหลัก Android TV

โปรดทราบว่าสิทธิ์บางอย่างหมายถึงฟีเจอร์ฮาร์ดแวร์

การประกาศไฟล์ Manifest บางรายการ uses-permission หมายถึงฟีเจอร์ฮาร์ดแวร์ ลักษณะการทำงานนี้หมายความว่าการขอสิทธิ์บางอย่างในไฟล์ Manifest ของแอปอาจทำให้แอปไม่สามารถติดตั้งและใช้งานในอุปกรณ์ทีวี สิทธิ์ที่ขอโดยทั่วไปต่อไปนี้จะสร้างข้อกำหนดด้านฟีเจอร์ฮาร์ดแวร์ โดยนัย

สิทธิ์ ฟีเจอร์ฮาร์ดแวร์โดยนัย
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

อุปกรณ์ทีวีบางเครื่องมีการเชื่อมต่ออีเทอร์เน็ตเท่านั้น

ดูรายการคำขอสิทธิ์ทั้งหมดที่หมายถึงข้อกำหนดด้านฟีเจอร์ฮาร์ดแวร์ได้ที่ uses-feature คู่มือ หากแอปของคุณขอฟีเจอร์รายการใดรายการหนึ่งที่ระบุไว้ก่อนหน้านี้ ให้ใส่การประกาศ uses-feature ในไฟล์ Manifest สำหรับฟีเจอร์ฮาร์ดแวร์โดยนัยที่ระบุว่าไม่ จำเป็น android:required="false"

หมายเหตุ: หากแอปของคุณกำหนดเป้าหมายเป็น Android 5.0 (API ระดับ 21) ขึ้นไปและใช้สิทธิ์ ACCESS_COARSE_LOCATION หรือ ACCESS_FINE_LOCATION ผู้ใช้จะยังคงติดตั้งแอปของคุณในอุปกรณ์ทีวีได้ แม้ว่าอุปกรณ์ทีวีจะไม่มีการ์ดเครือข่ายหรือเครื่องรับสัญญาณ GPS

หลังจากทำให้ฟีเจอร์ฮาร์ดแวร์เป็นตัวเลือกสำหรับแอปแล้ว คุณต้องตรวจสอบความพร้อมใช้งานของฟีเจอร์เหล่านั้นในรันไทม์ แล้วปรับลักษณะการทำงานของแอป ส่วนถัดไป จะอธิบายวิธีตรวจสอบฟีเจอร์ฮาร์ดแวร์และแนะนำแนวทางบางอย่างในการเปลี่ยนลักษณะการทำงานของแอป

ดูข้อมูลเพิ่มเติมเกี่ยวกับการกรองและการประกาศฟีเจอร์ในไฟล์ Manifest ได้ที่ uses-feature คู่มือ

ตรวจสอบฟีเจอร์ฮาร์ดแวร์

เฟรมเวิร์ก Android สามารถบอกคุณได้ว่าฟีเจอร์ฮาร์ดแวร์ไม่พร้อมใช้งานในอุปกรณ์ที่ แอปของคุณทำงานอยู่หรือไม่ ใช้เมธอด hasSystemFeature(String) เพื่อตรวจสอบฟีเจอร์เฉพาะในรันไทม์ เมธอดนี้ใช้การโต้แย้งสตริงเดียวที่ ระบุฟีเจอร์ที่ต้องการตรวจสอบ

ตัวอย่างโค้ดต่อไปนี้แสดงวิธีตรวจหาความพร้อมใช้งานของฟีเจอร์ฮาร์ดแวร์ ในรันไทม์:

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

หน้าจอสัมผัส

อุปกรณ์ทีวีส่วนใหญ่ไม่มีหน้าจอสัมผัสหรือความสามารถในการป้อนข้อมูลด้วยตัวชี้ และต้องใช้ รีโมตคอนโทรลแบบปุ่มทิศทาง (D-pad) อย่างเต็มที่ในการนำทาง แอปทีวีต้องรองรับรีโมตคอนโทรลแบบ D-pad เสมอ

ดูข้อมูลเพิ่มเติมเกี่ยวกับการรองรับการนำทางอย่างเหมาะสมโดยใช้ตัวควบคุมที่เหมาะกับทีวีได้ที่ หัวข้อการนำทางในทีวี

ประกาศการรองรับระบบสัมผัส

อุปกรณ์ทีวีบางเครื่องรองรับรีโมตตัวชี้และจอแสดงผลแบบหน้าจอสัมผัส แอปของคุณสามารถรองรับการโต้ตอบแบบคลิก วางเมาส์เหนือ และเลื่อน เช่น ในอุปกรณ์เคลื่อนที่ เพื่อมอบประสบการณ์การใช้งานที่ดีขึ้นในอุปกรณ์ ที่รองรับ

หากแอปอนุญาตให้ใช้โหมดสัมผัส คุณสามารถประกาศการรองรับระบบสัมผัสได้โดยเพิ่ม android.software.leanback.supports_touch เป็น true ใน AndroidManifest.xml

<meta-data android:name="android.software.leanback.supports_touch" android:value="true|false"/>

หมายเหตุ: ในอุปกรณ์ที่รองรับรีโมตตัวชี้ (เช่น เมาส์อากาศหรือแทร็กแพด) การเปิดใช้ตัวเลือกนี้ จะเปิดใช้โหมดเคอร์เซอร์และโหมดสัมผัสแทนที่จะใช้การจำลองความเข้ากันได้ของแพลตฟอร์ม การละเว้น ข้อมูลเมตานี้จะใช้ค่าเริ่มต้นเป็น false

กล้อง

แม้ว่าโดยทั่วไปแล้วทีวีจะไม่มีกล้อง แต่คุณก็ยังสามารถให้บริการแอปที่เกี่ยวข้องกับการถ่ายภาพ ในทีวีได้ ตัวอย่างเช่น หากคุณมีแอปที่ใช้ถ่าย ดู และแก้ไขรูปภาพ คุณสามารถ ปิดใช้ฟังก์ชันการถ่ายรูปสำหรับทีวี และยังคงอนุญาตให้ผู้ใช้ดูและแม้แต่แก้ไข รูปภาพได้ หากตัดสินใจเปิดใช้แอปที่เกี่ยวข้องกับกล้องให้ทำงานบนทีวี ให้เพิ่ม การประกาศฟีเจอร์ต่อไปนี้ลงในไฟล์ Manifest ของแอป

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

หากเปิดใช้แอปให้ทำงานได้โดยไม่ต้องใช้กล้อง ให้เพิ่มโค้ดลงในแอป เพื่อตรวจหาว่าฟีเจอร์กล้องพร้อมใช้งานหรือไม่ และทำการปรับเปลี่ยนการทำงานของ แอป ตัวอย่างโค้ดต่อไปนี้แสดงวิธีตรวจหาว่ามีกล้องหรือไม่

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

ทีวีเป็นอุปกรณ์ในร่มที่อยู่กับที่และไม่มีเครื่องรับสัญญาณระบบกำหนดตำแหน่งทั่วโลก (GPS) ในตัว หากแอปของคุณใช้ข้อมูลตำแหน่ง คุณยังคงอนุญาตให้ผู้ใช้ค้นหา สถานที่หรือใช้ผู้ให้บริการตำแหน่งแบบคงที่ เช่น รหัสไปรษณีย์ที่กำหนดค่าไว้ระหว่างการตั้งค่าอุปกรณ์ทีวี ได้

Kotlin

// Request a static location from the location manager.
val locationManager = this.getSystemService(Context.LOCATION_SERVICE) as LocationManager
val location = locationManager.getLastKnownLocation("static")
if (location == null) {
    Log.e(TAG, "Location is null")
    return
}

// 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)?.firstOrNull()
                    ?.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);
}

หยุดเล่นชั่วคราวระหว่างโหมดใช้พลังงานต่ำ

อุปกรณ์ทีวีบางเครื่องรองรับโหมดใช้พลังงานต่ำเมื่อผู้ใช้ปิดอุปกรณ์ อุปกรณ์จะปิดจอแสดงผลและให้ Android TV ทำงานในเบื้องหลังต่อไปแทนที่จะปิดเครื่อง เอาต์พุตเสียงจะยังคงเปิดใช้งานในโหมดนี้ ดังนั้นให้หยุดเนื้อหาที่กำลังเล่นอยู่เมื่ออุปกรณ์อยู่ในโหมดใช้พลังงานต่ำ

หากต้องการหลีกเลี่ยงการเล่นระหว่างโหมดใช้พลังงานต่ำ ให้ลบล้าง onStop และหยุดเนื้อหาที่กำลังเล่นอยู่

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

เมื่อผู้ใช้เปิดเครื่องอีกครั้ง ระบบจะเรียก onStart หากแอปของคุณเป็นแอปที่ทำงานอยู่เบื้องหน้า ดูข้อมูลเพิ่มเติมเกี่ยวกับการเริ่มและหยุดกิจกรรมได้ที่ วงจรกิจกรรม