ย้ายข้อมูลแอปผู้ส่ง Android จาก Cast SDK v2 ไปยัง Cast Application Framework (CAF)

ขั้นตอนต่อไปนี้จะช่วยให้คุณสามารถแปลงแอปผู้ส่ง Android จาก Cast SDK v2 เป็น CAF Sender โดยอิงตาม Singleton ของ CastContext

SDK ผู้ส่ง CAF ของแคสต์ใช้ CastContext เพื่อจัดการ GoogleAPIClient ในนามของคุณ CastContext จะจัดการวงจรการใช้งาน ข้อผิดพลาด และการเรียกกลับให้คุณ ซึ่งช่วยให้การพัฒนาแอป Cast ง่ายขึ้นอย่างมาก

เกริ่นนำ

  • ผู้ส่ง CAF จะยังคงกระจายอยู่เป็นส่วนหนึ่งของบริการ Google Play โดยใช้ Android SDK Manager
  • เพิ่มแพ็กเกจใหม่ที่รับผิดชอบในการปฏิบัติตามรายการตรวจสอบการออกแบบของ Google Cast (com.google.android.gms.cast.framework.*)
  • ผู้ส่ง CAF มีวิดเจ็ตที่เป็นไปตามข้อกำหนด UX ของ Cast v2 ไม่มีคอมโพเนนต์ UI ใดๆ และคุณจะต้องใช้วิดเจ็ตเหล่านี้
  • ไม่จำเป็นต้องใช้ GoogleApiClient ในการใช้ Cast API อีกต่อไป
  • คำบรรยายใน CAF Sender จะคล้ายกับเวอร์ชัน 2

การอ้างอิง

V2 และ CAF มีการขึ้นต่อกันของไลบรารีการสนับสนุนและบริการ Google Play (9.2.0 ขึ้นไป) ตามที่อธิบายไว้ในคู่มือฟีเจอร์ของไลบรารีการสนับสนุน

Android SDK เวอร์ชันต่ำสุดที่ CAF รองรับคือ 9 (Gingerbread)

การเริ่มต้น

ใน CAF จำเป็นต้องมีขั้นตอนการเริ่มต้นอย่างชัดเจนสำหรับเฟรมเวิร์ก Cast การดำเนินการนี้เกี่ยวข้องกับการเริ่มต้น CastContext Singleton โดยใช้ OptionsProvider เพื่อระบุรหัสแอปพลิเคชันเว็บรีซีฟเวอร์และตัวเลือกอื่นๆ ส่วนกลาง

public class CastOptionsProvider implements OptionsProvider {

    @Override
    public CastOptions getCastOptions(Context context) {
        return new CastOptions.Builder()
                .setReceiverApplicationId(context.getString(R.string.app_id))
                .build();
    }

    @Override
    public List<SessionProvider> getAdditionalSessionProviders(Context context) {
        return null;
    }
}

ประกาศ OptionsProvider ภายในแท็ก "แอปพลิเคชัน" ของไฟล์แอป AndroidManifest.xml ดังนี้

<application>
...
    <meta-data
        android:name=
            "com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
        android:value="com.google.sample.cast.refplayer.CastOptionsProvider" />
</application>

เริ่มต้น CastContext แบบ Lazi ในเมธอด onCreate ของแต่ละกิจกรรม:

private CastContext mCastContext;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.video_browser);
    setupActionBar();

    mCastContext = CastContext.getSharedInstance(this);
}

คุณไม่จำเป็นต้องทำตามขั้นตอนเหล่านี้ในเวอร์ชัน 2

การค้นหาอุปกรณ์

ใน CAF กระบวนการสำรวจจะเริ่มต้นและหยุดโดยอัตโนมัติจากเฟรมเวิร์กเมื่อแอปมาที่เบื้องหน้าและไปยังเบื้องหลังตามลำดับ ไม่ควรใช้ MediaRouteSelector และ MediaRouter.Callback

ปุ่มแคสต์และกล่องโต้ตอบแคสต์

เช่นเดียวกับเวอร์ชัน 2 คอมโพเนนต์เหล่านี้จะมีมาจากไลบรารีการสนับสนุน MediaRouter

ปุ่ม "แคสต์" จะยังคงใช้งานโดย MediaRouteButton และสามารถเพิ่มไปยังกิจกรรมได้ (โดยใช้ ActionBar หรือ Toolbar) เป็นรายการในเมนูในเมนู

<item
    android:id="@+id/media_route_menu_item"
    android:title="@string/media_route_menu_title"
    app:actionProviderClass="android.support.v7.app.MediaRouteActionProvider"
    app:showAsAction="always"/>

ลบล้างเมธอด onCreateOptionMenu() ของแต่ละกิจกรรมโดยใช้ CastButtonFactory เพื่อต่อสาย MediaRouteButton ไปยังเฟรมเวิร์กการแคสต์

private MenuItem mediaRouteMenuItem;

