CCL Sender App को Cast ऐप्लिकेशन फ़्रेमवर्क (CAF) में माइग्रेट करें

नीचे दिए गए तरीके की मदद से, Android Android ऐप्लिकेशन को SDK टूल के v2 वर्शन से CCL में CAF में बदला जा सकता है. CCL की सभी सुविधाएं CAF में लागू कर दी गई हैं, इसलिए माइग्रेशन के बाद, आपको CCL का इस्तेमाल करने की ज़रूरत नहीं होगी.

Cast CAF Sender SDK, आपकी ओर से GoogleAPIClient को मैनेज करने के लिए CastContext का इस्तेमाल करता है. CastContext आपके लिए लाइफ़साइकल, गड़बड़ियों, और कॉलबैक को मैनेज करता है. इससे Cast ऐप्लिकेशन को डेवलप करने में बहुत आसानी होती है.

सुविधा के बारे में जानकारी

  • CAF सेंडर डिज़ाइन को Cast Companion लाइब्रेरी से प्रभावित किया गया था. इसलिए, सीसीएल से CAF सेंडर में माइग्रेट करने के लिए, क्लास और उनके तरीकों को वन-टू-वन मैपिंग में शामिल किया गया.
  • सीएएफ़ भेजने वाले को अब भी 'Android SDK मैनेजर' का इस्तेमाल करके, 'Google Play सेवाएं' के हिस्से के तौर पर उपलब्ध कराया जाता है.
  • सीसीएल भेजने वाले में ऐसे नए पैकेज (com.google.android.gms.cast.framework.*) शामिल किए गए हैं जो सीसीएल से मिलती-जुलती सुविधा के साथ जोड़े गए हैं. ये Google Cast के डिज़ाइन की चेकलिस्ट का पालन करने की ज़िम्मेदारी लेते हैं.
  • CAF की मदद से भेजने वाले लोग, UX की ज़रूरी शर्तों का पालन करने वाले विजेट उपलब्ध कराते हैं. ये विजेट, सीसीएल से मिलने वाले विजेट जैसे ही होते हैं.
  • CAF की मदद से एसिंक्रोनस कॉलबैक की मदद से, राज्यों को ट्रैक किया जा सकता है और डेटा पाया जा सकता है. इन कॉलबैक में सीसीएल से मिलता-जुलता होता है. सीसीएल भेजने वाला, सीसीएल के उलट, इंटरफ़ेस के अलग-अलग तरीकों पर कोई कार्रवाई नहीं करता है.

नीचे दिए गए सेक्शन में, हम मुख्य रूप से सीसीएल के VideoCastManager पर आधारित वीडियो आधारित ऐप्लिकेशन पर फ़ोकस करेंगे, लेकिन कई मामलों में यही सिद्धांत DataCastManager पर भी लागू होते हैं.

डिपेंडेंसी

CCL और CAF, दोनों पर एक ही डिपेंडेंसी होती है. यह AppCompat की सहायता लाइब्रेरी, MediaRouter v7 की सहायता लाइब्रेरी और Google Play सेवाओं पर निर्भर करती है. हालांकि, अंतर यह है कि CAF, Google Play सेवाओं के 9.2.0 या उसके बाद के वर्शन में उपलब्ध नए कास्ट फ़्रेमवर्क पर निर्भर करता है.

अपनी build.gradle फ़ाइल में, com.google.android.gms:play-services-cast और com.google.android.libraries.cast.companionlibrary:ccl की निर्भरता हटाएं. इसके बाद, नया कास्ट फ़्रेमवर्क जोड़ें:

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 से जुड़ी सेवाओं, गतिविधियों, और संसाधनों को आपके ऐप्लिकेशन के मेनिफ़ेस्ट और रिसॉर्स के साथ अपने-आप मर्ज कर दिया जाता है.

Android SDK टूल का सबसे कम वर्शन 9 (Gingerbread) है. साथ ही, सीसीएल में Android SDK का कम से कम 10 वर्शन है.

