CDK
CDK

Reputation: 11

How can I resolve Task is not yet complete exception when implementing Google Cast into project?

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

Answers (2)

Darkryh
Darkryh

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

Paul Frank Allan
Paul Frank Allan

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

Related Questions