ช่องต่างๆ ในหน้าจอหลัก

หน้าจอหลักของ Android TV มี UI ที่แสดงเนื้อหาแนะนำเป็นตาราง ช่องและ โปรแกรม โดยแต่ละแถวคือช่อง และช่องจะมีบัตรสำหรับทุกโปรแกรมที่พร้อมให้บริการในช่องนั้นๆ ดังนี้

หน้าจอหลักของ Android TV
หน้าจอหลักของ Android TV

เอกสารนี้จะแสดงวิธีเพิ่มช่องและโปรแกรมลงในหน้าจอหลัก อัปเดตเนื้อหา จัดการการดำเนินการของผู้ใช้ และมอบประสบการณ์การใช้งานที่ดีที่สุดแก่ผู้ใช้ (หากต้องการเจาะลึกเกี่ยวกับ API ให้ลองทำตาม Codelab หน้าจอหลัก และดูเซสชัน I/O 2017 Android TV)

UI ของหน้าจอหลัก

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

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

ช่อง "แนะนำให้รับชม"

ช่อง "แนะนำให้รับชม" เป็นแถวที่ 2 ที่ปรากฏในหน้าจอหลักหลังจากแถวแอป ระบบจะสร้างและดูแลช่องนี้ แอปของคุณสามารถเพิ่มโปรแกรมลงในช่อง "แนะนำให้รับชม" ได้ ดูข้อมูลเพิ่มเติมได้ที่หัวข้อ เพิ่มโปรแกรมลงใน ช่อง "แนะนำให้รับชม"

ช่องของแอป

ช่องที่แอปของคุณสร้างขึ้นทั้งหมดจะเป็นไปตามวงจรชีวิตต่อไปนี้

  1. ผู้ใช้ค้นพบช่องในแอปและขอเพิ่มช่องนั้นลงในหน้าจอหลัก
  2. แอปสร้างช่องและเพิ่มช่องนั้นลงใน TvProvider (ณ จุดนี้ ช่องจะยังไม่ปรากฏ)
  3. แอปขอให้ระบบแสดงช่อง
  4. ระบบขอให้ผู้ใช้อนุมัติช่องใหม่
  5. ช่องใหม่จะปรากฏในแถวสุดท้ายของหน้าจอหลัก

ช่องเริ่มต้น

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

สิ่งที่ต้องมีก่อน

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

<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />

ไลบรารีการสนับสนุน TvProvider ช่วยให้ใช้งานผู้ให้บริการได้ง่ายขึ้น เพิ่มไลบรารีนี้ลงในทรัพยากร Dependency ในไฟล์ build.gradle ดังนี้

ดึงดูด

implementation 'androidx.tvprovider:tvprovider:1.0.0'

Kotlin

implementation("androidx.tvprovider:tvprovider:1.0.0")

หากต้องการใช้ช่องและโปรแกรม โปรดตรวจสอบว่าได้รวมการนำเข้าไลบรารีการสนับสนุนเหล่านี้ไว้ในโปรแกรมแล้ว

Kotlin

import android.support.media.tv.Channel
import android.support.media.tv.TvContractCompat
import android.support.media.tv.ChannelLogoUtils
import android.support.media.tv.PreviewProgram
import android.support.media.tv.WatchNextProgram

Java

import android.support.media.tv.Channel;
import android.support.media.tv.TvContractCompat;
import android.support.media.tv.ChannelLogoUtils;
import android.support.media.tv.PreviewProgram;
import android.support.media.tv.WatchNextProgram;

ช่อง

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

การสร้างช่อง

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

