Closed GoogleCodeExporter closed 9 years ago
Sorry I hit enter by mistake before typing anything.
I'm switching my app away from the CastCompanionLibrary and a few of my users
are having trouble with Chromecast discovery. I stripped out all of the
unnecessary code and made an app just to see what was going on during discovery
and sent it to one of those users and the code is never getting any of the
callbacks from the media router. At the exact same time they can run my old app
with the CastCompanionLibrary and it will find the Chromecast just fine.
Here is the code I sent the user:
public class MainActivity extends AppCompatActivity {
private static SimpleDateFormat TIME_ONLY = new SimpleDateFormat("HH:mm:ss.SSS");
protected MediaRouter.Callback mMediaRouterCallback;
boolean isRunning = false;
private TextView logView;
private MediaRouter mMediaRouter;
private MediaRouteSelector mMediaRouteSelector;
private Timer removeRoutesTimer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMediaRouter = createMediaRouter(getApplicationContext());
mMediaRouterCallback = new MediaRouterCallback();
logView = (TextView) findViewById(R.id.log);
Button sendLog = (Button)findViewById(R.id.send_log);
sendLog.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent send = new Intent(Intent.ACTION_SENDTO);
String uriText = "mailto:" + Uri.encode("myemailaddress") +
"?subject=" + Uri.encode("Logs") +
"&body=" + Uri.encode(logView.getText().toString());
Uri uri = Uri.parse(uriText);
send.setData(uri);
startActivity(Intent.createChooser(send, "Send logs..."));
}
});
restart();
}
protected MediaRouter createMediaRouter(Context context) {
return MediaRouter.getInstance(context);
}
public void start() {
log("start");
if (isRunning) {
log("start - is running");
return;
}
isRunning = true;
if (mMediaRouteSelector == null) {
log("start - route selector null");
try {
mMediaRouteSelector = new MediaRouteSelector.Builder()
.addControlCategory(CastMediaControlIntent.categoryForCast(
CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID))
.build();
log("start - route selector built");
} catch (IllegalArgumentException e) {
log("start - route selector null exception " + e);
return;
}
} else {
log("start - route selector not null");
}
rescan();
}
private void log(String start) {
Calendar cal = new GregorianCalendar();
String currentLog = logView.getText().toString();
logView.setText(currentLog + "\n" + TIME_ONLY.format(cal.getTime()) + " - " + start);
}
public void stop() {
log("stop");
isRunning = false;
if (removeRoutesTimer != null) {
log("stop - removeRoutesTimer not null");
removeRoutesTimer.cancel();
removeRoutesTimer = null;
} else {
log("stop - removeRoutesTimer null");
}
if (mMediaRouter != null) {
log("stop - mMediaRouter not null");
runOnUiThread(new Runnable() {
@Override
public void run() {
log("stop - mMediaRouter inside ui thread");
mMediaRouter.removeCallback(mMediaRouterCallback);
}
});
} else {
log("stop - mMediaRouter null");
}
}
public void restart() {
log("restart");
stop();
log("restart - stop called");
start();
log("restart - start called");
}
public void rescan() {
log("rescan");
mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback,
MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
}
private class MediaRouterCallback extends MediaRouter.Callback {
@Override
public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo route) {
log("onRouteAdded - " + route.getName());
super.onRouteAdded(router, route);
}
@Override
public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo route) {
log("onRouteChanged - " + route.getName());
super.onRouteChanged(router, route);
}
@Override
public void onRoutePresentationDisplayChanged(MediaRouter router,
MediaRouter.RouteInfo route) {
log("onRoutePresentationDisplayChanged - [" + route.getName() + "] ["
+ route.getDescription() + "]");
super.onRoutePresentationDisplayChanged(router, route);
}
@Override
public void onRouteRemoved(final MediaRouter router, final MediaRouter.RouteInfo route) {
log("onRouteRemoved - " + route.getName());
super.onRouteRemoved(router, route);
}
@Override
public void onRouteVolumeChanged(MediaRouter router, final MediaRouter.RouteInfo route) {
super.onRouteVolumeChanged(router, route);
}
private void removeServices(final MediaRouter.RouteInfo route) {
log("removeServices - " + route.getName());
}
}
}
Here is the log he sent me:
17:50:24.194 - restart
17:50:24.194 - stop
17:50:24.195 - stop - removeRoutesTimer null
17:50:24.195 - stop - mMediaRouter not null
17:50:24.195 - stop - mMediaRouter inside ui thread
17:50:24.195 - restart - stop called
17:50:24.196 - start
17:50:24.196 - start - route selector null
17:50:24.197 - start - route selector built
17:50:24.197 - rescan
17:50:24.198 - restart - start called
So basically no calls to the callback methods.
Here is a log from my network where it works just fine (exact same apk):
15:59:27.307 - restart
15:59:27.307 - stop
15:59:27.308 - stop - removeRoutesTimer null
15:59:27.308 - stop - mMediaRouter not null
15:59:27.308 - stop - mMediaRouter inside ui thread
15:59:27.309 - restart - stop called
15:59:27.309 - start
15:59:27.309 - start - route selector null
15:59:27.311 - start - route selector built
15:59:27.311 - rescan
15:59:27.312 - restart - start called
15:59:28.457 - onRouteAdded - Master bedroom
15:59:28.482 - onRouteChanged - Master bedroom
15:59:28.484 - onRouteAdded - Living room chromecast
15:59:28.528 - onRouteChanged - Master bedroom
15:59:28.542 - onRouteChanged - Living room chromecast
15:59:28.542 - onRouteAdded - Basement east bedroom
15:59:28.639 - onRouteChanged - Master bedroom
15:59:28.640 - onRouteChanged - Living room chromecast
15:59:28.641 - onRouteAdded - Gym
15:59:28.641 - onRouteChanged - Basement east bedroom
16:01:42.117 - onRouteChanged - Living room chromecast
16:01:42.122 - onRouteChanged - Gym
16:01:42.124 - onRouteChanged - Basement east bedroom
16:01:50.663 - onRouteChanged - Master bedroom
16:01:50.664 - onRouteChanged - Living room chromecast
16:01:50.664 - onRouteChanged - Gym
16:01:50.664 - onRouteChanged - Basement east bedroom
So what is wrong with my discovery code?
Thanks.
Original comment by casol...@gmail.com
on 3 Sep 2015 at 7:06
Please be advised that Cast Companion Library is strongly recommended. If you
have a special use-case, do share.
Original comment by na...@google.com
on 5 Sep 2015 at 12:01
I totally understand that but I have moved to ConnectSDK
(http://connectsdk.com/). The example I posted above is the ConnectSDK
discovery code stripped off code that only makes sense on their SDK.
Like I said it works perfectly fine on my network but I have two users for whom
it never finds the Chromecast. I've had them run apps (including my own but an
older version) which use the CastCompanionLibrary and they find the Chromecast
just fine.
The code is ridiculously simple so I'm really curious as to where the bug is.
There are a couple of runOnUIThread calls in that code that I'm not sure if
they are needed but I've had the users test without those and they still have
the same issue.
Thanks.
Original comment by car...@instantbits.com
on 5 Sep 2015 at 12:20
I have been sending tests to a user and changing the add callback flag to
MediaRouter.CALLBACK_FLAG_FORCE_DISCOVERY fixes the issue but according to the
documentation that isn't the recommended flag.
Original comment by casol...@gmail.com
on 7 Sep 2015 at 12:50
Unfortunately, we can not help with third party libraries. Your implementation
should be closely inline with the code-base from Cast Companion Library which
is available on GitHub. Please refer to the same.
Original comment by na...@google.com
on 10 Sep 2015 at 9:06
Thank you for the reply but I'm not asking you to troubleshoot a third party
library, the example I posted above is self contained. If you look at the code
it is ridiculously simple, there are just a few lines dealing with discovery:
mMediaRouter = MediaRouter.getInstance(context)
mMediaRouterCallback = new MediaRouterCallback();
mMediaRouteSelector = new MediaRouteSelector.Builder()
.addControlCategory(CastMediaControlIntent.categoryForCast(
CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID))
.build();
mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback,
MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
That is basically it.
So where is the bug with the code? I've read the CastCompanionLibrary code
several times and can't see any difference on this little bit of code.
Original comment by casol...@gmail.com
on 10 Sep 2015 at 9:43
Are these low-RAM devices? Please note that the documentation
(https://developer.android.com/reference/android/support/v7/media/MediaRouter.ht
ml#CALLBACK_FLAG_REQUEST_DISCOVERY) clearly mentions the flag
CALLBACK_FLAG_REQUEST_DISCOVERY is not supported on low-RAM devices
(https://developer.android.com/reference/android/app/ActivityManager.html#isLowR
amDevice()). If the CALLBACK_FLAG_FORCE_DISCOVERY works on those devices, most
likely they are low-RAM devices.
If that's not the case, please respond back with the device configurations for
the devices these issue can be seen on and we'd gladly look into it.
Original comment by na...@google.com
on 16 Sep 2015 at 8:21
I've put the question to multiple users as to what kind of device they have but
only one has responded. She said she had one phone until last weekend and now
has a new one.
Old phone was a Samsung galaxy prevail Ram: 384mb
And now has a Moto E Ram: 1gb
On my app I use CALLBACK_FLAG_REQUEST_DISCOVERY normally but I added a "rescan"
button which uses CALLBACK_FLAG_FORCE_DISCOVERY, and she says on the new phone
she doesn't have to use "rescan" as often as on the old phone but she still has
to use it.
If it is an issue with low memory, why does my old app with the CCL and the
CastVideos sample app work just fine? doesn't the CCL use
CALLBACK_FLAG_REQUEST_DISCOVERY?
Thanks.
Original comment by casol...@gmail.com
on 17 Sep 2015 at 3:43
Another user sent me their device model. THL T6 PRO and it looks like it has 1
gig of ram. They mentioned that other Chromecast apps don't have that issue,
they mentioned one that I know uses CCL.
Original comment by casol...@gmail.com
on 17 Sep 2015 at 4:05
Please refer to this example of MediaRouter implementation -
https://github.com/googlecast/MediaRouter-Cast-Button-android - to debug
MediaRouter issues.
Original comment by na...@google.com
on 17 Sep 2015 at 5:23
I compiled that example and sent it to two users. One of them said the device
list populated right away and with my app he said sometimes it does and
sometimes he has to "rescan" (which uses CALLBACK_FLAG_FORCE_DISCOVERY).
The other user (the one with the two phones), said that on her new phone the
device list populated right away but that on the old phone the device list was
empty.
For that second user, her old phone certainly has less ram so maybe that is the
issue but I still don't understand why the CCL works just fine on her old
phone?
Thanks.
Original comment by casol...@gmail.com
on 19 Sep 2015 at 1:43
I have another user who is on a mobile hotspot for whom apps built with the
CastCompanionLibrary work fine but other apps don't, including
https://github.com/googlecast/MediaRouter-Cast-Button-android
He basically gets not devices at all unless the CastCompanionLibrary is used.
Original comment by casol...@gmail.com
on 1 Oct 2015 at 7:42
Original issue reported on code.google.com by
casol...@gmail.com
on 3 Sep 2015 at 7:05