Reputation: 11
I've been working on this for weeks no joke but I'm really stumped at this one part. So I'm in the process of implementing Google Cast into a poorly constructed codebase that I inherited.
Specifically, I'm using this source as reference since the codebase was written entirely in Java for some arbitrary reason: https://github.com/googlecast/CastVideos-android
And to be more specific, all I'm trying to do right now is get the
mCastContext = CastContext.getSharedInstance(this,localExecutor).getResult();
line in VideoBrowserActivity to work in my project. However, I am getting this error when implementing it but not when I run the other project: Unable to start activity ComponentInfo{}: java.lang.IllegalStateException: Task is not yet complete
Here are the important parts of my work and the reference file, respectively:
public class VideoExoPlayerActivity extends BaseActivity implements OnClickHandlerInterface {
private ActivityVideoExoPlayerBinding binding;
private VideoPlayerViewModel viewModel;
private String videoUuid;
private ExoPlayer exoPlayer;
private DefaultTrackSelector trackSelector;
private String drmLicenseUrl;
private String mimeType;
private Boolean isDashDRM;
private AudioManager manager;
private boolean isScreenLock = false;
private boolean isShortVideo = false;
private boolean isRollOverVideoAvailable = false;
private boolean isRollOverShow = false;
private boolean isRollOverDismiss = false;
private int currentPosition = 0;
private int continuePosition = -1;
private List<VideoUuidURLModel> list_url = new ArrayList<>();
private List<VideoPlayerDataResponse.Data> list_video = new ArrayList<>();
private PictureInPictureParams.Builder mPictureInPictureParamsBuilder;
private CastContext mCastContext;
private CastSession mCastSession;
private MediaRouteButton mMediaRouteButton;
private SessionManager mSessionManager;
private SessionManagerListener<CastSession> mSessionManagerListener =
new SessionManagerListenerImpl();
private Executor localExecutor = Executors.newSingleThreadExecutor();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_video_exo_player);
viewModel = new ViewModelProvider(this, new CommonFactory<>(this)).get(VideoPlayerViewModel.class);
mCastContext = CastContext.getSharedInstance(this, localExecutor).getResult();
initView();
hideStatusBar();
startService(new Intent(this, HistoryAPIBackgroundService.class));
}
public class VideoBrowserActivity extends AppCompatActivity {
private static final String TAG = "VideoBrowserActivity";
private CastContext mCastContext;
private final SessionManagerListener<CastSession> mSessionManagerListener =
new MySessionManagerListener();
private CastSession mCastSession;
private MenuItem mediaRouteMenuItem;
private MenuItem mQueueMenuItem;
private Toolbar mToolbar;
private IntroductoryOverlay mIntroductoryOverlay;
private CastStateListener mCastStateListener;
private Executor localExecutor = Executors.newSingleThreadExecutor();
private class MySessionManagerListener implements SessionManagerListener<CastSession> {
@Override
public void onSessionEnded(CastSession session, int error) {
if (session == mCastSession) {
mCastSession = null;
}
invalidateOptionsMenu();
}
@Override
public void onSessionResumed(CastSession session, boolean wasSuspended) {
mCastSession = session;
invalidateOptionsMenu();
}
@Override
public void onSessionStarted(CastSession session, String sessionId) {
mCastSession = session;
invalidateOptionsMenu();
}
@Override
public void onSessionStarting(CastSession session) {
}
@Override
public void onSessionStartFailed(CastSession session, int error) {
}
@Override
public void onSessionEnding(CastSession session) {
}
@Override
public void onSessionResuming(CastSession session, String sessionId) {
}
@Override
public void onSessionResumeFailed(CastSession session, int error) {
}
@Override
public void onSessionSuspended(CastSession session, int reason) {
}
}
/*
* (non-Javadoc)
* @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video_browser);
setupActionBar();
mCastStateListener = new CastStateListener() {
@Override
public void onCastStateChanged(int newState) {
if (newState != CastState.NO_DEVICES_AVAILABLE) {
showIntroductoryOverlay();
}
}
};
mCastContext = CastContext.getSharedInstance(this,localExecutor).getResult();
}
There are some things in mine that look to be missing, but I've tried implementing everything you can see already and nothing has changed my result. Please ask if you need to see other parts of the code because I have no idea if this problem could be coming from somewhere else. From what I can tell, there are next to no tutorials about implementing this in Java so I'm doing it very blind and it has been very difficult so I really appreciate any help I can get.
Upvotes: 1
Views: 711
Reputation: 51
It's not the best option, I guess, but if you want to get the object in the main thread, this works for me. Java Versión:
public CastContext getCastContext(Context context) {
ExecutorService executor = Executors.newSingleThreadExecutor();
try {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
CompletableFuture<CastContext> castContextFuture = new CompletableFuture<>();
castContextFuture.complete(CastContext.getSharedInstance(context, executor).getResult());
return castContextFuture.get();
}
} catch (Exception e) {
throw new IllegalStateException("Error: couldn't get CastContext", e);
}
return null;
}
Kotlin Versión:
fun getCastContext(context: Context) : CastContext {
val executor = Executors.newSingleThreadExecutor()
val castContextTask: Task<CastContext> = CastContext.getSharedInstance(context, executor)
return try {
runBlocking {
castContextTask.await()
}
} catch (e : Exception) {
throw IllegalStateException("error couldn't get CastContext")
}
}
Upvotes: 0
Reputation: 751
This doesn't answer your question directly as to why your app behaves differently than the google cast reference app but you can add OnCompleteListener then set the context:
Kotlin:
CastContext.getSharedInstance(this, castExecutor).addOnCompleteListener {
castContext = it.result
castContext?.addCastStateListener(this)
}
Java:
Task task = CastContext.getSharedInstance(this,localExecutor);
task.addOnCompleteListener(task1 -> mCastContext = (CastContext) task1.getResult());
// or
Task task = CastContext.getSharedInstance(this,localExecutor);
task.addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
mCastContext = (CastContext)task.getResult();
}
});
I am stuck at the same point (much of today) as yourself trying to figure out why the CastContext.getSharedInstance(this, castExecutor).result gives the "Task is not yet complete" exception in my own app but not the reference app even though I have followed the same steps as far as I can tell.
Upvotes: 0