CCL सुविधा की मदद से, इस बात की पुष्टि की जाती है कि डिवाइस पर Google Play सेवाओं का वर्शन काम करता है या नहीं. इसके लिए, BaseCastManager.checkGooglePlayServices(activity) का इस्तेमाल किया जा सकता है. CAF, Cast SDK के हिस्से के तौर पर यह जानकारी नहीं देता है. इस प्रक्रिया का पालन करें पक्का करें कि डिवाइस में Google Play सेवाएं APK मौजूद हों ताकि यह पक्का किया जा सके कि उपयोगकर्ता के डिवाइस पर सही Google Play सेवाएं APK इंस्टॉल है, क्योंकि हो सकता है कि अपडेट सभी उपयोगकर्ताओं तक तुरंत न पहुंचें.

आपको अब भी ऐप्लिकेशन के थीम के लिए, थीम.AppCompat के वैरिएंट का इस्तेमाल करना होगा.

डेटा लेयर में इवेंट बनाने की प्रोसेस

सीसीएल के लिए, VideoCastManager.initialize(), को onCreate() इंस्टेंस में ऐप्लिकेशन इंस्टेंस के लिए कॉल करना ज़रूरी था. इस तर्क को आपके ऐप्लिकेशन के क्लास कोड से हटा दिया जाना चाहिए.

सीएएफ़ में, कास्ट फ़्रेमवर्क के लिए जानकारी को साफ़ तौर पर दिखाना भी ज़रूरी है. इसमें CastContext सिंगलटन को शुरू करना, सही OptionsProvider का इस्तेमाल करना, ताकि रिसीवर ऐप्लिकेशन आईडी और दूसरे सभी ग्लोबल विकल्प तय किए जा सकें. CastContext, सीसीएल VideoCastManager की तरह ही एक सिंगलटन देता है, जो क्लाइंट से इंटरैक्ट करता है. OptionsProvider, सीसीएल की CastConfiguration से मिलता-जुलता है. इसलिए, आपको कास्ट फ़्रेमवर्क की सुविधाएं कॉन्फ़िगर करने की अनुमति मिलेगी.

अगर आपका मौजूदा CCL CastConfiguration.Builder ऐसा दिखता है:

VideoCastManager.initialize(
   getApplicationContext(),
   new CastConfiguration.Builder(context.getString(R.string.app_id))
       .enableWifiReconnection()
       .enableAutoReconnect()
       .build());

तो CAF में CastOptions.Builder का इस्तेमाल करने वाली CastOptionsProvider एक जैसी होगी:

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 को पूरी तरह लागू करने के लिए, हमारे सैंपल ऐप्लिकेशन पर एक नज़र डालें.

AndroidManifest.xml फ़ाइल के "application" एलिमेंट में OptionProvider का एलान करें:

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

हर Activity के onCreate तरीके में लेज़ी तरीके से CastContext को शुरू करें (न कि Application इंस्टेंस):

private CastContext mCastContext;

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

    mCastContext = CastContext.getSharedInstance(this);
}

CastContext सिंगलटन के इस्तेमाल के लिए:

mCastContext = CastContext.getSharedInstance(this);

कास्ट की सुविधा वाले डिवाइस खोजना

अपने Activities के onResume और onPause तरीकों से, सीसीएल की VideoCastManager incrementUiCounter और decrementUiCounter को हटा दिया जाना चाहिए.

CAF में, खोज की प्रक्रिया फ़्रेम के ज़रिए अपने-आप शुरू हो जाती है. जब ऐप्लिकेशन फ़ोरग्राउंड पर आता है और बैकग्राउंड में जाता है, तब यह प्रक्रिया अपने-आप बंद हो जाती है.

कास्ट बटन और कास्ट डायलॉग

CCL की तरह, ये कॉम्पोनेंट MediaRouter v7 की सहायता लाइब्रेरी से भी मिलते हैं.