หากต้องการสร้างช่อง ให้ทำตามขั้นตอนต่อไปนี้

  1. สร้างเครื่องมือสร้างช่องและตั้งค่าแอตทริบิวต์ โปรดทราบว่าประเภทช่องต้องเป็น TYPE_PREVIEW และเพิ่มแอตทริบิวต์อื่นๆ ตามที่จำเป็น

    Kotlin

    val builder = Channel.Builder()
    // Every channel you create must have the type `TYPE_PREVIEW`
    builder.setType(TvContractCompat.Channels.TYPE_PREVIEW)
            .setDisplayName("Channel Name")
            .setAppLinkIntentUri(uri)
    

    Java

    Channel.Builder builder = new Channel.Builder();
    // Every channel you create must have the type `TYPE_PREVIEW`
    builder.setType(TvContractCompat.Channels.TYPE_PREVIEW)
            .setDisplayName("Channel Name")
            .setAppLinkIntentUri(uri);
    
  2. แทรกช่องลงในผู้ให้บริการ

    Kotlin

    var channelUri = context.contentResolver.insert(
            TvContractCompat.Channels.CONTENT_URI, builder.build().toContentValues())
    

    Java

    Uri channelUri = context.getContentResolver().insert(
            TvContractCompat.Channels.CONTENT_URI, builder.build().toContentValues());
    
  3. คุณต้องบันทึกรหัสช่องเพื่อเพิ่มโปรแกรมลงในช่องในภายหลัง โดยแยกวิเคราะห์รหัสช่องจาก URI ที่แสดงผล

    Kotlin

    var channelId = ContentUris.parseId(channelUri)
    

    Java

    long channelId = ContentUris.parseId(channelUri);
    
  4. คุณต้องเพิ่มโลโก้สำหรับช่อง โดยใช้ Uri หรือ Bitmap ไอคอนโลโก้ควรมีขนาด 80dp x 80dp และต้องทึบแสง โดยจะแสดงภายใต้มาสก์วงกลมดังนี้

    มาสก์ไอคอนหน้าจอหลักของทีวี

    Kotlin

    // Choose one or the other
    storeChannelLogo(context: Context, channelId: Long, logoUri: Uri) // also works if logoUri is a URL
    storeChannelLogo(context: Context, channelId: Long, logo: Bitmap)
    

    Java

    // Choose one or the other
    storeChannelLogo(Context context, long channelId, Uri logoUri); // also works if logoUri is a URL
    storeChannelLogo(Context context, long channelId, Bitmap logo);
    
  5. สร้างช่องเริ่มต้น (ไม่บังคับ): เมื่อแอปสร้างช่องแรก คุณสามารถกำหนดให้ช่องนั้นเป็นช่อง ช่องเริ่มต้น เพื่อให้ช่องปรากฏในหน้าจอหลัก ทันทีโดยไม่ต้องให้ผู้ใช้ดำเนินการใดๆ ส่วนช่องอื่นๆ ที่คุณสร้างขึ้น จะไม่ปรากฏจนกว่าผู้ใช้จะเลือกช่องเหล่านั้นอย่างชัดแจ้ง selects

    Kotlin

    TvContractCompat.requestChannelBrowsable(context, channelId)
    

    Java

    TvContractCompat.requestChannelBrowsable(context, channelId);
    
  6. ทำให้ช่องเริ่มต้นปรากฏก่อนที่จะเปิดแอป คุณสามารถทำให้เกิดลักษณะการทำงานนี้ได้โดยการเพิ่ม BroadcastReceiver ที่รอรับการดำเนินการ android.media.tv.action.INITIALIZE_PROGRAMS ซึ่งหน้าจอหลักจะส่งหลังจากติดตั้งแอปแล้ว

    <receiver
      android:name=".RunOnInstallReceiver"
      android:exported="true">
        <intent-filter>
          <action android:name="android.media.tv.action.INITIALIZE_PROGRAMS" />
          <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>
    

    เมื่อโหลดแอปจากแหล่งที่ไม่รู้จักระหว่างการพัฒนา คุณสามารถทดสอบขั้นตอนนี้ได้โดยการ ทริกเกอร์ Intent ผ่าน adb โดยที่ your.package.name/.YourReceiverName คือ BroadcastReceiver ของแอป

    adb shell am broadcast -a android.media.tv.action.INITIALIZE_PROGRAMS -n \
        your.package.name/.YourReceiverName
    

    ในบางกรณีที่พบได้ยาก แอปของคุณอาจได้รับการออกอากาศในเวลาเดียวกับที่ผู้ใช้เริ่มแอป โปรดตรวจสอบว่าโค้ดของคุณไม่ได้พยายามเพิ่มช่องเริ่มต้นมากกว่า 1 ครั้ง

การอัปเดตช่อง

การอัปเดตช่องคล้ายกับการสร้างช่องมาก

ใช้ Channel.Builder อีกรายการเพื่อตั้งค่าแอตทริบิวต์ที่ต้องเปลี่ยน

ใช้ ContentResolver เพื่ออัปเดตช่อง โดยใช้รหัสช่องที่คุณบันทึกไว้เมื่อเพิ่มช่องครั้งแรก