public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    getMenuInflater().inflate(R.menu.browse, menu);
    mediaRouteMenuItem =
        CastButtonFactory.setUpMediaRouteButton(getApplicationContext(),
                                                menu,
                                                R.id.media_route_menu_item);
    return true;
}

เมื่อมีผู้แตะปุ่ม กล่องโต้ตอบแคสต์จะแสดงขึ้นโดยอัตโนมัติ

ส่วนควบคุมอุปกรณ์

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

คลาส CastSession แสดงถึงเซสชันที่มีอุปกรณ์แคสต์ ชั้นเรียนนี้มีเมธอดสำหรับการควบคุมระดับเสียงของอุปกรณ์และสถานะปิดเสียง ซึ่งก่อนหน้านี้ทำใน v2 โดยใช้เมธอดใน Cast.CastApi

ในเวอร์ชัน 2 การเรียกกลับของ Cast.Listener จะแสดงการแจ้งเตือนการเปลี่ยนแปลงสถานะของอุปกรณ์ ซึ่งรวมถึงระดับเสียง สถานะปิดเสียง สถานะการสแตนด์บาย ฯลฯ

ใน CAF การแจ้งเตือนการเปลี่ยนสถานะระดับเสียง/ปิดเสียงจะยังคงส่งผ่านวิธีการเรียกกลับใน Cast.Listener โดย Listener เหล่านี้ลงทะเบียนไว้กับ CastSession การแจ้งเตือนสถานะของอุปกรณ์ที่เหลืออยู่ทั้งหมดจะส่งผ่านการเรียกกลับ CastStateListener ซึ่ง Listener เหล่านี้ลงทะเบียนไว้กับ CastSession ตรวจสอบว่าคุณยังคงยกเลิกการลงทะเบียน Listener เมื่อ Fragment กิจกรรม หรือแอปที่เกี่ยวข้องไปที่พื้นหลัง

ตรรกะการเชื่อมต่ออีกครั้ง

CAF จะพยายามเชื่อมต่อเครือข่ายที่สูญเสียไปเนื่องจากสูญเสียสัญญาณ Wi-Fi ชั่วคราวหรือมีข้อผิดพลาดอื่นๆ เกี่ยวกับเครือข่าย เช่นเดียวกับเวอร์ชัน 2 การดำเนินการนี้จะทำได้ในระดับเซสชัน โดยเซสชันจะเข้าสู่สถานะ "ถูกระงับ" เมื่อสูญเสียการเชื่อมต่อ และจะเปลี่ยนกลับไปเป็นสถานะ "เชื่อมต่อแล้ว" เมื่อมีการคืนค่าการเชื่อมต่อ โดยเฟรมเวิร์กนี้จะดูแลการเชื่อมต่อกับแอปพลิเคชันตัวรับสัญญาณเว็บอีกครั้ง และเชื่อมต่อช่อง Cast ใหม่ในขั้นตอนนี้

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

การลงทะเบียนแชแนลที่กำหนดเอง

ในเวอร์ชัน 2 แชแนลที่กำหนดเอง (ใช้งานโดยใช้ Cast.MessageReceivedCallback) จะได้รับการลงทะเบียนกับ Cast.CastApi ใน CAF แชแนลที่กำหนดเองจะได้รับการลงทะเบียนกับอินสแตนซ์ CastSession แทน การลงทะเบียนสามารถทำได้ในวิธีติดต่อกลับของ SessionManagerListener.onSessionStarted สำหรับแอปพลิเคชันสื่อ คุณไม่จำเป็นต้องลงทะเบียนช่องทางควบคุมสื่อผ่าน Cast.CastApi.setMessageReceivedCallbacks อย่างชัดแจ้งอีกต่อไป โปรดดูรายละเอียดเพิ่มเติมในส่วนต่อไปนี้

ส่วนควบคุมสื่อ

เราเลิกใช้งานคลาส v2 RemoteMediaPlayer ไปแล้วและไม่ควรใช้ ใน CAF จะมีคลาส RemoteMediaClient ใหม่มาแทนที่ ซึ่งจะมีฟังก์ชันการทำงานที่เทียบเท่ากันใน API ที่สะดวกกว่า คุณไม่จำเป็นต้องเริ่มต้นหรือลงทะเบียนออบเจ็กต์นี้อย่างชัดแจ้ง เฟรมเวิร์กจะสร้างอินสแตนซ์ของออบเจ็กต์โดยอัตโนมัติและลงทะเบียนแชนเนลสื่อที่สำคัญในเวลาเริ่มต้นเซสชันหากแอปพลิเคชัน Web Agent ที่เชื่อมต่ออยู่รองรับเนมสเปซของสื่อ

คุณสามารถเข้าถึง RemoteMediaClient ได้ด้วยเมธอด getRemoteMediaClient ของออบเจ็กต์ CastSession