कास्ट बटन अब भी MediaRouteButton के ज़रिए लागू किया जाता है और इसे आपके मेन्यू में एक मेन्यू आइटम के रूप में (ActionBar या Toolbar का इस्तेमाल करके) आपकी गतिविधि में जोड़ा जा सकता है.

मेन्यू एक्सएमएल में, MediaRouteActionProvider का एलान वही है जो सीसीएल के साथ है:

<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 का इस्तेमाल करने के बजाय, MediaRouteButton को कास्ट फ़्रेमवर्क में लाने के लिए, CAF के CastButtonFactory का इस्तेमाल करें:

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

डिवाइस नियंत्रण

सीसीएल की तरह ही, सीएएफ़ में भी ज़्यादातर डिवाइस कंट्रोल, फ़्रेमवर्क के हिसाब से होता है. भेजने वाले ऐप्लिकेशन को डिवाइस से कनेक्ट करने और (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 में, भेजने वाले ऐप्लिकेशन को SessionManager के साथ SessionManagerListener को रजिस्टर करके, सेशन के लाइफ़साइकल इवेंट की सूचना दी जा सकती है. सेशन मैनेजर कॉलबैक, सभी सेशन के लाइफ़साइकल इवेंट के लिए, कॉलबैक तरीके तय करते हैं.

इन SessionManagerListener तरीकों को सीसीएल VideoCastConsumer इंटरफ़ेस से मैप किया गया है:

  • 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 कक्षा, कास्ट डिवाइस वाले सेशन के बारे में बताती है. इस क्लास में, डिवाइस की आवाज़ और म्यूट करने की स्थितियों को कंट्रोल करने के तरीके मौजूद होते हैं, जिन्हें सीसीएल BaseCastManager में करता है.

ग्राहक को जोड़ने के लिए, CCL का इस्तेमाल करने के बजाय: VideoCastManager.

VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);

अब अपना SessionManagerListener रजिस्टर करें:

mCastSessionManager = 
    CastContext.getSharedInstance(this).getSessionManager();
mCastSessionManagerListener = new CastSessionManagerListener();
mCastSessionManager.addSessionManagerListener(mCastSessionManagerListener,
                  CastSession.class);

सीसीएल में इवेंट सुनना बंद करने के लिए:

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

यह तय करने के लिए कि पैसे पाने वाला, पाने वाले से जुड़ा है या नहीं, एमसीएल VideoCastManager.getInstance().isConnected() की जानकारी देता है, लेकिन सीएएफ़ में SessionManager का इस्तेमाल करें:

public boolean isConnected() {
    CastSession castSession = CastContext.getSharedInstance(mAppContext)
                                  .getSessionManager()
                                  .getCurrentCastSession();
    return (castSession != null && castSession.isConnected());
}

सीएएफ़ में, आवाज़/म्यूट करने की स्थिति में बदलाव की सूचनाएं अब भी Cast.Listener में कॉलबैक मैथड के ज़रिए दी जाती हैं; ये लिसनर CastSession के साथ रजिस्टर होते हैं. डिवाइस की बाकी बची सभी स्थितियों के बारे में सूचनाएं CastStateListener कॉलबैक के ज़रिए दी जाती हैं. ये सुनने वाले, CastSession के साथ रजिस्टर होते हैं. पक्का करें कि आपके सुझाए गए फ़्रैगमेंट, गतिविधियों या ऐप्लिकेशन के बैकग्राउंड में जाने पर भी, आपको लिसनर का रजिस्ट्रेशन रद्द करना हो.

फिर से कनेक्शन करने का तर्क

CAF थोड़ी देर के लिए वाई-फ़ाई सिग्नल खो जाने या नेटवर्क की दूसरी गड़बड़ियों की वजह से खोए नेटवर्क कनेक्शन को फिर से जोड़ने की कोशिश करता है. यह अब एक सेशन में किया जाता है. जब कोई कनेक्शन टूट जाता है, तो एक सेशन "निलंबित" स्थिति में जा सकता है. इसके बाद, कनेक्टिविटी वापस आने पर वह वापस "कनेक्ट है" की स्थिति में आ जाएगी. फ़्रेमवर्क, रिसीवर ऐप्लिकेशन से दोबारा कनेक्ट करता है और प्रक्रिया के हिस्से के रूप में किसी भी कास्ट चैनल को फिर से कनेक्ट करता है.