Kotlin

context.contentResolver.update(
        TvContractCompat.buildChannelUri(channelId),
        builder.build().toContentValues(),
        null,
        null
)

Java

context.getContentResolver().update(TvContractCompat.buildChannelUri(channelId),
    builder.build().toContentValues(), null, null);

หากต้องการอัปเดตโลโก้ของช่อง ให้ใช้ storeChannelLogo()

การลบช่อง

Kotlin

context.contentResolver.delete(TvContractCompat.buildChannelUri(channelId), null, null)

Java

context.getContentResolver().delete(TvContractCompat.buildChannelUri(channelId), null, null);

โปรแกรม

โปรแกรมคือบัตรเนื้อหาแต่ละรายการที่แสดงภายในช่อง คุณสามารถเผยแพร่โปรแกรมไปยังทั้งช่องที่กำหนดเองของแอปและช่อง "แนะนำให้รับชม" ที่ระบบจัดการ

การเพิ่มโปรแกรมลงในช่องของแอป

สร้าง PreviewProgram.Builder และตั้งค่าแอตทริบิวต์

Kotlin

val builder = PreviewProgram.Builder()
builder.setChannelId(channelId)
        .setType(TvContractCompat.PreviewPrograms.TYPE_CLIP)
        .setTitle("Title")
        .setDescription("Program description")
        .setPosterArtUri(uri)
        .setIntentUri(uri)
        .setInternalProviderId(appProgramId)

Java

PreviewProgram.Builder builder = new PreviewProgram.Builder();
builder.setChannelId(channelId)
        .setType(TvContractCompat.PreviewPrograms.TYPE_CLIP)
        .setTitle("Title")
        .setDescription("Program description")
        .setPosterArtUri(uri)
        .setIntentUri(uri)
        .setInternalProviderId(appProgramId);

เพิ่มแอตทริบิวต์อื่นๆ ขึ้นอยู่กับประเภทของโปรแกรม (หากต้องการดูแอตทริบิวต์ ที่ใช้ได้สำหรับโปรแกรมแต่ละประเภท โปรดดู ตาราง ด้านล่าง)

แทรกโปรแกรมลงในผู้ให้บริการ

Kotlin

var programUri = context.contentResolver.insert(TvContractCompat.PreviewPrograms.CONTENT_URI,
        builder.build().toContentValues())

Java

Uri programUri = context.getContentResolver().insert(TvContractCompat.PreviewPrograms.CONTENT_URI,
      builder.build().toContentValues());

ดึงข้อมูลรหัสโปรแกรมไว้ใช้อ้างอิงในภายหลัง

Kotlin

val programId = ContentUris.parseId(programUri)

Java

long programId = ContentUris.parseId(programUri);

การเพิ่มโปรแกรมลงในช่อง "แนะนำให้รับชม"

หากต้องการแทรกโปรแกรมลงในช่อง "แนะนำให้รับชม" โปรดดูหัวข้อเพิ่มโปรแกรมลงในช่อง แนะนำให้รับชม

การอัปเดตโปรแกรม

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

ใช้ PreviewProgram.Builder เพื่อตั้งค่าแอตทริบิวต์ที่ต้องการเปลี่ยน จากนั้นเรียกใช้ getContentResolver().update เพื่ออัปเดตโปรแกรม โดยระบุรหัสโปรแกรมที่คุณบันทึกไว้เมื่อเพิ่มโปรแกรมครั้งแรก

Kotlin

context.contentResolver.update(
        TvContractCompat.buildPreviewProgramUri(programId),
                builder.build().toContentValues(), null, null
)

Java

context.getContentResolver().update(TvContractCompat.buildPreviewProgramUri(programId),
    builder.build().toContentValues(), null, null);

การลบโปรแกรม

Kotlin

context.contentResolver
        .delete(TvContractCompat.buildPreviewProgramUri(programId), null, null)

Java

context.getContentResolver().delete(TvContractCompat.buildPreviewProgramUri(programId), null, null);

การจัดการการดำเนินการของผู้ใช้

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

การค้นพบและการเพิ่มช่อง

แอปของคุณสามารถแสดงองค์ประกอบ UI ที่ช่วยให้ผู้ใช้เลือกและเพิ่มช่องของแอปได้ (เช่น ปุ่มที่ขอให้เพิ่มช่อง)

