android – 如何在Google云端硬盘中替换文件?
作者:互联网
使用以下代码(取自android-quickstart),如果您拍摄多张照片,此代码可以生成多个具有相同名称的文件.如何修改以确保替换具有相同名称的文件?
public class MainActivity extends Activity implements ConnectionCallbacks,
OnConnectionFailedListener {
private static final String TAG = "android-drive-quickstart";
private static final int REQUEST_CODE_CAPTURE_IMAGE = 1;
private static final int REQUEST_CODE_CREATOR = 2;
private static final int REQUEST_CODE_RESOLUTION = 3;
private GoogleApiClient mGoogleApiClient;
private Bitmap mBitmapToSave;
/**
* Create a new file and save it to Drive.
*/
private void saveFileToDrive() {
// Start by creating a new contents, and setting a callback.
Log.i(TAG, "Creating new contents.");
final Bitmap image = mBitmapToSave;
Drive.DriveApi.newContents(mGoogleApiClient).setResultCallback(new ResultCallback<ContentsResult>() {
@Override
public void onResult(ContentsResult result) {
// If the operation was not successful, we cannot do anything
// and must
// fail.
if (!result.getStatus().isSuccess()) {
Log.i(TAG, "Failed to create new contents.");
return;
}
// Otherwise, we can write our data to the new contents.
Log.i(TAG, "New contents created.");
// Get an output stream for the contents.
OutputStream outputStream = result.getContents().getOutputStream();
// Write the bitmap data from it.
ByteArrayOutputStream bitmapStream = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.PNG, 100, bitmapStream);
try {
outputStream.write(bitmapStream.toByteArray());
} catch (IOException e1) {
Log.i(TAG, "Unable to write file contents.");
}
// Create the initial metadata - MIME type and title.
// Note that the user will be able to change the title later.
MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
.setMimeType("image/jpeg")
.setTitle("Android Photo.png")
.build();
// Create an intent for the file chooser, and start it.
IntentSender intentSender = Drive.DriveApi
.newCreateFileActivityBuilder()
.setInitialMetadata(metadataChangeSet)
.setInitialContents(result.getContents())
.build(mGoogleApiClient);
try {
startIntentSenderForResult(
intentSender, REQUEST_CODE_CREATOR, null, 0, 0, 0);
} catch (SendIntentException e) {
Log.i(TAG, "Failed to launch file chooser.");
}
}
});
}
@Override
protected void onResume() {
super.onResume();
if (mGoogleApiClient == null) {
// Create the API client and bind it to an instance variable.
// We use this instance as the callback for connection and connection
// failures.
// Since no account name is passed, the user is prompted to choose.
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
// Connect the client. Once connected, the camera is launched.
mGoogleApiClient.connect();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
@Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
@Override
protected void onPause() {
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
super.onPause();
}
@Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_CODE_CAPTURE_IMAGE:
// Called after a photo has been taken.
if (resultCode == Activity.RESULT_OK) {
// Store the image data as a bitmap for writing later.
mBitmapToSave = (Bitmap) data.getExtras().get("data");
}
break;
case REQUEST_CODE_CREATOR:
// Called after a file is saved to Drive.
if (resultCode == RESULT_OK) {
Log.i(TAG, "Image successfully saved.");
mBitmapToSave = null;
// Just start the camera again for another photo.
startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE),
REQUEST_CODE_CAPTURE_IMAGE);
}
break;
}
}
@Override
public void onConnectionFailed(ConnectionResult result) {
// Called whenever the API client fails to connect.
Log.i(TAG, "GoogleApiClient connection failed: " + result.toString());
if (!result.hasResolution()) {
// show the localized error dialog.
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this, 0).show();
return;
}
// The failure has a resolution. Resolve it.
// Called typically when the app is not yet authorized, and an
// authorization
// dialog is displayed to the user.
try {
result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
} catch (SendIntentException e) {
Log.e(TAG, "Exception while starting resolution activity", e);
}
}
@Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "API client connected.");
if (mBitmapToSave == null) {
// This activity has no UI of its own. Just start the camera.
startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE),
REQUEST_CODE_CAPTURE_IMAGE);
return;
}
saveFileToDrive();
}
@Override
public void onConnectionSuspended(int cause) {
Log.i(TAG, "GoogleApiClient connection suspended");
}
}
解决方法:
我按如下方式打开驱动文件进行写入:
writeDriveFile(DriveFile file, Handler handler){
//see query task below to get a drive file by its name. Be careful you can get multiple data elements in the MetadataBuffer below if you have uploaded multiple files with the same name.
Task<DriveContents> openFileTask = myDriveResourceClient.openFile(file, DriveFile.MODE_WRITE_ONLY);
然后用该任务将一些对象字节写入流someObject.getBytes(),这里没有魔法.然后提交结果.
openFileTask
.continueWithTask(task -> {
DriveContents contents = task.getResult();
// Process contents...
try (OutputStream writer = contents.getOutputStream()) {
writer.write(someObject.getBytes());
writer.close();
}
//Add whatever metadata you want here
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setLastViewedByMeDate(new Date())
.build();
//commit the file to Google Drive
Task<Void> commitTask = myDriveResourceClient.commitContents(contents, changeSet);
handler.onWriteResults();
return commitTask;
})
.addOnFailureListener(e -> {
// Handle failure
Log.e(TAG, "Unable to read contents", e);
handler.onDriveError(e);
});
处理程序只是我为Drive API执行后要处理的错误或结果定义的接口.您还可以添加addOnCompleteListener()以在写入完成后处理某些内容.
file是DriveFile的一个实例,可以通过查询任务获取.在任务代码块中找到的元数据有一个getDriveId()方法,它有一个asDrivefFile()方法来获取上面需要的Drive文件.
Query query = new Query.Builder()
.addFilter(Filters.eq(SearchableField.TITLE, "file name"))
.build();
Task<MetadataBuffer> queryTask = mDriveResourceClient.query(query);
然后处理MetadataBuffer
queryTask.continueWithTask(
task -> {
MetadataBuffer metadataBuffer = task.getResult() ;
//I have this loop because I wanted to know if there were other versions of the file on the drive
for(Metadata data : metadataBuffer) {
Log.d(TAG, "******************* metadataBuffer title is " + data.getTitle());
if(data.getTitle().equals("file name")){
//this is just a method I defined that encapsulates the drive writing code above.
writeDriveFile(data.getDriveId().asDriveFile(), jsonContent, handler);
}
}
return task;
})
.addOnCompleteListener(task -> {
//some complete tasks
}
})
.addOnFailureListener(e -> {
Log.e(TAG, "************************** Error searching for " + fileName, e);
handler.onDriveError(e);
});
此代码全部用于写入App文件夹,但您只需在创建资源客户端时设置正确的范围.
删除驱动器文件可以按如下方式完成.
public void deleteDriveFile(DriveResource file){
Task<Void> deleteTask = mDriveResourceClient.delete(file);
deleteTask
.continueWith(task -> {
Log.d(TAG, "************* Deleted drive file: " + file.getDriveId().toInvariantString());
return task;
})
.addOnFailureListener(e -> {
//log some sort of error for yourself
});
}
标签:android,google-drive-sdk 来源: https://codeday.me/bug/20190728/1562802.html