CAF अपनी खुद की फिर से कनेक्ट करने की सेवा देता है, ताकि आप अपने मेनिफ़ेस्ट से ReconnectionServiceCCL हटा सकें:

<service android:name="com.google.android.libraries.cast.companionlibrary.cast.reconnection.ReconnectionService"/>

रीकनेक्शन तर्क के लिए आपको अपने मेनिफ़ेस्ट में, नीचे दी गई अनुमतियों की भी ज़रूरत नहीं है:

<uses‐permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses‐permission android:name="android.permission.ACCESS_WIFI_STATE"/>

CAF से फिर से कनेक्ट करने की सेवा डिफ़ॉल्ट रूप से चालू रहती है. हालांकि, CastOptions का इस्तेमाल करके इसे बंद किया जा सकता है.

इसके अलावा, CAF अपने-आप सेशन फिर से शुरू होने की सुविधा भी जोड़ता है, जो डिफ़ॉल्ट रूप से चालू होती है (और इसे CastOptions से बंद किया जा सकता है). अगर भेजने वाले ऐप्लिकेशन को बैकग्राउंड में हटाया जाता है या बंद करने पर या स्क्रीन की वजह से बंद हो जाता है, तो फ़्रेमवर्क उस सेशन को फिर से शुरू करने की कोशिश करेगा.

कस्टम चैनल रजिस्ट्रेशन

ग्राहक को कस्टम मैसेज चैनल बनाने के लिए, सीसीएल दो तरीके देता है:

  • CastConfiguration से आप एक से ज़्यादा नेमस्पेस तय कर सकते हैं. इसके बाद, CCL आपके लिए चैनल बनाएगा.
  • DataCastManager, VideoCastManager से मिलता-जुलता है, लेकिन गैर-मीडिया उपयोग के मामलों पर केंद्रित है.

इनमें से कोई भी तरीका CAF से काम नहीं करता -- आपको अपने भेजने वाले ऐप्लिकेशन के लिए, इसके बजाय कस्टम चैनल जोड़ने की प्रक्रिया अपनानी होगी.

मीडिया ऐप्लिकेशन के लिए सीसीएल की तरह, मीडिया कंट्रोल चैनल को साफ़ तौर पर रजिस्टर करना ज़रूरी नहीं है.

मीडिया नियंत्रण

CAF में RemoteMediaClient क्लास, VideoCastManager मीडिया तरीकों के बराबर होती है. RemoteMediaClient.Listener, VideoCastConsumer मैथड के बराबर है. खास तौर पर, VideoCastConsumer के onRemoteMediaPlayerMetadataUpdated और onRemoteMediaPlayerStatusUpdated के तरीके, RemoteMediaClient.Listener के onMetadataUpdated और onStatusUpdated के तरीकों को मैप करते हैं:

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 को CastSession ऑब्जेक्ट के getRemoteMediaClient तरीके के तौर पर ऐक्सेस किया जा सकता है.

CastSession castSession = CastContext.getSharedInstance(mAppContext)
                                     .getSessionManager()
                                     .getCurrentCastSession();
mRemoteMediaClient = castSession.getRemoteMediaClient();
mRemoteMediaClientListener = new CastMediaClientListener();

सीसीएल के बजाय

VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);

अब CAF का इस्तेमाल करें:

mRemoteMediaClient.addListener(mRemoteMediaClientListener);

RemoteMediaClient की मदद से, कितने भी लिसनर रजिस्टर किए जा सकते हैं. इससे, भेजने वाले के कई कॉम्पोनेंट, सेशन से जुड़े RemoteMediaClient के एक ही इंस्टेंस को शेयर कर पाएंगे.