หลังจากที่ผู้ใช้ขอช่องที่เฉพาะเจาะจงแล้ว ให้เรียกใช้โค้ดนี้เพื่อขอสิทธิ์จากผู้ใช้ในการเพิ่มช่องลงใน UI ของหน้าจอหลัก

Kotlin

val intent = Intent(TvContractCompat.ACTION_REQUEST_CHANNEL_BROWSABLE)
intent.putExtra(TvContractCompat.EXTRA_CHANNEL_ID, channelId)
try {
  activity.startActivityForResult(intent, 0)
} catch (e: ActivityNotFoundException) {
  // handle error
}

Java

Intent intent = new Intent(TvContractCompat.ACTION_REQUEST_CHANNEL_BROWSABLE);
intent.putExtra(TvContractCompat.EXTRA_CHANNEL_ID, channelId);
try {
   activity.startActivityForResult(intent, 0);
} catch (ActivityNotFoundException e) {
  // handle error
}

ระบบจะแสดงกล่องโต้ตอบที่ขอให้ผู้ใช้อนุมัติช่อง จัดการผลลัพธ์ของคำขอในเมธอด onActivityResult ของกิจกรรม (Activity.RESULT_CANCELED หรือ Activity.RESULT_OK)

เหตุการณ์ในหน้าจอหลักของ Android TV

เมื่อผู้ใช้โต้ตอบกับโปรแกรมและช่องที่แอปเผยแพร่ หน้าจอหลักจะส่ง Intent ไปยังแอปดังนี้

  • หน้าจอหลักจะส่ง Uri ที่จัดเก็บไว้ในแอตทริบิวต์ APP_LINK_INTENT_URI ของช่องไปยังแอปเมื่อผู้ใช้เลือกโลโก้ของช่อง แอปควรเปิด UI หลักหรือมุมมองที่เกี่ยวข้องกับช่องที่เลือก
  • หน้าจอหลักจะส่ง Uri ที่จัดเก็บไว้ในแอตทริบิวต์ INTENT_URI ของโปรแกรมไปยังแอปเมื่อผู้ใช้เลือกโปรแกรม แอปควรเล่นเนื้อหาที่เลือก
  • ผู้ใช้สามารถระบุว่าไม่สนใจโปรแกรมอีกต่อไปและต้องการนำโปรแกรมออกจาก UI ของหน้าจอหลัก ระบบจะนำโปรแกรมออกจาก UI และส่ง Intent (android.media.tv.ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED หรือ android.media.tv.ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED) พร้อมรหัสของโปรแกรมไปยังแอปที่เป็นเจ้าของโปรแกรม แอปควรนำโปรแกรมออกจากผู้ให้บริการและไม่ควรแทรกโปรแกรมกลับเข้าไปอีก

อย่าลืมสร้างตัวกรอง Intent สำหรับ Uris ทั้งหมดที่หน้าจอหลัก ส่งสำหรับการโต้ตอบของผู้ใช้ เช่น

<receiver
   android:name=".WatchNextProgramRemoved"
   android:enabled="true"
   android:exported="true">
   <intent-filter>
       <action android:name="android.media.tv.ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED" />
   </intent-filter>
</receiver>

