android - 如果我使用 GoogleSignIn + DriveClient,如何执行后台同步任务
问题描述
我们的用户有机会登录,授权应用访问他们的 Google Drive。我们基于GoogleSignIn
和实现DriveClient
。(不是另一个已弃用的 API GoogleApiClient
)
https://developers.google.com/drive/android/auth
用户退出应用程序后,我们希望 Google Drive 同步过程仍然在后台无缝运行,无需进一步的用户/UI 交互。(能够处理登录令牌在几天/小时后过期/无效的情况)
我可以知道如何做到这一点。任何代码示例都值得赞赏。
解决方案
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;
}
推荐阅读
- machine-learning - 如何处理 GMM 模型中的分类和非欧几里得数据?
- python - 在 Pandas 中重用打开的数据文件
- amazon-elastic-beanstalk - 使用 Puma 平台在 AWS Elastic Beanstalk Ruby 上禁用 Puma
- python - 如何使用 exec 将静态方法动态添加到类中?
- c - 如何将子结构数据附加到父结构?
- workflow - 在 Cadence 上使用周期性作业建模工作流程
- c# - Mandrill 版本 3 Ping() 方法
- html - 如何在悬停时使用 flexbox 显示附加文本
- javascript - If / Else 函数是两部分而不是一部分
- mysql - 安装在子目录中的 Wordpress 访问 WP-Admin