ในเวอร์ชัน 2 คำขอสื่อทั้งหมดที่ออกใน RemoteMediaPlayer จะแสดงผล RemoteMediaPlayer.MediaChannelResult ผ่านโค้ดเรียกกลับ PendingResult

ใน CAF คำขอสื่อทั้งหมดที่ออกใน RemoteMediaClient จะแสดงผล RemoteMediaClient.MediaChannelResult ผ่านการเรียกกลับ PendingResult ซึ่งสามารถใช้เพื่อติดตามความคืบหน้าและผลลัพธ์สุดท้ายของคำขอ

RemoteMediaPlayer เวอร์ชัน 2 จะส่งการแจ้งเตือนเกี่ยวกับการเปลี่ยนแปลงสถานะของโปรแกรมเล่นสื่อในเว็บรีซีฟเวอร์ผ่าน RemoteMediaPlayer.OnStatusUpdatedListener

ใน CAF นั้น RemoteMediaClient ให้โค้ดเรียกกลับที่เทียบเท่าผ่านอินเทอร์เฟซ RemoteMediaClient.Listener คุณลงทะเบียน Listener กับ RemoteMediaClient ได้กี่รายการก็ได้ ซึ่งทำให้คอมโพเนนต์ของผู้ส่งหลายรายแชร์อินสแตนซ์เดียวของ RemoteMediaClient ที่เชื่อมโยงกับเซสชันได้

ในเวอร์ชัน 2 แอปพลิเคชันของผู้ส่งต้องรับภาระในการดูแลอินเทอร์เฟซผู้ใช้ให้สอดคล้องกับสถานะของโปรแกรมเล่นสื่อในเว็บรีซีฟเวอร์

ใน CAF ชั้นเรียน UIMediaController รับหน้าที่ส่วนใหญ่นี้

โฆษณาซ้อนทับแนะนำ

V2 ไม่มี UI แนะนำการวางซ้อน

CAF มีมุมมองที่กำหนดเอง IntroductoryOverlay เพื่อไฮไลต์ปุ่ม "แคสต์" เมื่อแสดงต่อผู้ใช้เป็นครั้งแรก

มินิคอนโทรลเลอร์

ในเวอร์ชัน 2 คุณต้องใช้ตัวควบคุมขนาดเล็กตั้งแต่ต้นในแอปผู้ส่ง

ใน CAF นั้น SDK จะมีมุมมองที่กำหนดเอง MiniControllerFragment ซึ่งคุณสามารถเพิ่มลงในไฟล์เลย์เอาต์แอปของกิจกรรมที่คุณต้องการแสดงตัวควบคุมขนาดเล็กได้

การแจ้งเตือนและหน้าจอล็อก

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

ใน CAF จะมี NotificationsOptions.Builder ที่จะช่วยคุณสร้างการควบคุมสื่อสำหรับการแจ้งเตือนและหน้าจอล็อกในแอปผู้ส่ง คุณสามารถเปิดใช้การควบคุมการแจ้งเตือนและหน้าจอล็อกได้ด้วย CastOptions เมื่อเริ่มต้น CastContext

public CastOptions getCastOptions(Context context) {
    NotificationOptions notificationOptions = new NotificationOptions.Builder()
            .setTargetActivityClassName(VideoBrowserActivity.class.getName())
            .build();
    CastMediaOptions mediaOptions = new CastMediaOptions.Builder()
            .setNotificationOptions(notificationOptions)
            .build();

    return new CastOptions.Builder()
            .setReceiverApplicationId(context.getString(R.string.app_id))
            .setCastMediaOptions(mediaOptions)
            .build();
}

ตัวควบคุมแบบขยาย

ในเวอร์ชัน 2 คุณต้องใช้ตัวควบคุมแบบขยายตั้งแต่ต้นในแอปผู้ส่ง

CAF มีคลาสผู้ช่วย UIMediaController ที่จะช่วยให้คุณสร้างตัวควบคุมแบบขยายของตนเองได้อย่างง่ายดาย

CAF เพิ่มวิดเจ็ตตัวควบคุมแบบขยายที่สร้างขึ้นล่วงหน้า ExpandedControllerActivity ซึ่งคุณเพิ่มลงในแอปได้ง่ายๆ โดยไม่จำเป็นต้อง ใช้ตัวควบคุมแบบขยายแบบกำหนดเองโดยใช้ UIMediaController อีกต่อไป

โฟกัสอัตโนมัติ

ในเวอร์ชัน 2 คุณต้องใช้ MediaSessionCompat เพื่อจัดการโฟกัสของเสียง

ใน CAF การโฟกัสเสียงจะได้รับการจัดการโดยอัตโนมัติ

การบันทึกการแก้ไขข้อบกพร่อง

ใน CAF ไม่มีตัวเลือกในการบันทึก

แอปตัวอย่าง

เรามีบทแนะนำ Codelab และแอปตัวอย่างที่ใช้ CAF