Android : Unable to find chromecast devices in a reliable manner

on Monday, November 10, 2014


This is my first question in stackoverflow. So please be patient with me...


I want to start an activity which detects all chromecast device in my WLAN.


First of all I implement an own activity extending Activity.


The onCreate()-Method looks like this:



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

try
{
// get the parameters from intent
Bundle extras = getIntent().getExtras();
if (extras == null)
{
// this is just for testing purposes --> set a sample directory name
ms_ImageBasePath = "/storage/extSdCard/Bilder/2014/2014_08/2014_08_09";
ms_ImageFilename = "";
}
else
{
// get the data from the calling activity
ms_ImageBasePath = extras.getString(FWCastActivity.IMAGEPATH2CAST);
ms_ImageFilename = extras.getString(FWCastActivity.IMAGE2CAST);
}

// create the controls
mo_Button_left = (ImageButton)this.findViewById(R.id.cast_left_imageButton);
mo_Button_right = (ImageButton)this.findViewById(R.id.cast_right_imageButton);
mo_Button_stop = (ImageButton)this.findViewById(R.id.cast_stop_imageButton);
mo_SelectDeviceButton = (ImageButton)findViewById(R.id.cast_select_device_imageButton);
mo_SelectDeviceButton.setBackgroundColor(Color.WHITE);
mo_Filename = (TextView)findViewById(R.id.cast_filename_textView);
mo_Filename.setText("-");
mo_Headline = (TextView)findViewById(R.id.cast_headline_textView);
mo_ImageView = (ImageView)findViewById(R.id.cast_currentview_imageView);

// prepare the spinner which collects the routes
mo_CastDeviceSpinner = (Spinner) findViewById(R.id.cast_device_selection_spinner);
updateAdapter();


// prepare all the images for casting
if (prepareImages()==false)
{
// an error happened
throw new Exception("No images found in " + ms_ImageBasePath + " to cast");
}

// get the ip address --> important for casting images
ms_IPAddress = getLocalIpv4Address();

// create the handlers for the controls
createHandler();

// create the webserver which servers the images to chromecast
createWebServer(ms_ImageBasePath);

// create the mediarouter --> this starts searching for available devices
createMediaRouter();


}
catch (Exception e)
{
// problem in onCreate
doLog("Exception in onCreate: " + e.toString());
// to do: make sure process stops here...
}
}


The createMediaRouter()-method looks like this:



private void createMediaRouter()
{
try
{
mMediaRouter = MediaRouter.getInstance(getApplicationContext());

// Create a MediaRouteSelector for the type of routes your app supports
//mMediaRouteSelector = new MediaRouteSelector.Builder().addControlCategory(CastMediaControlIntent.categoryForCast(CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID)).build();
mMediaRouteSelector = new MediaRouteSelector.Builder().addControlCategory(CastMediaControlIntent.categoryForCast(APPID)).build();

// Create a MediaRouter callback for discovery events
mMediaRouterCallback = new CastFWMediaRouterCallback();

}
catch (Exception e)
{
doLog("Exception in createMediaRouter: " + e.toString());
}
}


The callback class looks like this:



private class CastFWMediaRouterCallback extends MediaRouter.Callback
{

@Override
public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo info)
{
try
{
doLog("onRouteAdded: info.getName = " + info.getName());
// Add route to list of discovered routes
synchronized (this)
{
mRouteInfos.add(info);
mRouteNames.add(info.getName() + " (" + info.getDescription()+ ")");

updateAdapter();

doLog(" --> Found route: Now you can select route from list and start casting");
}
}
catch (Exception e)
{
doLog("Ex in MyMediaRouterCallback.onRouteAdded: " + e.toString());
}
}

@Override
public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo info)
{
try
{

doLog("onRouteRemoved: info=" + info);
// Remove route from list of routes
synchronized (this)
{
for (int i = 0; i < mRouteInfos.size(); i++) {
MediaRouter.RouteInfo routeInfo = mRouteInfos.get(i);
if (routeInfo.equals(info))
{
mRouteInfos.remove(i);
mRouteNames.remove(i);
updateAdapter();
return;
}
}
}
}
catch (Exception e)
{
doLog("Ex in MyMediaRouterCallback.onRouteRemoved: " + e.toString());
}
}

@Override
public void onRouteSelected(MediaRouter router, RouteInfo info)
{
try
{

doLog("onRouteSelected: info=" + info.getName());
mSelectedDevice = CastDevice.getFromBundle(info.getExtras());
String routeId = info.getId();
doLog("route with id " + routeId + " selected --> now preparing API Client");
prepareApiClient();

}
catch (Exception e)
{
doLog("Exception in MyMediaRouterCallback.onRouteSelected: " + e.toString());
}
}

@Override
public void onRouteUnselected(MediaRouter router, RouteInfo info) {
doLog("onRouteUnselected: info=" + info);
teardown();
mSelectedDevice = null;
}

} // end of inner class


The callback-class is added in the onResume-method



@Override
protected void onResume()
{
super.onResume();
if (mMediaRouter!=null)
{
// Add the callback to start device discovery
mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback,MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);

}
}


This code works properly for the first time I use it. It starts, my chromecast device is detected and I can send image-links on my smartphone over an integrated webserver. Images are shown on the chromecast device -great. If I finish the activity and create it again, the routes are not found again.


I've already discussed things on Google+ but the guys there told me to post my code on StackOverflow. It would be great to get some help. I'd also appreciate a piece of code where the chromecast devices are detected manually.


Any help appreciated! Thanks!


0 comments:

Post a Comment