ขั้นตอนต่อไปนี้ช่วยให้คุณแปลงแอปผู้ส่ง Android จาก Cast SDK v2 เป็น CCL เป็น CAF ระบบใช้ฟังก์ชันทั้งหมดของ CCL ใน CAF แล้ว ดังนั้นเมื่อย้ายข้อมูลแล้วก็ไม่จําเป็นต้องใช้ CCL อีกต่อไป
Cast CAF Sender SDK ใช้ CastContext เพื่อจัดการ GoogleAPIClient ในนามของคุณ CastContext จะจัดการวงจร ข้อผิดพลาด และการติดต่อกลับให้คุณ ซึ่งช่วยให้พัฒนาแอปแคสต์ได้ง่ายขึ้น
บทนำ
- เนื่องจากการออกแบบ CAF Sender ได้รับอิทธิพลจาก Cast Companion Library การย้ายข้อมูลจาก CCL ไปยัง CAF Sender เกี่ยวข้องกับการแมปชั้นเรียนและเมธอดเหล่านั้นแบบตัวต่อตัว
- ผู้ส่ง CAF จะยังกระจายอยู่ในบริการ Google Play โดยใช้ตัวจัดการ SDK ของ Android
- แพ็กเกจใหม่ (
com.google.android.gms.cast.framework.*
) ที่เพิ่มลงใน GoogleF Sender ด้วยฟังก์ชันที่คล้ายกับ CCL มีหน้าที่รับผิดชอบต่อการปฏิบัติตามรายการตรวจสอบการออกแบบ Google Cast - ผู้ส่ง CAF มีวิดเจ็ตที่สอดคล้องกับข้อกําหนดของ Cast UX วิดเจ็ตเหล่านี้คล้ายกับวิดเจ็ตที่ CCL ระบุไว้
- ผู้ส่ง CAF มีการโค้ดเรียกกลับแบบไม่พร้อมกันซึ่งคล้ายกับ CCL เพื่อติดตามสถานะและรับข้อมูล CAF Sender ต่างจากการใช้ CCL ตรงที่ไม่มีวิธีการต่างๆ ที่ใช้อินเทอร์เฟซ
ส่วนต่อไปนี้เราจะเน้นแอปพลิเคชันที่เน้นวิดีโอเป็นหลักโดยอิงจาก VideoCastManager ของ CCL แต่ในหลายกรณีแนวคิดเดียวกันก็มีผลกับ DataCastManager ด้วย
การอ้างอิง
CCL และ CAF ใช้ทรัพยากร Dependency เดียวกันในไลบรารีการสนับสนุน AppCompat, ไลบรารีการสนับสนุน MediaRouter v7 และบริการ Google Play แต่ความแตกต่างก็คือ CAF จะขึ้นอยู่กับเฟรมเวิร์ก Cast ใหม่ที่พร้อมใช้งานในบริการ Google Play 9.2.0 ขึ้นไป
ในไฟล์ build.gradle ให้นําทรัพยากร Dependency ใน com.google.android.gms:play-services-cast
และ com.google.android.libraries.cast.companionlibrary:ccl
ออก จากนั้นเพิ่มเฟรมเวิร์กของ Cast ใหม่
dependencies {
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:mediarouter-v7:23.4.0'
compile 'com.google.android.gms:play-services-cast-framework:9.4.0'
}
นอกจากนี้ คุณยังนําข้อมูลเมตาของบริการ Google Play ออกได้ด้วย
<meta‐data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>
ระบบจะรวมบริการ กิจกรรม และทรัพยากรที่เป็นส่วนหนึ่งของ CAF เข้ากับไฟล์ Manifest และทรัพยากรของแอปโดยอัตโนมัติ
เวอร์ชัน Android SDK ขั้นต่ําที่ CAF รองรับคือ 9 (Gingerburger) เวอร์ชัน Android SDK ขั้นต่ําของ CCL คือ 10 รายการ
CCL มีวิธีการที่สะดวก
BaseCastManager.checkGooglePlayServices(activity)
เพื่อยืนยันว่าบริการ Google Play เวอร์ชันที่เข้ากันได้พร้อมให้บริการในอุปกรณ์ CAF ไม่ได้จัดเตรียมข้อมูลนี้ไว้เป็นส่วนหนึ่งของ Cast SDK ทําตามขั้นตอน
ตรวจสอบว่าอุปกรณ์มี APK ของบริการ Google Play
เพื่อตรวจดูว่ามีการติดตั้ง APK ของบริการ Google Play ที่ถูกต้องในอุปกรณ์ของผู้ใช้ เนื่องจากการอัปเดตอาจไม่เข้าถึงผู้ใช้ทั้งหมดทันที
คุณยังคงต้องใช้ตัวแปรของ Theme.AppCompat สําหรับธีมของแอปพลิเคชัน
การเริ่มต้น
สําหรับ CCL ต้องมีการเรียก VideoCastManager.initialize()
ในเมธอด onCreate()
ของอินสแตนซ์แอปพลิเคชัน ตรรกะนี้ควรนําออกจากโค้ดคลาสแอปพลิเคชัน
ใน CAF คุณจําเป็นต้องระบุขั้นตอนการแคสต์อย่างชัดแจ้งสําหรับเฟรมเวิร์ก "แคสต์" ซึ่งรวมถึงการเริ่มต้น CastContext
Singleton โดยใช้ OptionsProvider
ที่เหมาะสมเพื่อระบุรหัสแอปพลิเคชันของผู้รับและตัวเลือกอื่นๆ ทั่วโลก CastContext
มีบทบาทคล้ายกับ CCL
VideoCastManager
โดยการระบุ Singleton ที่ลูกค้าโต้ตอบด้วย
OptionsProvider
คล้ายกับ CastConfiguration
ของ CCL เพื่อช่วยให้คุณกําหนดค่าฟีเจอร์เฟรมเวิร์กแคสต์ได้
หาก CCL ปัจจุบัน CastConfiguration.Builder
มีลักษณะดังนี้
VideoCastManager.initialize(
getApplicationContext(),
new CastConfiguration.Builder(context.getString(R.string.app_id))
.enableWifiReconnection()
.enableAutoReconnect()
.build());
จากนั้นใน CAF CastOptionsProvider
ต่อไปนี้โดยใช้ CastOptions.Builder
จะคล้ายกัน
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;
}
}
อ่านแอปตัวอย่างเพื่อดูการใช้งาน OptionProvider ที่สมบูรณ์
ประกาศ OptionProvider ภายในองค์ประกอบ "application" ของไฟล์ 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
ด้วยตนเองในเมธอด onCreate
ของ Activity
แต่ละรายการ
(ไม่ใช่อินสแตนซ์ Application
) ดังนี้
private CastContext mCastContext;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video_browser);
setupActionBar();
mCastContext = CastContext.getSharedInstance(this);
}
วิธีเข้าถึงการใช้งาน Singleton CastContext
mCastContext = CastContext.getSharedInstance(this);
การค้นหาอุปกรณ์
ควรนํา VideoCastManager
incrementUiCounter
และ decrementUiCounter
ของ CCL ออกจากเมธอด onResume
และ onPause
ของ Activities
ใน CAF กระบวนการเริ่มระบบจะเริ่มและหยุดโดยอัตโนมัติเมื่อเฟรมเวิร์กทํางานเมื่อแอปทํางานอยู่เบื้องหน้าและไปอยู่ที่พื้นหลังตามลําดับ
ปุ่ม "แคสต์" และกล่องโต้ตอบการแคสต์
เช่นเดียวกับ CCL คอมโพเนนต์เหล่านี้มีไว้สําหรับไลบรารีการรองรับ MediaRouter v7
MediaRouteButton
ยังใช้ปุ่ม "แคสต์" อยู่ และสามารถเพิ่มลงในกิจกรรม (โดยใช้ ActionBar
หรือ Toolbar
) เป็นรายการเมนูในเมนู
การประกาศ MediaRouteActionProvider
ใน XML ของเมนูจะเหมือนกับ CCL
<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"/>
เช่นเดียวกับ CCL, ลบล้างเมธอด onCreateOptionMenu() ของแต่ละกิจกรรม แต่แทนที่จะใช้ CastManager.addMediaRouterButton ให้ใช้ CastButtonFactory ของ CAF เพื่อต่อ MediaMediaButton กับเฟรมเวิร์ก "แคสต์"
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.browse, menu);
CastButtonFactory.setUpMediaRouteButton(getApplicationContext(),
menu,
R.id.media_route_menu_item);
return true;
}
ส่วนควบคุมอุปกรณ์
ใน CAF ใน CF การควบคุมอุปกรณ์ส่วนใหญ่ได้รับการจัดการโดยเฟรมเวิร์ก
แอปพลิเคชันของผู้ส่งไม่จําเป็นต้องจัดการ (และไม่ควรลองจัดการ)
การเชื่อมต่อกับอุปกรณ์และเปิดใช้งานแอปพลิเคชันตัวรับโดยใช้
GoogleApiClient
การโต้ตอบระหว่างผู้ส่งและผู้รับจะแสดงเป็น "เซสชัน" คลาส SessionManager
จัดการวงจรเซสชันและเริ่มโดยอัตโนมัติและหยุดเซสชันตามท่าทางสัมผัสของผู้ใช้ โดยเซสชันจะเริ่มต้นขึ้นเมื่อผู้ใช้เลือกอุปกรณ์แคสต์ในกล่องโต้ตอบแคสต์ และจะสิ้นสุดเมื่อผู้ใช้แตะปุ่ม "หยุดแคสต์" ในกล่องโต้ตอบแคสต์หรือเมื่อแอปของผู้ส่งสิ้นสุด
ใน CCL คุณจะต้องขยายคลาส VideoCastConsumerImpl
เพื่อติดตามสถานะเซสชันการแคสต์ ดังนี้
private final VideoCastConsumer mCastConsumer = new VideoCastConsumerImpl() {
public void onApplicationConnected(ApplicationMetadata appMetadata,
String sessionId,
boolean wasLaunched) {}
public void onDisconnectionReason(int reason) {}
public void onDisconnected() {}
}
ใน CAF แอปพลิเคชันแอปพลิเคชันจะได้รับแจ้งเกี่ยวกับเหตุการณ์ในวงจรของเซสชันโดยลงทะเบียน SessionManagerListener
กับ SessionManager
โค้ดเรียกกลับของเซสชันของ ManagerManagerListener กําหนดเมธอดเรียกกลับสําหรับเหตุการณ์อายุการใช้งานของเซสชันทั้งหมด
วิธีSessionManagerListener
ต่อไปนี้แมปจากอินเทอร์เฟซ VideoCastConsumer
ของ CCL
VideoCastConsumer.onApplicationConnected
->SessionManagerListener.onSessionStarted
VideoCastConsumer.onDisconnected
->SessionManagerListener.onSessionEnded
ประกาศคลาสที่ใช้อินเทอร์เฟซ SessionManagerListener
และย้ายตรรกะ VideoCastConsumerImpl
ไปยังวิธีการที่ตรงกัน
private class CastSessionManagerListener implements SessionManagerListener<CastSession> {
public void onSessionEnded(CastSession session, int error) {}
public void onSessionStarted(CastSession session, String sessionId) {}
public void onSessionEnding(CastSession session) {}
...
}
คลาส CastSession
แสดงถึงเซสชันที่มีอุปกรณ์แคสต์ ชั้นเรียนมีวิธีควบคุมระดับเสียงของอุปกรณ์และปิดเสียงสถานะต่างๆ ซึ่ง CCL จะดําเนินการใน BaseCastManager
แทนที่จะใช้ CCL VideoCastManager
เพื่อเพิ่มผู้บริโภค ให้ทําดังนี้
VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);
ลงทะเบียน SessionManagerListener
เลย:
mCastSessionManager =
CastContext.getSharedInstance(this).getSessionManager();
mCastSessionManagerListener = new CastSessionManagerListener();
mCastSessionManager.addSessionManagerListener(mCastSessionManagerListener,
CastSession.class);
หากต้องการหยุดฟังกิจกรรมใน CCL ให้ทําดังนี้
VideoCastManager.getInstance().removeVideoCastConsumer(mCastConsumer);
ปัจจุบันให้ใช้ SessionManager
เพื่อหยุดฟังเหตุการณ์ของเซสชัน
mCastSessionManager.removeSessionManagerListener(mCastSessionManagerListener,
CastSession.class);
หากต้องการยกเลิกการเชื่อมต่อกับอุปกรณ์แคสต์อย่างชัดเจน CCL ใช้
VideoCastManager.disconnectDevice(boolean stopAppOnExit,
boolean clearPersistedConnectionData,
boolean setDefaultRoute)
สําหรับ CAF ให้ใช้ SessionManager
CastContext.getSharedInstance(this).getSessionManager()
.endCurrentSession(true);
หากต้องการทราบว่าผู้ส่งเชื่อมต่อกับผู้รับหรือไม่ CCL จะให้
VideoCastManager.getInstance().isConnected()
แต่ใน CAF ให้ใช้ SessionManager
public boolean isConnected() {
CastSession castSession = CastContext.getSharedInstance(mAppContext)
.getSessionManager()
.getCurrentCastSession();
return (castSession != null && castSession.isConnected());
}
ใน CAF การแจ้งเตือนการเปลี่ยนแปลงระดับเสียง/ปิดเสียงจะยังส่งผ่านเมธอดเรียกกลับใน Cast.Listener
โดยผู้ฟังเหล่านี้ลงทะเบียนกับ CastSession
การแจ้งเตือนสถานะอุปกรณ์ที่เหลือทั้งหมดจะส่งผ่านการเรียกกลับ CastStateListener
ผู้ฟังเหล่านี้ลงทะเบียนกับ CastSession
ตรวจสอบว่าคุณยังคงยกเลิกการลงทะเบียนผู้ฟังเมื่อส่วน กิจกรรม หรือแอปที่เชื่อมโยงอยู่เบื้องหลัง
ตรรกะการเชื่อมต่ออีกครั้ง
CAF จะพยายามเชื่อมต่อเครือข่ายที่สูญหายอีกครั้งเนื่องจากสัญญาณ Wi-Fi ขาดหายชั่วคราวหรือข้อผิดพลาดอื่นๆ เกี่ยวกับเครือข่าย ซึ่งทําได้ที่ระดับเซสชัน เซสชันสามารถเข้าสู่สถานะ "ถูกระงับ" เมื่อการเชื่อมต่อขาดหาย และจะเปลี่ยนกลับไปเป็นสถานะ "เชื่อมต่อแล้ว" เมื่อมีการเชื่อมต่ออีกครั้ง โดยเฟรมเวิร์กจะเชื่อมต่ออีกครั้งกับแอปพลิเคชันตัวรับสัญญาณและเชื่อมต่อช่องแคสต์อีกครั้งระหว่างกระบวนการนี้
CAF ให้บริการการเชื่อมต่ออีกครั้ง คุณจึงนํา CCL ReconnectionService
ออกจากไฟล์ Manifest ได้
<service android:name="com.google.android.libraries.cast.companionlibrary.cast.reconnection.ReconnectionService"/>
และคุณไม่จําเป็นต้องมีสิทธิ์ต่อไปนี้ในไฟล์ Manifest สําหรับตรรกะการเชื่อมต่ออีกครั้ง
<uses‐permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses‐permission android:name="android.permission.ACCESS_WIFI_STATE"/>
บริการเชื่อมต่อ CAF อีกครั้งจะเปิดอยู่โดยค่าเริ่มต้น แต่คุณปิดใช้ได้โดยใช้ CastOptions
นอกจากนี้ CAF ยังมีการเพิ่มการเริ่มเซสชันอัตโนมัติซึ่งเปิดใช้โดยค่าเริ่มต้นด้วย (และสามารถปิดใช้งานผ่าน CastOptions
) หากแอปพลิเคชันของผู้ส่งส่งไปยังพื้นหลังหรือถูกสิ้นสุดการใช้งาน (ด้วยการปัดออกหรือเนื่องจากมีข้อขัดข้อง) ในระหว่างเซสชันการแคสต์ เฟรมเวิร์กจะพยายามกลับมาทํางานอีกครั้งเมื่อแอปพลิเคชันของผู้ส่งกลับไปทํางานเบื้องหน้าหรือเปิดใช้อีกครั้ง ซึ่งจะจัดการโดยอัตโนมัติตาม SessionManager
ซึ่งจะเรียกใช้ใน SessionManager
โดยอัตโนมัติ
การลงทะเบียนแชแนลที่กําหนดเอง
CCL มี 2 วิธีสร้างแชแนลข้อความที่กําหนดเองไปยังผู้รับ ดังนี้
CastConfiguration
ให้คุณระบุเนมสเปซหลายรายการ แล้ว CCL จะสร้างช่องให้คุณDataCastManager
คล้ายกับ VideoCastManager แต่มุ่งเน้นกรณีการใช้งานที่ไม่ใช่สื่อ
CAF ทั้ง 2 วิธีนี้ไม่รองรับการสร้างแชแนลที่กําหนดเอง ดังนั้นคุณต้องทําตามขั้นตอน เพิ่มแชแนลที่กําหนดเองสําหรับแอปของผู้ส่งแทน
เช่นเดียวกับ CCL สําหรับแอปพลิเคชันสื่อ คุณไม่ต้องลงทะเบียนช่องทางควบคุมสื่ออย่างชัดแจ้ง
ส่วนควบคุมสื่อ
ใน CAF คลาส RemoteMediaClient
เทียบเท่ากับเมธอดสื่อ VideoCastManager
RemoteMediaClient.Listener
เทียบเท่ากับเมธอด VideoCastConsumer
โดยเฉพาะอย่างยิ่ง เมธอด onRemoteMediaPlayerMetadataUpdated
และ onRemoteMediaPlayerStatusUpdated
ของ VideoCastConsumer
จะแมปกับเมธอด onMetadataUpdated
และ onStatusUpdated
ของ RemoteMediaClient.Listener
ตามลําดับ
private class CastMediaClientListener implements RemoteMediaClient.Listener {
@Override
public void onMetadataUpdated() {
setMetadataFromRemote();
}
@Override
public void onStatusUpdated() {
updatePlaybackState();
}
@Override
public void onSendingRemoteMediaRequest() {
}
@Override
public void onQueueStatusUpdated() {
}
@Override
public void onPreloadStatusUpdated() {
}
}
ไม่จําเป็นต้องเริ่มต้นหรือลงทะเบียนออบเจ็กต์ RemoteMediaClient
อย่างชัดแจ้ง เฟรมเวิร์กจะสร้างอินสแตนซ์ของออบเจ็กต์โดยอัตโนมัติและลงทะเบียนแชแนลสื่อแทนเวลาเริ่มต้นของเซสชันหากแอปพลิเคชันตัวรับที่กําลังเชื่อมต่อรองรับเนมสเปซสื่อ
คุณจะเข้าถึง RemoteMediaClient
ได้โดยใช้เมธอด getRemoteMediaClient
ของออบเจ็กต์ CastSession
CastSession castSession = CastContext.getSharedInstance(mAppContext)
.getSessionManager()
.getCurrentCastSession();
mRemoteMediaClient = castSession.getRemoteMediaClient();
mRemoteMediaClientListener = new CastMediaClientListener();
แทนที่จะเป็น CCL
VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);
ใช้ CAF เลย
mRemoteMediaClient.addListener(mRemoteMediaClientListener);
จํานวน Listener จํานวนมากสามารถลงทะเบียนกับ RemoteMediaClient
ได้ ซึ่งทําให้คอมโพเนนต์ผู้ส่งหลายรายแชร์อินสแตนซ์ของ RemoteMediaClient
รายการเดียวที่เชื่อมโยงกับเซสชันได้
VideoCastManager
ของ CCL แสดงวิธีจัดการการเล่นสื่อ ดังนี้
VideoCastManager manager = VideoCastManager.getInstance();
if (manager.isRemoteMediaLoaded()) {
manager.pause();
mCurrentPosition = (int) manager.getCurrentMediaPosition();
}
ขณะนี้ RemoteMediaClient ติดตั้งใช้งานโดย CAF แล้ว
if (mRemoteMediaClient.hasMediaSession()) {
mRemoteMediaClient.pause();
mCurrentPosition =
(int)mRemoteMediaClient.getApproximateStreamPosition();
}
ใน CAF คําขอสื่อทั้งหมดที่ออกใน RemoteMediaClient
จะแสดง RemoteMediaClient.MediaChannelResult
ผ่านโค้ดเรียกกลับ PendingResult
ซึ่งใช้เพื่อติดตามความคืบหน้าและผลลัพธ์สุดท้ายของคําขอได้
ทั้ง CCL และ CAF ใช้คลาส MediaInfo
และ MediaMetadata
เพื่อแสดงรายการสื่อและเพื่อโหลดสื่อ
ในการโหลดสื่อใน CCL ระบบจะใช้ VideoCastManager
:
VideoCastManager.getInstance().loadMedia(media, autoPlay, mCurrentPosition, customData);
ใน CAF ระบบจะใช้ RemoteMediaClient
เพื่อโหลดสื่อ ดังนี้
mRemoteMediaClient.load(media, autoPlay, mCurrentPosition, customData);
หากต้องการรับข้อมูลและสถานะของ Media
ของเซสชันสื่อปัจจุบันในฝั่งผู้รับ CCL ใช้ VideoCastManager
ดังนี้
MediaInfo mediaInfo = VideoCastManager.getInstance()
.getRemoteMediaInformation();
int status = VideoCastManager.getInstance().getPlaybackStatus();
int idleReason = VideoCastManager.getInstance().getIdleReason();
ใน CAF ให้ใช้ RemoteMediaClient
เพื่อรับข้อมูลเดียวกัน
MediaInfo mediaInfo = mRemoteMediaClient.getMediaInfo();
int status = mRemoteMediaClient.getPlayerState();
int idleReason = mRemoteMediaClient.getIdleReason();
การวางซ้อนที่แนะนํา
เช่นเดียวกับ CCL CAF จะให้มุมมองที่กําหนดเอง IntroductoryOverlay
เพื่อไฮไลต์ปุ่ม "แคสต์" เมื่อแสดงต่อผู้ใช้เป็นครั้งแรก
แทนที่จะใช้วิธี VideoCastConsumer
onCastAvailabilityChanged
ของ CCL เพื่อให้ทราบเวลาที่จะแสดงการวางซ้อน ให้ประกาศ CastStateListener
เพื่อกําหนดว่าปุ่ม "แคสต์" จะปรากฏเมื่อใดเมื่อ MediaRouter
พบอุปกรณ์แคสต์ในเครือข่ายภายใน
private IntroductoryOverlay mIntroductoryOverlay;
private MenuItem mMediaRouteMenuItem;
protected void onCreate(Bundle savedInstanceState) {
...
mCastStateListener = new CastStateListener() {
@Override
public void onCastStateChanged(int newState) {
if (newState != CastState.NO_DEVICES_AVAILABLE) {
showIntroductoryOverlay();
}
}
};
mCastContext = CastContext.getSharedInstance(this);
mCastContext.registerLifecycleCallbacksBeforeIceCreamSandwich(this,
savedInstanceState);
}
protected void onResume() {
mCastContext.addCastStateListener(mCastStateListener);
...
}
protected void onPause() {
mCastContext.removeCastStateListener(mCastStateListener);
...
}
ติดตามอินสแตนซ์ MediaRouteMenuItem
:
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.browse, menu);
mMediaRouteMenuItem = CastButtonFactory.setUpMediaRouteButton(
getApplicationContext(), menu,
R.id.media_route_menu_item);
showIntroductoryOverlay();
return true;
}
ตรวจสอบว่ามองเห็น MediaRouteButton
หรือไม่ เพื่อให้การวางซ้อนบทนําแสดงได้
private void showIntroductoryOverlay() {
if (mIntroductoryOverlay != null) {
mIntroductoryOverlay.remove();
}
if ((mMediaRouteMenuItem != null) && mMediaRouteMenuItem.isVisible()) {
new Handler().post(new Runnable() {
@Override
public void run() {
mIntroductoryOverlay = new IntroductoryOverlay.Builder(
VideoBrowserActivity.this, mMediaRouteMenuItem)
.setTitleText(getString(R.string.introducing_cast))
.setOverlayColor(R.color.primary)
.setSingleTime()
.setOnOverlayDismissedListener(
new IntroductoryOverlay
.OnOverlayDismissedListener() {
@Override
public void onOverlayDismissed() {
mIntroductoryOverlay = null;
}
})
.build();
mIntroductoryOverlay.show();
}
});
}
}
ดูแอปตัวอย่างสําหรับโค้ดการทํางานที่สมบูรณ์สําหรับการแสดงการวางซ้อนที่แนะนํา
หากต้องการปรับแต่งการจัดรูปแบบการวางซ้อนแนะนํา ให้ทําตามขั้นตอนปรับแต่งการวางซ้อนแนะนํา
ตัวควบคุมขนาดเล็ก
แทนที่จะใช้ MiniController
ของ CCL ให้ใช้ MiniControllerFragment
ของ CAF ในไฟล์เลย์เอาต์แอปของกิจกรรมที่คุณต้องการแสดงตัวควบคุมขนาดเล็ก โดยทําดังนี้
<fragment
android:id="@+id/cast_mini_controller"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:castShowImageThumbnail="true"
android:visibility="gone"
class="com.google.android.gms.cast.framework.media.widget.MiniControllerFragment" />
CAF ไม่รองรับการกําหนดค่าด้วยตนเองที่ MiniController
ของ CCL รองรับและไม่รองรับฟีเจอร์ Autoplay
ด้วย
หากต้องการปรับแต่งการจัดรูปแบบและปุ่มของตัวควบคุมขนาดเล็ก ให้ทําตามกระบวนการปรับแต่งตัวควบคุมขนาดเล็ก
การแจ้งเตือนและหน้าจอล็อก
CAF คล้ายกับ VideoCastNotificationService
ของ CCL โดยให้บริการ MediaNotificationService
เพื่อจัดการการแสดงการแจ้งเตือนสื่อเมื่อแคสต์
คุณต้องนํารายการต่อไปนี้ออกจากไฟล์ Manifest
VideoIntentReceiver
VideoCastNotificationService
CCL รองรับการให้บริการการแจ้งเตือนที่กําหนดเองด้วย CastConfiguration.Builder
ซึ่ง CAF ไม่รองรับ
ลองใช้การเริ่มต้น CastManager
ต่อไปนี้โดยใช้ CCL
VideoCastManager.initialize(
getApplicationContext(),
new CastConfiguration.Builder(
context.getString(R.string.app_id))
.addNotificationAction(
CastConfiguration.NOTIFICATION_ACTION_PLAY_PAUSE,true)
.addNotificationAction(
CastConfiguration.NOTIFICATION_ACTION_DISCONNECT,true)
.build());
สําหรับการกําหนดค่าที่เทียบเท่าใน CAF SDK จะมี NotificationsOptions.Builder
เพื่อช่วยคุณสร้างการควบคุมสื่อสําหรับการแจ้งเตือนและหน้าจอล็อกในแอปผู้ส่ง คุณสามารถเปิดใช้การควบคุมการแจ้งเตือนและหน้าจอล็อกด้วย CastOptions
เมื่อเริ่มต้น CastContext
public CastOptions getCastOptions(Context context) {
NotificationOptions notificationOptions =
new NotificationOptions.Builder()
.setActions(Arrays.asList(
MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK,
MediaIntentReceiver.ACTION_STOP_CASTING), new int[]{0, 1})
.build();
CastMediaOptions mediaOptions = new CastMediaOptions.Builder()
.setNotificationOptions(notificationOptions)
.build();
return new CastOptions.Builder()
.setReceiverApplicationId(context.getString(R.string.app_id))
.setCastMediaOptions(mediaOptions)
.build();
}
การแจ้งเตือนและการควบคุมหน้าจอล็อกจะเปิดใช้ใน CAF เสมอ นอกจากนี้ โปรดทราบว่าจะมีปุ่มเล่น/หยุดชั่วคราวและหยุดแคสต์โดยค่าเริ่มต้น CAF จะติดตามระดับการเข้าถึงกิจกรรมเพื่อตัดสินใจว่าจะแสดงการแจ้งเตือนสื่อเมื่อใด ยกเว้น Gingerburger
(สําหรับ Gingerburger โปรดดูหมายเหตุก่อนหน้า
การใช้ registerLifecycleCallbacksBeforeIceCreamSandwich()
; CCL
VideoCastManager
incrementUiCounter
และ decrementUiCounter
ควรนําออก)
หากต้องการปรับแต่งปุ่มที่แสดงในการแจ้งเตือน ให้ทําตามขั้นตอนเพิ่มการควบคุมสื่อไปยังการแจ้งเตือนและหน้าจอล็อก
ตัวควบคุมแบบขยาย
CCL ให้ VideoCastControllerActivity
และ VideoCastControllerFragment
แสดงตัวควบคุมที่ขยายเมื่อแคสต์สื่อ
คุณนําการประกาศ VideoCastControllerActivity
ในไฟล์ Manifest ออกได้
ใน CAF คุณต้องขยายกิจกรรมExpandedController และเพิ่มปุ่มแคสต์
หากต้องการปรับแต่งรูปแบบและปุ่มที่แสดงในตัวควบคุมแบบขยาย ให้ทําตามขั้นตอนปรับแต่งตัวควบคุมที่ขยาย
โฟกัสอัตโนมัติ
โฟกัสเสียงจะจัดการโดยอัตโนมัติ เช่นเดียวกับ CCL
การควบคุมระดับเสียง
สําหรับ Gingerburger, dispatchKeyEvent
จําเป็นต้องเหมือนกับ CCL ใน ICS ขึ้นไป สําหรับทั้งการควบคุมระดับเสียง CCL และ CAF จะได้รับการจัดการโดยอัตโนมัติ
CAF ช่วยให้คุณควบคุมระดับเสียงแคสต์ผ่านปุ่มปรับระดับเสียงของโทรศัพท์ ภายในกิจกรรมบนแอปได้ ทั้งยังแสดงแถบระดับเสียงเมื่อแคสต์ในเวอร์ชันที่รองรับ CAF ยังจัดการกับการเปลี่ยนระดับเสียงผ่านระดับเสียงเพียงเล็กน้อย แม้ว่าแอปจะไม่ได้อยู่ที่ด้านหน้า ล็อกอยู่ หรือแม้หน้าจอจะปิดอยู่
คำบรรยาย
ใน Android KitKat ขึ้นไป คําบรรยายจะปรับแต่งได้ผ่านการตั้งค่าคําบรรยาย ซึ่งอยู่ในส่วนการตั้งค่า > การช่วยเหลือพิเศษ แต่ Android เวอร์ชันก่อนหน้านั้น ไม่มีความสามารถนี้ CCL จัดการปัญหานี้โดยกําหนดการตั้งค่าที่กําหนดเองสําหรับเวอร์ชันก่อนหน้าและกําหนดให้การตั้งค่าระบบใน KitKat ขึ้นไป
CAF ไม่ได้ตั้งค่าที่กําหนดเองให้เปลี่ยนค่ากําหนดของคําบรรยายวิดีโอ คุณควรนําการอ้างอิง CaptionsPreferenceActivity
ในไฟล์ Manifest และ XML ค่ากําหนดออก
ไม่จําเป็นต้องใช้ TracksChooserDialog
ของ CCL อีกต่อไป เนื่องจาก UI ของตัวควบคุมแบบขยายจะเปลี่ยนแทร็กคําบรรยาย
API คําบรรยาย ใน CAF คล้ายกับ v2
การบันทึกการแก้ไขข้อบกพร่อง
CAF ไม่ได้ตั้งค่าการบันทึกการแก้ไขข้อบกพร่อง
อื่นๆ
CAF ไม่รองรับฟีเจอร์ CCL ต่อไปนี้
- การขออนุญาตก่อนเล่นด้วยการระบุ
MediaAuthService
- ข้อความ UI ที่กําหนดค่าได้
แอปตัวอย่าง
ดู diff สําหรับการย้ายข้อมูลแอปตัวอย่าง Universal Music Player สําหรับ Android (uamp) จาก CCL ไปยัง CAF
และเรายังมีบทแนะนําเกี่ยวกับ Codelab และตัวอย่างแอปที่ใช้ CAF ด้วย