सीसीएल की VideoCastManager में, मीडिया प्लेबैक को मैनेज करने के तरीके दिए गए हैं:

VideoCastManager manager = VideoCastManager.getInstance();
if (manager.isRemoteMediaLoaded()) {
    manager.pause();
    mCurrentPosition = (int) manager.getCurrentMediaPosition();
}

इन्हें अब CAF में RemoteMediaClient के ज़रिए लागू किया गया है:

if (mRemoteMediaClient.hasMediaSession()) {
    mRemoteMediaClient.pause();
    mCurrentPosition = 
        (int)mRemoteMediaClient.getApproximateStreamPosition();
}

CAF में, RemoteMediaClient पर जारी किए गए सभी मीडिया अनुरोधों के लिए, PendingResult कॉलबैक के ज़रिए RemoteMediaClient.MediaChannelResult दिया जाता है. इसका इस्तेमाल, अनुरोध की स्थिति और आखिरी नतीजे ट्रैक करने के लिए किया जा सकता है.

मीडिया आइटम को दिखाने और मीडिया को लोड करने के लिए 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 तरीके का इस्तेमाल करने के बजाय, 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();
            }
        });
    }
}

हमारा ओवरले दिखाने के लिए नमूना ऐप्लिकेशन पर एक नज़र डालें. इसकी मदद से शुरुआती ओवरले दिखाया जा सकता है.

शुरुआती ओवरले की स्टाइल को पसंद के मुताबिक बनाने के लिए, प्रोसेस को फ़ॉलो करें शुरुआती ओवरले पसंद के मुताबिक बनाएं.

मिनी कंट्रोलर

CCL की MiniController के बजाय, अपने ऐप्लिकेशन की लेआउट फ़ाइल में, उन गतिविधियों की CAF की MiniControllerFragment का इस्तेमाल करें जिनमें आपको मिनी कंट्रोलर को दिखाना है:

<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, Autoplay की सुविधा के साथ भी काम नहीं करता.

मिनी कंट्रोलर की स्टाइल और बटन को पसंद के मुताबिक बनाने के लिए, प्रक्रिया को फ़ॉलो करें मिनी कंट्रोलर को पसंद के मुताबिक बनाएं.

सूचना और लॉक स्क्रीन

CCL के VideoCastNotificationService की तरह, CAF भी कास्ट करने के लिए मीडिया सूचनाओं का डिसप्ले मैनेज करने के लिए MediaNotificationService देता है.

आपको अपने मेनिफ़ेस्ट से ये चीज़ें हटानी होंगी:

  • VideoIntentReceiver
  • VideoCastNotificationService

सीसीएल में, CastConfiguration.Builder को पसंद के मुताबिक सूचना देने की सेवा दी जाती है. यह सुविधा CAF के साथ काम नहीं करती.

सीसीएल का इस्तेमाल करके, CastManager शुरू करने के बारे में सोचें:

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 की सुविधा देता है. इससे, आपको भेजने वाले ऐप्लिकेशन में सूचना और लॉक स्क्रीन के लिए मीडिया कंट्रोल बनाने में मदद मिलती है. CastContext शुरू करते समय, CastOptions के साथ सूचना और लॉक स्क्रीन की सेटिंग चालू की जा सकती हैं.

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, अपने-आप यह तय करने के लिए, गतिविधियां देख सकता है कि मीडिया सूचना कब दिखानी है. हालांकि, Gingerbread में ऐसा नहीं होगा. (Gingerbread के लिए, registerLifecycleCallbacksBeforeIceCreamSandwich() का इस्तेमाल करने से जुड़ी पहले की जानकारी देखें; CCL कीVideoCastManager incrementUiCounter और decrementUiCounter कॉल हटा दी जाएंगी.)

सूचनाओं में दिखने वाले बटन को पसंद के मुताबिक बनाने के लिए, प्रोसेस का पालन करें सूचना और लॉक स्क्रीन पर मीडिया कंट्रोल जोड़ें.