ข้อพิจารณาเพิ่มเติม

  • แอปทีวีหลายแอปกำหนดให้ผู้ใช้ต้องเข้าสู่ระบบ ในกรณีนี้ BroadcastReceiver ที่รอรับ android.media.tv.action.INITIALIZE_PROGRAMS ควรแนะนำเนื้อหาช่องสำหรับผู้ใช้ที่ไม่ได้ตรวจสอบสิทธิ์ เช่น แอปของคุณสามารถแสดงเนื้อหาที่ดีที่สุดหรือเนื้อหาที่กำลังได้รับความนิยมในปัจจุบันได้ในตอนแรก หลังจากที่ผู้ใช้เข้าสู่ระบบแล้ว แอปจะแสดงเนื้อหาที่ปรับตามโปรไฟล์ของผู้ใช้ได้ นี่เป็นโอกาสที่ดีสำหรับแอปในการเสนอขายสินค้าและบริการเพิ่มเติมแก่ผู้ใช้ก่อนที่ผู้ใช้จะเข้าสู่ระบบ
  • เมื่อแอปไม่ได้ทำงานอยู่เบื้องหน้าและคุณต้องอัปเดตช่องหรือโปรแกรม ให้ใช้ JobScheduler เพื่อกำหนดเวลาการทำงาน (ดู JobScheduler และ JobService)
  • ระบบสามารถเพิกถอนสิทธิ์ของผู้ให้บริการของแอปได้หากแอปทำงานไม่ถูกต้อง (เช่น สแปมข้อมูลไปยังผู้ให้บริการอย่างต่อเนื่อง) โปรดตรวจสอบว่าคุณได้ใส่โค้ดที่เข้าถึงผู้ให้บริการไว้ในคําสั่ง try-catch เพื่อจัดการข้อยกเว้นด้านความปลอดภัย
  • ก่อนอัปเดตโปรแกรมและช่อง ให้ค้นหาข้อมูลที่ต้องการอัปเดตจากผู้ให้บริการและปรับข้อมูลให้ตรงกัน เช่น ไม่จำเป็นต้องอัปเดตโปรแกรมที่ผู้ใช้ต้องการนำออกจาก UI ใช้การทำงานเบื้องหลังที่แทรกหรืออัปเดตข้อมูลลงในผู้ให้บริการหลังจากค้นหาข้อมูลที่มีอยู่แล้ว จากนั้นขออนุมัติช่อง คุณสามารถเรียกใช้การทำงานนี้เมื่อแอปเริ่มต้นและเมื่อใดก็ตามที่แอปต้องอัปเดตข้อมูล

Kotlin

context.contentResolver
      .query(
          TvContractCompat.buildChannelUri(channelId),
              null, null, null, null).use({
                  cursor-> if (cursor != null and cursor.moveToNext()) {
                                val channel = Channel.fromCursor(cursor)
                                if (channel.isBrowsable()) {
                                    //update channel's programs
                                }
                            }
              })

Java

try (Cursor cursor = context.getContentResolver()
          .query(
              TvContractCompat.buildChannelUri(channelId),
              null,
              null,
              null,
              null)) {
                  if (cursor != null &amp;&amp; cursor.moveToNext()) {
                      Channel channel = Channel.fromCursor(cursor);
                      if (channel.isBrowsable()) {
                          //update channel's programs
                      }
                  }
              }
  • ใช้ Uri ที่ไม่ซ้ำกันสำหรับรูปภาพทั้งหมด (โลโก้ ไอคอน รูปภาพเนื้อหา) และอย่าลืมใช้ Uri อื่นเมื่ออัปเดตรูปภาพ ระบบจะแคชรูปภาพทั้งหมด หากคุณไม่เปลี่ยน Uri เมื่อเปลี่ยนรูปภาพ รูปภาพเก่าจะยังคงปรากฏอยู่

  • โปรดทราบว่าไม่อนุญาตให้ใช้คําสั่ง WHERE และการเรียกผู้ให้บริการด้วยคําสั่ง WHERE จะทำให้เกิดข้อยกเว้นด้านความปลอดภัย

แอตทริบิวต์

ส่วนนี้จะอธิบายแอตทริบิวต์ของช่องและโปรแกรมแยกกัน

แอตทริบิวต์ของช่อง

คุณต้องระบุแอตทริบิวต์ต่อไปนี้สำหรับทุกช่อง

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

นอกจากนี้ ช่องยังมีช่องที่สงวนไว้ 6 ช่องสำหรับการใช้งานแอปภายใน คุณสามารถใช้ช่องเหล่านี้เพื่อจัดเก็บคีย์หรือค่าอื่นๆ ที่ช่วยให้แอปจับคู่ช่องกับโครงสร้างข้อมูลภายในได้

  • INTERNAL_PROVIDER_ID
  • INTERNAL_PROVIDER_DATA
  • INTERNAL_PROVIDER_FLAG1
  • INTERNAL_PROVIDER_FLAG2
  • INTERNAL_PROVIDER_FLAG3
  • INTERNAL_PROVIDER_FLAG4

แอตทริบิวต์ของโปรแกรม

ดูหน้าแต่ละหน้าสำหรับแอตทริบิวต์ของโปรแกรมแต่ละประเภท

โค้ดตัวอย่าง

ดูข้อมูลเพิ่มเติมเกี่ยวกับการสร้างแอปที่โต้ตอบกับหน้าจอหลัก รวมถึงการเพิ่ม ช่องและโปรแกรมลงในหน้าจอหลักของ Android TV ได้ที่ Codelab หน้าจอหลัก