Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Implementing cast in android

1,016 views

Published on

My slides for my Presentation about how to Implement Google Cast into Android and a Texted Version of the Live Coding Demo with some Explanations

Published in: Engineering
  • DOWNLOAD THIS BOOKS INTO AVAILABLE FORMAT (2019 Update) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { https://soo.gd/irt2 } ......................................................................................................................... Download Full EPUB Ebook here { https://soo.gd/irt2 } ......................................................................................................................... Download Full doc Ebook here { https://soo.gd/irt2 } ......................................................................................................................... Download PDF EBOOK here { https://soo.gd/irt2 } ......................................................................................................................... Download EPUB Ebook here { https://soo.gd/irt2 } ......................................................................................................................... Download doc Ebook here { https://soo.gd/irt2 } ......................................................................................................................... ......................................................................................................................... ................................................................................................................................... eBook is an electronic version of a traditional print book THIS can be read by using a personal computer or by using an eBook reader. (An eBook reader can be a software application for use on a computer such as Microsoft's free Reader application, or a book-sized computer THIS is used solely as a reading device such as Nuvomedia's Rocket eBook.) Users can purchase an eBook on diskette or CD, but the most popular method of getting an eBook is to purchase a downloadable file of the eBook (or other reading material) from a Web site (such as Barnes and Noble) to be read from the user's computer or reading device. Generally, an eBook can be downloaded in five minutes or less ......................................................................................................................... .............. Browse by Genre Available eBooks .............................................................................................................................. Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, ......................................................................................................................... ......................................................................................................................... .....BEST SELLER FOR EBOOK RECOMMEND............................................................. ......................................................................................................................... Blowout: Corrupted Democracy, Rogue State Russia, and the Richest, Most Destructive Industry on Earth,-- The Ride of a Lifetime: Lessons Learned from 15 Years as CEO of the Walt Disney Company,-- Call Sign Chaos: Learning to Lead,-- StrengthsFinder 2.0,-- Stillness Is the Key,-- She Said: Breaking the Sexual Harassment Story THIS Helped Ignite a Movement,-- Atomic Habits: An Easy & Proven Way to Build Good Habits & Break Bad Ones,-- Everything Is Figureoutable,-- What It Takes: Lessons in the Pursuit of Excellence,-- Rich Dad Poor Dad: What the Rich Teach Their Kids About Money THIS the Poor and Middle Class Do Not!,-- The Total Money Makeover: Classic Edition: A Proven Plan for Financial Fitness,-- Shut Up and Listen!: Hard Business Truths THIS Will Help You Succeed, ......................................................................................................................... .........................................................................................................................
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Be the first to like this

Implementing cast in android

  1. 1. Google Cast with Android How to Implement Google Cast into Android Apps +Angelo Rüggeberg @s3xy4ngyc
  2. 2. agenda -  Introduction to Google Cast -  Connecting an Android App to an Cast App -  Launching the Cast App -  Interacting with the Cast App -  using the CastCompanionLibrary for Media
  3. 3. Introduction to Google Cast
  4. 4. Biggest, most beautiful screen in the house...
  5. 5. Your app on the TV!
  6. 6. Simple to get started with the SDK
  7. 7. Connecting technology
  8. 8. Start with your existing app
  9. 9. e.g. Phone app
  10. 10. e.g. Phone app
  11. 11. e.g. Phone app
  12. 12. Tablets
  13. 13. Web Apps
  14. 14. Your app is ‘The Sender’
  15. 15. Receiving device
  16. 16. Receiver app runs on Cast receiving device
  17. 17. Cast SDK app looks for Cast devices
  18. 18. Cast icon shown on discovery of Cast devices
  19. 19. Selection activates connected icon look
  20. 20. developers.google.com/cast/docs/ux_guidelines Consistent UX fully documented
  21. 21. developers.google.com/cast/ docs/ux_guidelines ●  Selecting Cast Device ●  Pausing & Scrubbing ●  Visual Consistency
  22. 22. Sender triggers Receiver loading
  23. 23. https://… Content loads direct from the cloud
  24. 24. https://… Sender manages playback control
  25. 25. developers.google.com/cast/docs/receiver_apps
  26. 26. Images
  27. 27. Leader Board 1st Scotty 145 2nd Andrea 109 3rd Ralph 94
  28. 28. developers.google.com/cast/docs/downloads
  29. 29. Connecting an Android App to an Cast App
  30. 30. Environment: ●  Real Device ○  with Google Play Services Installed ●  Cast Device ○  e.g. Chromecast Prequesites Dependencies: play-services-cast Handles Connection to Cast 'com.google.android.gms:play-services-cast:8.3.0' support-media-router Button to Connect to Cast 'com.android.support:mediarouter-v7:23.1.0'
  31. 31. Dependencies - build.gradle dependencies { compile 'com.android.support:mediarouter-v7:23.1.0' compile 'com.google.android.gms:play-services-cast:8.3.0' }
  32. 32. Permissions - Manifest.xml <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
  33. 33. Adding Media Route Button via Menu <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <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"/> </menu>
  34. 34. Adding Media Route Button via Menu <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <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"/> </menu>
  35. 35. Adding Media Route Button to an Layout <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" /> <android.support.v7.app.MediaRouteButton android:id="@+id/media_route_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:mediaRouteTypes="user" /> … </RelativeLayout>
  36. 36. Adding Media Route Button to an Layout <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" /> <android.support.v7.app.MediaRouteButton android:id="@+id/media_route_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:mediaRouteTypes="user" /> … </RelativeLayout>
  37. 37. Adding Media Route Button to an Layout <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" /> <android.support.v7.app.MediaRouteButton android:id="@+id/media_route_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:mediaRouteTypes="user" /> … </RelativeLayout>
  38. 38. Fields - MainActivity.java private MediaRouteButton mMediaRouteButton; private MediaRouter mMediaRouter; private MediaRouteSelector mMediaRouteSelector; private MediaRouter.Callback mMediaRouterCallback; private CastDevice mSelectedDevice;
  39. 39. Fields - MainActivity.java private MediaRouteButton mMediaRouteButton; private MediaRouter mMediaRouter; private MediaRouteSelector mMediaRouteSelector; private MediaRouter.Callback mMediaRouterCallback; private CastDevice mSelectedDevice; The Button added To the Layout
  40. 40. Fields - MainActivity.java private MediaRouteButton mMediaRouteButton; private MediaRouter mMediaRouter; private MediaRouteSelector mMediaRouteSelector; private MediaRouter.Callback mMediaRouterCallback; private CastDevice mSelectedDevice; The Media Router. This handles the Connection to our Cast Device
  41. 41. Fields - MainActivity.java private MediaRouteButton mMediaRouteButton; private MediaRouter mMediaRouter; private MediaRouteSelector mMediaRouteSelector; private MediaRouter.Callback mMediaRouterCallback; private CastDevice mSelectedDevice; The Route Selector. This is the Configuration for our Connection e.g the Device to Interact with
  42. 42. Fields - MainActivity.java private MediaRouteButton mMediaRouteButton; private MediaRouter mMediaRouter; private MediaRouteSelector mMediaRouteSelector; private MediaRouter.Callback mMediaRouterCallback; private CastDevice mSelectedDevice; The Router Callbacks. These Callbacks are used to Notify the Application on Select and Deselction of an Device Route and enables us to react to these events e.g by printing the Connected Device to the User.
  43. 43. Fields - MainActivity.java private MediaRouteButton mMediaRouteButton; private MediaRouter mMediaRouter; private MediaRouteSelector mMediaRouteSelector; private MediaRouter.Callback mMediaRouterCallback; private CastDevice mSelectedDevice; The Cast Device we are Connected to. It contains Informations like Device Name, Model, Capabilities, etc.
  44. 44. Initializing - MainActivity.java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); mConnectionStatus = (TextView) findViewById(R.id.text_connection); mMediaRouteButton = (MediaRouteButton) findViewById(R.id.media_route_button); initCast(); }
  45. 45. Initializing - MainActivity.java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); mConnectionStatus = (TextView) findViewById(R.id.text_connection); mMediaRouteButton = (MediaRouteButton) findViewById(R.id.media_route_button); initCast(); }
  46. 46. Initializing - MainActivity.java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); mConnectionStatus = (TextView) findViewById(R.id.text_connection); mMediaRouteButton = (MediaRouteButton) findViewById(R.id.media_route_button); initCast(); }
  47. 47. Initializing - MainActivity.java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); mConnectionStatus = (TextView) findViewById(R.id.text_connection); mMediaRouteButton = (MediaRouteButton) findViewById(R.id.media_route_button); initCast(); }
  48. 48. Initializing - MainActivity.java private void initCast() { // Configure Cast device discovery mMediaRouter = MediaRouter.getInstance(getApplicationContext()); }
  49. 49. Initializing - MainActivity.java private void initCast() { // Configure Cast device discovery mMediaRouter = MediaRouter.getInstance(getApplicationContext()); mMediaRouteSelector = new MediaRouteSelector.Builder() .addControlCategory( CastMediaControlIntent.categoryForCast(getResources().getString(R.string.app_id))) .build(); }
  50. 50. Initializing - MainActivity.java private void initCast() { // Configure Cast device discovery mMediaRouter = MediaRouter.getInstance(getApplicationContext()); mMediaRouteSelector = new MediaRouteSelector.Builder() .addControlCategory( CastMediaControlIntent.categoryForCast(getResources().getString(R.string.app_id))) .build(); } The Cast Application ID. E.g “794B7BBF” (Cast Sample Helloworld)
  51. 51. Initializing - MainActivity.java private void initCast() { // Configure Cast device discovery mMediaRouter = MediaRouter.getInstance(getApplicationContext()); mMediaRouteSelector = new MediaRouteSelector.Builder() .addControlCategory(CastMediaControlIntent.categoryForCast(getResources() .getString(R.string.app_id))) .build(); // Set the MediaRouteButton selector for device discovery. mMediaRouteButton.setRouteSelector(mMediaRouteSelector); }
  52. 52. Initializing - MainActivity.java @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item); MediaRouteActionProvider mediaRouteActionProvider = (MediaRouteActionProvider) MenuItemCompat .getActionProvider(mediaRouteMenuItem); // Set the MediaRouteActionProvider selector for device discovery. mediaRouteActionProvider.setRouteSelector(mMediaRouteSelector); return true; }
  53. 53. Initializing - MainActivity.java @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item); MediaRouteActionProvider mediaRouteActionProvider = (MediaRouteActionProvider) MenuItemCompat .getActionProvider(mediaRouteMenuItem); // Set the MediaRouteActionProvider selector for device discovery. mediaRouteActionProvider.setRouteSelector(mMediaRouteSelector); return true; }
  54. 54. Initializing - MainActivity.java @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item); MediaRouteActionProvider mediaRouteActionProvider = (MediaRouteActionProvider) MenuItemCompat .getActionProvider(mediaRouteMenuItem); // Set the MediaRouteActionProvider selector for device discovery. mediaRouteActionProvider.setRouteSelector(mMediaRouteSelector); return true; }
  55. 55. Initializing - MainActivity.java @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item); MediaRouteActionProvider mediaRouteActionProvider = (MediaRouteActionProvider) MenuItemCompat .getActionProvider(mediaRouteMenuItem); // Set the MediaRouteActionProvider selector for device discovery. mediaRouteActionProvider.setRouteSelector(mMediaRouteSelector); return true; }
  56. 56. Adding Callbacks - MainActivity.java private void initCast() { // Configure Cast device discovery mMediaRouter = MediaRouter.getInstance(getApplicationContext()); mMediaRouteSelector = new MediaRouteSelector.Builder() .addControlCategory(CastMediaControlIntent.categoryForCast(getResources() .getString(R.string.app_id))) .build(); // Set the MediaRouteButton selector for device discovery. mMediaRouteButton.setRouteSelector(mMediaRouteSelector); mMediaRouterCallback = new MyMediaRouterCallback(); }
  57. 57. Adding Callbacks - MainActivity.java private class MyMediaRouterCallback extends MediaRouter.Callback { @Override public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo info) { // Handle the user route selection. mSelectedDevice = CastDevice.getFromBundle(info.getExtras()); mConnectionStatus.setText("Connected to: " + mSelectedDevice.getFriendlyName()); } @Override public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo info) { mSelectedDevice = null; mConnectionStatus.setText("Not Connected"); } }
  58. 58. Adding Callbacks - MainActivity.java private class MyMediaRouterCallback extends MediaRouter.Callback { @Override public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo info) { // Handle the user route selection. mSelectedDevice = CastDevice.getFromBundle(info.getExtras()); mConnectionStatus.setText("Connected to: " + mSelectedDevice.getFriendlyName()); } @Override public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo info) { mSelectedDevice = null; mConnectionStatus.setText("Not Connected"); } }
  59. 59. Adding Callbacks - MainActivity.java private class MyMediaRouterCallback extends MediaRouter.Callback { @Override public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo info) { // Handle the user route selection. mSelectedDevice = CastDevice.getFromBundle(info.getExtras()); mConnectionStatus.setText("Connected to: " + mSelectedDevice.getFriendlyName()); } @Override public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo info) { mSelectedDevice = null; mConnectionStatus.setText("Not Connected"); } } Called after we Selected an Cast Device we want to Connect with. This does not mean we are Connected to the Cast Application yet!
  60. 60. Adding Callbacks - MainActivity.java private class MyMediaRouterCallback extends MediaRouter.Callback { @Override public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo info) { // Handle the user route selection. mSelectedDevice = CastDevice.getFromBundle(info.getExtras()); mConnectionStatus.setText("Connected to: " + mSelectedDevice.getFriendlyName()); } @Override public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo info) { mSelectedDevice = null; mConnectionStatus.setText("Not Connected"); } } Called after we Decided to Disconnect from an Cast Device. This does not mean we are Disconnected from the Application yet!
  61. 61. Adding Callbacks - MainActivity.java private class MyMediaRouterCallback extends MediaRouter.Callback { @Override public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo info) { // Handle the user route selection. mSelectedDevice = CastDevice.getFromBundle(info.getExtras()); mConnectionStatus.setText("Connected to: " + mSelectedDevice.getFriendlyName()); } @Override public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo info) { mSelectedDevice = null; mConnectionStatus.setText("Not Connected"); } }
  62. 62. Adding Callbacks - MainActivity.java private class MyMediaRouterCallback extends MediaRouter.Callback { @Override public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo info) { // Handle the user route selection. mSelectedDevice = CastDevice.getFromBundle(info.getExtras()); mConnectionStatus.setText("Connected to: " + mSelectedDevice.getFriendlyName()); } @Override public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo info) { mSelectedDevice = null; mConnectionStatus.setText("Not Connected"); } }
  63. 63. Adding Callbacks - MainActivity.java private class MyMediaRouterCallback extends MediaRouter.Callback { @Override public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo info) { // Handle the user route selection. mSelectedDevice = CastDevice.getFromBundle(info.getExtras()); mConnectionStatus.setText("Connected to: " + mSelectedDevice.getFriendlyName()); } @Override public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo info) { mSelectedDevice = null; mConnectionStatus.setText("Not Connected"); } }
  64. 64. Starting Discovery - MainActivity.java @Override protected void onStart() { super.onStart(); // Start media router discovery mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback, MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY); } @Override protected void onStop() { // End media router discovery mMediaRouter.removeCallback(mMediaRouterCallback); super.onStop(); }
  65. 65. Starting Discovery - MainActivity.java @Override protected void onStart() { super.onStart(); // Start media router discovery mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback, MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY); } @Override protected void onStop() { // End media router discovery mMediaRouter.removeCallback(mMediaRouterCallback); super.onStop(); }
  66. 66. Starting Discovery - MainActivity.java @Override protected void onStart() { super.onStart(); // Start media router discovery mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback, MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY); } @Override protected void onStop() { // End media router discovery mMediaRouter.removeCallback(mMediaRouterCallback); super.onStop(); }
  67. 67. Demo
  68. 68. Launching the Cast Application
  69. 69. New Fields - MainActivity.java private GoogleApiClient mApiClient; private Cast.Listener mCastListener; private ConnectionCallbacks mConnectionCallbacks; private ConnectionFailedListener mConnectionFailedListener; private boolean mApplicationStarted; private boolean mWaitingForReconnect; private String mSessionId;
  70. 70. New Fields - MainActivity.java private GoogleApiClient mApiClient; private Cast.Listener mCastListener; private ConnectionCallbacks mConnectionCallbacks; private ConnectionFailedListener mConnectionFailedListener; private boolean mApplicationStarted; private boolean mWaitingForReconnect; private String mSessionId; The Api Client is used to Interact with The Chromecast e.g. Sending Messages
  71. 71. New Fields - MainActivity.java private GoogleApiClient mApiClient; private Cast.Listener mCastListener; private ConnectionCallbacks mConnectionCallbacks; private ConnectionFailedListener mConnectionFailedListener; private boolean mApplicationStarted; private boolean mWaitingForReconnect; private String mSessionId; Our Callbacks to Notify us about Connection Events e.g. disconnection
  72. 72. New Fields - MainActivity.java private GoogleApiClient mApiClient; private Cast.Listener mCastListener; private ConnectionCallbacks mConnectionCallbacks; private ConnectionFailedListener mConnectionFailedListener; private boolean mApplicationStarted; private boolean mWaitingForReconnect; private String mSessionId; The Connection Callbacks. e.G. we get disconnected due to application errors
  73. 73. New Fields - MainActivity.java private GoogleApiClient mApiClient; private Cast.Listener mCastListener; private ConnectionCallbacks mConnectionCallbacks; private ConnectionFailedListener mConnectionFailedListener; private boolean mApplicationStarted; private boolean mWaitingForReconnect; private String mSessionId; Our Callback if the connection Fails
  74. 74. New Fields - MainActivity.java private GoogleApiClient mApiClient; private Cast.Listener mCastListener; private ConnectionCallbacks mConnectionCallbacks; private ConnectionFailedListener mConnectionFailedListener; private boolean mApplicationStarted; private boolean mWaitingForReconnect; private String mSessionId; We keep Some Information for our Application stored in these Fields
  75. 75. Launching the Cast Application - MainActivity.java private void launchReceiver() { mCastListener = new Cast.Listener() { @Override public void onApplicationDisconnected(int errorCode) { Log.d(TAG, "application has stopped"); teardown(true); } }; }
  76. 76. Launching the Cast Application - MainActivity.java private void launchReceiver() { mCastListener = new Cast.Listener() { … }; mConnectionCallbacks = new ConnectionCallbacks(); mConnectionFailedListener = new ConnectionFailedListener(); }
  77. 77. Launching the Cast Application - MainActivity.java private void launchReceiver() { mCastListener = new Cast.Listener() { … }; mConnectionCallbacks = new ConnectionCallbacks(); mConnectionFailedListener = new ConnectionFailedListener(); Cast.CastOptions.Builder apiOptionsBuilder = Cast.CastOptions .builder(mSelectedDevice, mCastListener); }
  78. 78. Launching the Cast Application - MainActivity.java private void launchReceiver() { mCastListener = new Cast.Listener() { … }; mConnectionCallbacks = new ConnectionCallbacks(); mConnectionFailedListener = new ConnectionFailedListener(); Cast.CastOptions.Builder apiOptionsBuilder = Cast.CastOptions .builder(mSelectedDevice, mCastListener); }
  79. 79. Launching the Cast Application - MainActivity.java private void launchReceiver() { mCastListener = new Cast.Listener() { … }; mConnectionCallbacks = new ConnectionCallbacks(); mConnectionFailedListener = new ConnectionFailedListener(); Cast.CastOptions.Builder apiOptionsBuilder = Cast.CastOptions .builder(mSelectedDevice, mCastListener); mApiClient = new GoogleApiClient.Builder(this) .addApi(Cast.API, apiOptionsBuilder.build()) .addConnectionCallbacks(mConnectionCallbacks) .addOnConnectionFailedListener(mConnectionFailedListener) .build(); }
  80. 80. Launching the Cast Application - MainActivity.java private void launchReceiver() { mCastListener = new Cast.Listener() { … }; mConnectionCallbacks = new ConnectionCallbacks(); mConnectionFailedListener = new ConnectionFailedListener(); Cast.CastOptions.Builder apiOptionsBuilder = Cast.CastOptions .builder(mSelectedDevice, mCastListener); mApiClient = new GoogleApiClient.Builder(this) .addApi(Cast.API, apiOptionsBuilder.build()) .addConnectionCallbacks(mConnectionCallbacks) .addOnConnectionFailedListener(mConnectionFailedListener) .build(); }
  81. 81. Launching the Cast Application - MainActivity.java private void launchReceiver() { mCastListener = new Cast.Listener() { … }; mConnectionCallbacks = new ConnectionCallbacks(); mConnectionFailedListener = new ConnectionFailedListener(); Cast.CastOptions.Builder apiOptionsBuilder = Cast.CastOptions .builder(mSelectedDevice, mCastListener); mApiClient = new GoogleApiClient.Builder(this) .addApi(Cast.API, apiOptionsBuilder.build()) .addConnectionCallbacks(mConnectionCallbacks) .addOnConnectionFailedListener(mConnectionFailedListener) .build(); }
  82. 82. Launching the Cast Application - MainActivity.java private void launchReceiver() { mCastListener = new Cast.Listener() { … }; mConnectionCallbacks = new ConnectionCallbacks(); mConnectionFailedListener = new ConnectionFailedListener(); Cast.CastOptions.Builder apiOptionsBuilder = Cast.CastOptions .builder(mSelectedDevice, mCastListener); mApiClient = new GoogleApiClient.Builder(this) .addApi(Cast.API, apiOptionsBuilder.build()) .addConnectionCallbacks(mConnectionCallbacks) .addOnConnectionFailedListener(mConnectionFailedListener) .build(); mApiClient.connect(); }
  83. 83. Launching the Cast Application - MainActivity.java private class ConnectionCallbacks implements GoogleApiClient.ConnectionCallbacks { @Override public void onConnected(Bundle connectionHint) { ... // Launch the receiver app Cast.CastApi.launchApplication(mApiClient, getString(R.string.app_id), false) .setResultCallback( new ResultCallback<Cast.ApplicationConnectionResult>() { @Override public void onResult(Cast.ApplicationConnectionResult result) { … } }
  84. 84. Launching the Cast Application - MainActivity.java private class ConnectionCallbacks implements GoogleApiClient.ConnectionCallbacks { @Override public void onConnected(Bundle connectionHint) { ... // Launch the receiver app Cast.CastApi.launchApplication(mApiClient, getString(R.string.app_id), false) .setResultCallback( new ResultCallback<Cast.ApplicationConnectionResult>() { @Override public void onResult(Cast.ApplicationConnectionResult result) { … } }
  85. 85. Launching the Cast Application - MainActivity.java Status status = result.getStatus(); if (status.isSuccess()) { ApplicationMetadata applicationMetadata = result .getApplicationMetadata(); mSessionId = result.getSessionId(); mApplicationStarted = true; } else { Log.e(TAG, "application could not launch"); teardown(true); }
  86. 86. Launching the Cast Application - MainActivity.java Status status = result.getStatus(); if (status.isSuccess()) { ApplicationMetadata applicationMetadata = result .getApplicationMetadata(); mSessionId = result.getSessionId(); mApplicationStarted = true; } else { Log.e(TAG, "application could not launch"); teardown(true); }
  87. 87. Launching the Cast Application - MainActivity.java Status status = result.getStatus(); if (status.isSuccess()) { ApplicationMetadata applicationMetadata = result .getApplicationMetadata(); mSessionId = result.getSessionId(); mApplicationStarted = true; } else { Log.e(TAG, "application could not launch"); teardown(true); }
  88. 88. Launching the Cast Application - MainActivity.java Status status = result.getStatus(); if (status.isSuccess()) { ApplicationMetadata applicationMetadata = result .getApplicationMetadata(); mSessionId = result.getSessionId(); mApplicationStarted = true; } else { Log.e(TAG, "application could not launch"); teardown(true); }
  89. 89. Launching the Cast Application - MainActivity.java private void teardown(boolean selectDefaultRoute) { if (mApiClient != null) { if (mApplicationStarted) { if (mApiClient.isConnected() || mApiClient.isConnecting()) { Cast.CastApi.stopApplication(mApiClient, mSessionId); mApiClient.disconnect(); } mApplicationStarted = false; } mApiClient = null; } mSelectedDevice = null; mWaitingForReconnect = false; mSessionId = null; }
  90. 90. Launching the Cast Application - MainActivity.java private void teardown(boolean selectDefaultRoute) { if (mApiClient != null) { if (mApplicationStarted) { if (mApiClient.isConnected() || mApiClient.isConnecting()) { Cast.CastApi.stopApplication(mApiClient, mSessionId); mApiClient.disconnect(); } mApplicationStarted = false; } mApiClient = null; } mSelectedDevice = null; mWaitingForReconnect = false; mSessionId = null; }
  91. 91. Launching the Cast Application - MainActivity.java private void teardown(boolean selectDefaultRoute) { if (mApiClient != null) { if (mApplicationStarted) { if (mApiClient.isConnected() || mApiClient.isConnecting()) { Cast.CastApi.stopApplication(mApiClient, mSessionId); mApiClient.disconnect(); } mApplicationStarted = false; } mApiClient = null; } mSelectedDevice = null; mWaitingForReconnect = false; mSessionId = null; }
  92. 92. Launching the Cast Application - MainActivity.java private void teardown(boolean selectDefaultRoute) { if (mApiClient != null) { if (mApplicationStarted) { if (mApiClient.isConnected() || mApiClient.isConnecting()) { Cast.CastApi.stopApplication(mApiClient, mSessionId); mApiClient.disconnect(); } mApplicationStarted = false; } mApiClient = null; } mSelectedDevice = null; mWaitingForReconnect = false; mSessionId = null; }
  93. 93. Demo
  94. 94. Interacting with the Cast Application
  95. 95. Sending Messages - MainActivity.java class HelloWorldChannel implements Cast.MessageReceivedCallback { public String getNamespace() { return getString(R.string.namespace); } @Override public void onMessageReceived(CastDevice castDevice, String namespace, String message) { } }
  96. 96. Sending Messages - MainActivity.java class HelloWorldChannel implements Cast.MessageReceivedCallback { public String getNamespace() { return getString(R.string.namespace); } @Override public void onMessageReceived(CastDevice castDevice, String namespace, String message) { } }
  97. 97. Sending Messages - MainActivity.java class HelloWorldChannel implements Cast.MessageReceivedCallback { public String getNamespace() { return getString(R.string.namespace); } @Override public void onMessageReceived(CastDevice castDevice, String namespace, String message) { } } Our Custom Namespace. This is defined in our reciever app. e.g. urn:x-cast:com.google.cast.sample.helloworld
  98. 98. Sending Messages - MainActivity.java class HelloWorldChannel implements Cast.MessageReceivedCallback { public String getNamespace() { return getString(R.string.namespace); } @Override public void onMessageReceived(CastDevice castDevice, String namespace, String message) { } } This gets Triggered when the Reciever Sends Data To our Client. e.g. Updated Scores on Games
  99. 99. Sending Messages - MainActivity.java // Launch the receiver app Cast.CastApi.launchApplication(mApiClient, getString(R.string.app_id), false) …. // Create the custom message // channel mHelloWorldChannel = new HelloWorldChannel(); try { Cast.CastApi.setMessageReceivedCallbacks( mApiClient, mHelloWorldChannel.getNamespace(), mHelloWorldChannel); } catch (IOException e) { Log.e(TAG, "Exception while creating channel", e); }
  100. 100. Sending Messages - MainActivity.java // Launch the receiver app Cast.CastApi.launchApplication(mApiClient, getString(R.string.app_id), false) …. // Create the custom message // channel mHelloWorldChannel = new HelloWorldChannel(); try { Cast.CastApi.setMessageReceivedCallbacks( mApiClient, mHelloWorldChannel.getNamespace(), mHelloWorldChannel); } catch (IOException e) { Log.e(TAG, "Exception while creating channel", e); }
  101. 101. Sending Messages - MainActivity.java // Launch the receiver app Cast.CastApi.launchApplication(mApiClient, getString(R.string.app_id), false) …. // Create the custom message // channel mHelloWorldChannel = new HelloWorldChannel(); try { Cast.CastApi.setMessageReceivedCallbacks( mApiClient, mHelloWorldChannel.getNamespace(), mHelloWorldChannel); } catch (IOException e) { Log.e(TAG, "Exception while creating channel", e); }
  102. 102. Sending Messages - MainActivity.java // Launch the receiver app Cast.CastApi.launchApplication(mApiClient, getString(R.string.app_id), false) …. // Create the custom message // channel mHelloWorldChannel = new HelloWorldChannel(); try { Cast.CastApi.setMessageReceivedCallbacks( mApiClient, mHelloWorldChannel.getNamespace(), mHelloWorldChannel); } catch (IOException e) { Log.e(TAG, "Exception while creating channel", e); }
  103. 103. Sending Messages - MainActivity.java private void sendMessage(String message) { if (mApiClient != null && mHelloWorldChannel != null) { try { Cast.CastApi.sendMessage(mApiClient, mHelloWorldChannel.getNamespace(), message).setResultCallback( new ResultCallback<Status>() { @Override public void onResult(Status result) { if (!result.isSuccess()) { Log.e(TAG, "Sending message failed"); } } }); } catch (Exception e) { Log.e(TAG, "Exception while sending message", e); } }
  104. 104. Sending Messages - MainActivity.java private void sendMessage(String message) { if (mApiClient != null && mHelloWorldChannel != null) { try { Cast.CastApi.sendMessage(mApiClient, mHelloWorldChannel.getNamespace(), message).setResultCallback( new ResultCallback<Status>() { @Override public void onResult(Status result) { if (!result.isSuccess()) { Log.e(TAG, "Sending message failed"); } } }); } catch (Exception e) { Log.e(TAG, "Exception while sending message", e); } }
  105. 105. Sending Messages - MainActivity.java private void sendMessage(String message) { if (mApiClient != null && mHelloWorldChannel != null) { try { Cast.CastApi.sendMessage(mApiClient, mHelloWorldChannel.getNamespace(), message).setResultCallback( new ResultCallback<Status>() { @Override public void onResult(Status result) { if (!result.isSuccess()) { Log.e(TAG, "Sending message failed"); } } }); } catch (Exception e) { Log.e(TAG, "Exception while sending message", e); } }
  106. 106. Sending Messages - MainActivity.java private void sendMessage(String message) { if (mApiClient != null && mHelloWorldChannel != null) { try { Cast.CastApi.sendMessage(mApiClient, mHelloWorldChannel.getNamespace(), message).setResultCallback( new ResultCallback<Status>() { @Override public void onResult(Status result) { if (!result.isSuccess()) { Log.e(TAG, "Sending message failed"); } } }); } catch (Exception e) { Log.e(TAG, "Exception while sending message", e); } }
  107. 107. Sending Messages - MainActivity.java mSendButton = (Button) findViewById(R.id.button_send); mSendButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { sendMessage(mTextInput.getText().toString()); } });
  108. 108. Sending Messages - MainActivity.java mSendButton = (Button) findViewById(R.id.button_send); mSendButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { sendMessage(mTextInput.getText().toString()); } });
  109. 109. Demo
  110. 110. Wrap up
  111. 111. Wrap up ●  Initialize via MediaRouter ●  Select Device via MediaRouteSelector ●  Connect via GoogleApiClient ●  Setup Message Bus ●  Send Messages via CastApi through ApiClient
  112. 112. Using the CastCompanionLibrary for Media Streaming
  113. 113. Getting Started ●  Checkout CastCompanionLibrary from Github ○  https://github.com/googlecast/CastCompanionLibrary-android ●  Compile AAR file ○  ./gradlew build ●  copy compiled AAR to Project ○  rename to CastCompanionLibrary-2.6.aar ○  add repository flat dir to build.gradle ○  compile 'com.google.sample.castcompanionlibrary:CastCompanionLibrary:2.6@aar'
  114. 114. Cast Companion - build.gradle repositories { flatDir { dirs 'libs' } } dependencies { ... compile 'com.android.support:mediarouter-v7:23.1.0' compile 'com.google.android.gms:play-services-cast:8.3.0' companionCompile 'com.google.sample.castcompanionlibrary:CastCompanionLibrary:2.6@aar' }
  115. 115. Cast Companion - AndroidManifest.xml <activity android:name="com.google.android.libraries.cast.companionlibrary.cast.player.VideoCastControllerActivity" android:theme="@style/AppTheme.NoActionBar" />
  116. 116. Cast Companion - MainActivity.java private VideoCastManager mCastManager; private VideoCastConsumer mCastConsumer = new VideoCastConsumerImpl() {};
  117. 117. Cast Companion - MainActivity.java @Override protected void onResume() { Log.d(TAG, "onResume() was called"); mCastManager = VideoCastManager.getInstance(); mCastManager.addVideoCastConsumer(mCastConsumer); mCastManager.incrementUiCounter(); super.onResume(); }
  118. 118. Cast Companion - MainActivity.java private void initCast() { // initialize VideoCastManager VideoCastManager. initialize(this, getString(R.string.app_id), VideoCastControllerActivity.class, null). setVolumeStep(VOLUME_INCREMENT). enableFeatures(VideoCastManager.FEATURE_NOTIFICATION | VideoCastManager.FEATURE_LOCKSCREEN | VideoCastManager.FEATURE_WIFI_RECONNECT | VideoCastManager.FEATURE_AUTO_RECONNECT | VideoCastManager.FEATURE_CAPTIONS_PREFERENCE | VideoCastManager.FEATURE_DEBUGGING); }
  119. 119. Cast Companion - MainActivity.java private void initCast() { // initialize VideoCastManager VideoCastManager. initialize(this, getString(R.string.app_id), VideoCastControllerActivity.class, null). setVolumeStep(VOLUME_INCREMENT). enableFeatures(VideoCastManager.FEATURE_NOTIFICATION | VideoCastManager.FEATURE_LOCKSCREEN | VideoCastManager.FEATURE_WIFI_RECONNECT | VideoCastManager.FEATURE_AUTO_RECONNECT | VideoCastManager.FEATURE_CAPTIONS_PREFERENCE | VideoCastManager.FEATURE_DEBUGGING); } The Cast Controller Activity. Provided By Cast Companion Library
  120. 120. Cast Companion - MainActivity.java private void initCast() { // initialize VideoCastManager VideoCastManager. initialize(this, getString(R.string.app_id), VideoCastControllerActivity.class, null). setVolumeStep(VOLUME_INCREMENT). enableFeatures(VideoCastManager.FEATURE_NOTIFICATION | VideoCastManager.FEATURE_LOCKSCREEN | VideoCastManager.FEATURE_WIFI_RECONNECT | VideoCastManager.FEATURE_AUTO_RECONNECT | VideoCastManager.FEATURE_CAPTIONS_PREFERENCE | VideoCastManager.FEATURE_DEBUGGING); } Custom Namespace Like Message Channel from Previous Example
  121. 121. Cast Companion - MainActivity.java private void initCast() { // initialize VideoCastManager VideoCastManager. initialize(this, getString(R.string.app_id), VideoCastControllerActivity.class, null). setVolumeStep(VOLUME_INCREMENT). enableFeatures(VideoCastManager.FEATURE_NOTIFICATION | VideoCastManager.FEATURE_LOCKSCREEN | VideoCastManager.FEATURE_WIFI_RECONNECT | VideoCastManager.FEATURE_AUTO_RECONNECT | VideoCastManager.FEATURE_CAPTIONS_PREFERENCE | VideoCastManager.FEATURE_DEBUGGING); }
  122. 122. Cast Companion - MainActivity.java @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); mCastManager.addMediaRouterButton(menu, R.id.media_route_menu_item); return true; }
  123. 123. Cast Companion - MainActivity.java @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); mCastManager.addMediaRouterButton(menu, R.id.media_route_menu_item); return true; }
  124. 124. Cast Companion - MainActivity.java private void loadRemoteMedia(int position, MediaInfo media, boolean autoPlay) { mCastManager.startVideoCastControllerActivity(this, media, position, autoPlay); }
  125. 125. Cast Companion - MainActivity.java mCastButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { MediaMetadata metadata = new MediaMetadata(); MediaInfo media = new MediaInfo .Builder(mTextVideoUrl.getText().toString()) .setContentType("video/mp4") .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED) .setMetadata(metadata) .setStreamDuration(596) .build(); loadRemoteMedia(0, media, true); } });
  126. 126. Cast Companion - MainActivity.java mCastButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { MediaMetadata metadata = new MediaMetadata(); MediaInfo media = new MediaInfo .Builder(mTextVideoUrl.getText().toString()) .setContentType("video/mp4") .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED) .setMetadata(metadata) .setStreamDuration(596) .build(); loadRemoteMedia(0, media, true); } }); The Url to our Video e.g. .mp4 file
  127. 127. Cast Companion - MainActivity.java mCastButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { MediaMetadata metadata = new MediaMetadata(); MediaInfo media = new MediaInfo .Builder(mTextVideoUrl.getText().toString()) .setContentType("video/mp4") .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED) .setMetadata(metadata) .setStreamDuration(596) .build(); loadRemoteMedia(0, media, true); } }); Required. Contains Metadata like Studio, Production Year, etc.
  128. 128. Cast Companion - MainActivity.java mCastButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { MediaMetadata metadata = new MediaMetadata(); MediaInfo media = new MediaInfo .Builder(mTextVideoUrl.getText().toString()) .setContentType("video/mp4") .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED) .setMetadata(metadata) .setStreamDuration(596) .build(); loadRemoteMedia(0, media, true); } });

×