我使用Google Drive Android API(作为Google Play服务的一部分)将文件上传到云端。
使用以下代码(简化)连接客户端I
apiClient = new GoogleApiClient.Builder(context)
.addApi(Drive.API)
.setAccountName(preferences.getString("GOOGLE_DRIVE_ACCOUNT", null))
.build();
ConnectionResult connectionResult = apiClient.blockingConnect(SERVICES_CONNECTION_TIMEOUT_SEC, TimeUnit.SECONDS);
if (!connectionResult.isSuccess()) {
throw new ApiConnectionException(); //our own exception
}
使用以下代码(简化)上传文件I:
DriveApi.ContentsResult result = Drive.DriveApi.newContents(apiClient).await();
if (!result.getStatus().isSuccess()) {
/* ... code for error handling ... */
return;
}
OutputStream output = result.getContents().getOutputStream();
/* ... writing to output ... */
//create actual file on Google Drive
DriveFolder.DriveFileResult driveFileResult = Drive.DriveApi
.getFolder(apiClient, folderId)
.createFile(apiClient, metadataChangeSet, result.getContents())
.await();
除了一个特定的用户案例外,一切都按预期工作。当用户从"已连接的应用中删除我们的应用时(使用Google设置应用程序)此代码仍会返回所有调用的成功结果。虽然文件永远不会上传到Google云端硬盘。
与Google Play服务的连接也会成功。
是API的错误还是以某种方式检测到用户断开了应用程序?
答案 0 :(得分:1)
我不知道内部/外部的API,但是此页面可能会有所帮助https://support.google.com/drive/answer/2523073?hl=en。我会仔细检查accounts.google.com页面并验证是否已删除所有权限。这不会解决api行为,但至少可以验证权限。
答案 1 :(得分:0)
您是否收到UserRecoverableAuthIOException?因为你应该。任何尝试读取/上传到驱动器用户断开应用程序的位置应该返回此异常。您可能正在捕捉常规异常并错过了此消息。尝试调试,看看你是否没有得到这个例外。
如果你是,你所要做的就是重新申请
catch (UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), COMPLETE_AUTHORIZATION_REQUEST_CODE);
}
然后处理这样的回复:
case COMPLETE_AUTHORIZATION_REQUEST_CODE:
if (resultCode == RESULT_OK) {
// App is authorized, you can go back to sending the API request
} else {
// User denied access, show him the account chooser again
}
break;
}
答案 2 :(得分:-1)
要创建文件,请尝试根据this
发送IntentSender
通过将IntentSender提供给另一个应用程序,您授予它执行您指定的操作的权利,就好像另一个应用程序是您自己(具有相同的权限和标识)。看起来像待定意图。您可以使用
创建文件ResultCallback<ContentsResult> onContentsCallback =
new ResultCallback<ContentsResult>() {
@Override
public void onResult(ContentsResult result) {
// TODO: error handling in case of failure
MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
.setMimeType(MIME_TYPE_TEXT).build();
IntentSender createIntentSender = Drive.DriveApi
.newCreateFileActivityBuilder()
.setInitialMetadata(metadataChangeSet)
.setInitialContents(result.getContents())
.build(mGoogleApiClient);
try {
startIntentSenderForResult(createIntentSender, REQUEST_CODE_CREATOR, null,
0, 0, 0);
} catch (SendIntentException e) {
Log.w(TAG, "Unable to send intent", e);
}
}
};
在这里
`startIntentSenderForResult (IntentSender intent, int requestCode, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)`
如果requestCode&gt; = 0,则当活动退出时,此代码将在onActivityResult()
中返回。
在onActivityResult()
你可以
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
//REQUEST_CODE_CREATOR == 1
case REQUEST_CODE_CREATOR:
if (resultCode == RESULT_OK) {
DriveId driveId = (DriveId) data.getParcelableExtra(
OpenFileActivityBuilder.EXTRA_RESPONSE_DRIVE_ID);
showMessage("File created with ID: " + driveId);
}
finish();
break;
default:
super.onActivityResult(requestCode, resultCode, data);
break;
}
}
尝试获取此类apiClient
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API).addScope(Drive.SCOPE_FILE)
.setAccountName(mAccountName).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
/**
* Called when {@code mGoogleApiClient} is connected.
*/
@Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "GoogleApiClient connected");
}
/**
* Called when {@code mGoogleApiClient} is disconnected.
*/
@Override
public void onConnectionSuspended(int cause) {
Log.i(TAG, "GoogleApiClient connection suspended");
}
/**
* Called when {@code mGoogleApiClient} is trying to connect but failed.
* Handle {@code result.getResolution()} if there is a resolution is
* available.
*/
@Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "GoogleApiClient connection failed: " + result.toString());
if (!result.hasResolution()) {
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this, 0).show();
return;
}
try {
result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
} catch (SendIntentException e) {
Log.e(TAG, "Exception while starting resolution activity", e);
}
}
你可以像这样获得mAccountName
:
Account[] accounts = AccountManager.get(this).getAccountsByType("com.google");
if (accounts.length == 0) {
Log.d(TAG, "Must have a Google account installed");
return;
}
mAccountName = accounts[0].name;
希望这会有所帮助。