विस्तृत नियंत्रक

मीडिया कास्ट करते समय, CCL, VideoCastControllerActivity और VideoCastControllerFragment को एक बड़ा कंट्रोलर दिखाने के लिए देता है.

आप मेनिफ़ेस्ट से VideoCastControllerActivity एलान हटा सकते हैं.

सीएएफ़ में, आपको expandedControllerActivity को बढ़ाना और 'कास्ट करें' बटन जोड़ना होगा.

बड़ा किए गए कंट्रोलर में स्टाइल और बटन को पसंद के मुताबिक बनाने के लिए, प्रोसेस का पालन करें एक्सटेंडेड कंट्रोलर को पसंद के मुताबिक बनाएं.

ऑडियो फ़ोकस

सीसीएल की तरह ही, ऑडियो फ़ोकस भी अपने-आप मैनेज होता है.

वॉल्यूम कंट्रोल

जिंजरब्रेड के लिए dispatchKeyEvent की ज़रूरत, सीसीएल के साथ होती है. ICL और इससे ऊपर के वर्शन में, CCL और CAF वॉल्यूम कंट्रोल, दोनों ही अपने-आप हैंडल हो जाते हैं.

CAF आपके ऐप्लिकेशन की गतिविधियों में फ़ोन पर हार्ड वॉल्यूम बटन के द्वारा कास्ट वॉल्यूम को नियंत्रित करता है और समर्थित वर्शन पर कास्ट करते समय एक विज़ुअल वॉल्यूम बार भी दिखाता है. चाहे आपका ऐप्लिकेशन सामने न हो, लॉक हो या स्क्रीन बंद हो, तब भी CAF हार्ड वॉल्यूम के ज़रिए आवाज़ में बदलाव को संभालता है.

उपशीर्षक

Android KitKat और उसके बाद के वर्शन में, कैप्शन को सेटिंग > सुलभता में जाकर, कैप्शन की सेटिंग के ज़रिए पसंद के मुताबिक बनाया जा सकता है. Android के पुराने वर्शन में, हालांकि, इसमें यह सुविधा नहीं मिलती. इसके लिए, CCL का इस्तेमाल, पुराने वर्शन के लिए कस्टम सेटिंग की मदद से किया जाता है. साथ ही, KitKat और उसके बाद के वर्शन वाले सिस्टम की सेटिंग के हिसाब से, इस सेटिंग को मैनेज किया जाता है.

CAF, कैप्शन की सेटिंग में बदलाव करने के लिए कस्टम सेटिंग नहीं देता है. आपको अपने मेनिफ़ेस्ट से CaptionsPreferenceActivity रेफ़रंस और प्राथमिकताओं को एक्सएमएल से हटाना होगा.

सीसीएल के लिए TracksChooserDialog की ज़रूरत नहीं है, क्योंकि सबटाइटल ट्रैक को बदलने के लिए, नियंत्रक के यूज़र इंटरफ़ेस (यूआई) का इस्तेमाल किया जाता है.

सीएएफ़ में बंद कैप्शन एपीआई वर्शन 2 के जैसा ही है.

डीबग लॉगिंग

सीएएफ़ डीबग करने की सेटिंग नहीं देता है.

अन्य सुविधाएं

CAF में ये सीसीएल सुविधाएं काम नहीं करती हैं:

  • वीडियो उपलब्ध कराने से पहले, MediaAuthService इस्तेमाल करने की अनुमति लेना
  • कॉन्फ़िगर करने लायक यूज़र इंटरफ़ेस (यूआई) मैसेज

ऐप्लिकेशन के नमूने

Android Music Player for Android (uamp) के सैंपल ऐप्लिकेशन को CCL से CAF पर माइग्रेट करने के लिए, अंतर पर एक नज़र डालें.

हमारे पास कोडलैब ट्यूटोरियल और CAF का इस्तेमाल करने वाले सैंपल ऐप्लिकेशन भी हैं.