首页 > 解决方案 > 如果我使用 GoogleSignIn + DriveClient,如何执行后台同步任务

问题描述

我们的用户有机会登录,授权应用访问他们的 Google Drive。我们基于GoogleSignIn和实现DriveClient。(不是另一个已弃用的 API GoogleApiClient

https://developers.google.com/drive/android/auth

用户退出应用程序后,我们希望 Google Drive 同步过程仍然在后台无缝运行,无需进一步的用户/UI 交互。(能够处理登录令牌在几天/小时后过期/无效的情况)

我可以知道如何做到这一点。任何代码示例都值得赞赏。

标签: androidgoogle-drive-apigoogle-drive-android-api

解决方案


silentSignIn是解决问题的关键。silentSignIn当失败时,我们还需要处理边缘情况。这是真实世界的代码片段。


public static GoogleSignInClient buildGoogleSignInClient() {
    GoogleSignInOptions signInOptions =
            new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                    .requestScopes(Drive.SCOPE_APPFOLDER)
                    .build();
    return GoogleSignIn.getClient(WeNoteApplication.instance(), signInOptions);
}

public static boolean silentSignInThenSync(SyncViewModel syncViewModel, boolean handleSignInRequired) {
    GoogleSignInClient googleSignInClient = buildGoogleSignInClient();

    Task<GoogleSignInAccount> task = googleSignInClient.silentSignIn();

    if (task.isSuccessful()) {
        syncViewModel.getSlientSignInSuccessLiveData().postValue(true);

        return sync(task.getResult(), syncViewModel);
    } else {

        try {
            Tasks.await(task);
            try {
                GoogleSignInAccount googleSignInAccount = task.getResult(ApiException.class);

                syncViewModel.getSlientSignInSuccessLiveData().postValue(true);

                return sync(googleSignInAccount, syncViewModel);
            } catch (ApiException e) {
                Log.e(TAG, "", e);

                if (handleSignInRequired) {
                    if (e.getStatusCode() == GoogleSignInStatusCodes.SIGN_IN_REQUIRED) {
                        syncViewModel.getSignInRequiredLiveData().postValue(true);
                        return false;
                    }
                }

                String message = WeNoteApplication.instance().getString(R.string.sync_with_google_drive_failed_template, e.getLocalizedMessage());
                syncViewModel.getMessageLiveData().postValue(message);
            }
        } catch (ExecutionException e) {
            Log.e(TAG, "", e);

            if (handleSignInRequired) {
                if (e.getCause() instanceof ApiException) {
                    if (((ApiException) e.getCause()).getStatusCode() == GoogleSignInStatusCodes.SIGN_IN_REQUIRED) {
                        syncViewModel.getSignInRequiredLiveData().postValue(true);
                        return false;
                    }
                }
            }

            String message = WeNoteApplication.instance().getString(R.string.sync_with_google_drive_failed_template, e.getLocalizedMessage());
            syncViewModel.getMessageLiveData().postValue(message);
        } catch (InterruptedException e) {
            Log.e(TAG, "", e);

            String message = WeNoteApplication.instance().getString(R.string.sync_with_google_drive_failed_template, e.getLocalizedMessage());
            syncViewModel.getMessageLiveData().postValue(message);
        }
    }

    return false;
}

推荐阅读