skilled friends.
Could you someone help me with my problem, please? I'm trying to use GDAA (Google Drive API for Android = https://developers.google.com/drive/android/appfolder) for backup and restore my DB file. Not REST API. I tried use their demo classes from here: https://github.com/googledrive/android-demos/, but no positive result.
I suceed with authentication and with save my DB file into App Folder in Google Drive, but I can not edit or retrieve this file. I only still create new and new files. Could you help me, please?
I call this Edit activity:
public class EditContentsActivity extends BaseDemoActivity {
private static final String TAG = "EditContentsActivity";
@Override
public void onConnected(Bundle connectionHint) {
super.onConnected(connectionHint);
final ResultCallback<DriveIdResult> idCallback = new ResultCallback<DriveIdResult>() {
@Override
public void onResult(DriveIdResult result) {
if (!result.getStatus().isSuccess()) {
Intent intent = new Intent(getBaseContext(), CreateFileInAppFolderActivity.class);
startActivity(intent);
return;
}
DriveFile file = Drive.DriveApi.getFile(getGoogleApiClient(), result.getDriveId());
new EditContentsAsyncTask(EditContentsActivity.this).execute(file);
}
};
Drive.DriveApi.fetchDriveId(getGoogleApiClient(), EXISTING_FILE_ID)
.setResultCallback(idCallback);
}
public class EditContentsAsyncTask extends ApiClientAsyncTask<DriveFile, Void, Boolean> {
public EditContentsAsyncTask(Context context) {
super(context);
}
@Override
protected Boolean doInBackgroundConnected(DriveFile... args) {
DriveFile file = args[0];
try {
DriveContentsResult driveContentsResult = file.open(
getGoogleApiClient(), DriveFile.MODE_WRITE_ONLY, null).await();
if (!driveContentsResult.getStatus().isSuccess()) {
return false;
}
DriveContents driveContents = driveContentsResult.getDriveContents();
OutputStream outputStream = driveContents.getOutputStream();
String dbpath = "/data/" + "com.myapp" + "/databases/" + DatabaseHelper.DB_NAME;
FileInputStream fis = new FileInputStream(Environment.getDataDirectory() + dbpath);
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
com.google.android.gms.common.api.Status status =
driveContents.commit(getGoogleApiClient(), null).await();
outputStream.flush();
outputStream.close();
fis.close();
return status.getStatus().isSuccess();
} catch (IOException e) {
Log.e(TAG, "IOException while appending to the output stream", e);
}
return false;
}
@Override
protected void onPostExecute(Boolean result) {
if (!result) {
showMessage("Error while editing contents");
return;
}
showMessage("Successfully edited contents");
}
}
If I get "!result.getStatus().isSuccess()" I want to call Create Activity:
public class CreateFileInAppFolderActivity extends BaseDemoActivity {
@Override
public void onConnected(Bundle connectionHint) {
super.onConnected(connectionHint);
// create new contents resource
Drive.DriveApi.newDriveContents(getGoogleApiClient()).setResultCallback(driveContentsCallback);
}
final private ResultCallback<DriveContentsResult> driveContentsCallback =
new ResultCallback<DriveContentsResult>() {
@Override
public void onResult(DriveContentsResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Error while trying to create new file contents");
return;
}
String mimeType = MimeTypeMap.getSingleton().getExtensionFromMimeType("db");
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle(EXISTING_FILE_ID)
.setMimeType(mimeType)
.build();
OutputStream os = result.getDriveContents().getOutputStream();
try {
String dbpath = "/data/" + "com.myapp" + "/databases/" + DatabaseHelper.DB_NAME;
FileInputStream fis = new FileInputStream(Environment.getDataDirectory() + dbpath);
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
Drive.DriveApi.getAppFolder(getGoogleApiClient())
.createFile(getGoogleApiClient(), changeSet, result.getDriveContents())
.setResultCallback(fileCallback);
os.flush();
os.close();
fis.close();
throw new IOException("");
} catch (IOException e) {
Log.e("IOExceptions=", e.toString());
Drive.DriveApi.getAppFolder(getGoogleApiClient()).delete(getGoogleApiClient());
}
}
};
final private ResultCallback<DriveFileResult> fileCallback = new
ResultCallback<DriveFileResult>() {
@Override
public void onResult(DriveFileResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Error while trying to create the file");
return;
}
showMessage("Created a file in App Folder: "
+ result.getDriveFile().getDriveId());
}
};
All extend this Base Demo Activity:
public abstract class BaseDemoActivity extends Activity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = "BaseDriveActivity";
/**
* DriveId of an existing folder to be used as a parent folder in
* folder operations samples.
*/
public static final String EXISTING_FOLDER_ID = "0B2EEtIjPUdX6MERsWlYxN3J6RU0";
/**
* DriveId of an existing file to be used in file operation samples..
*/
public static final String EXISTING_FILE_ID = "0ByfSjdPVs9MZTHBmMVdSeWxaNTg";
/**
* Extra for account name.
*/
protected static final String EXTRA_ACCOUNT_NAME = "account_name";
/**
* Request code for auto Google Play Services error resolution.
*/
protected static final int REQUEST_CODE_RESOLUTION = 1;
/**
* Next available request code.
*/
protected static final int NEXT_AVAILABLE_REQUEST_CODE = 2;
/**
* Google API client.
*/
private GoogleApiClient mGoogleApiClient;
/**
* Called when activity gets visible. A connection to Drive services need to
* be initiated as soon as the activity is visible. Registers
* {@code ConnectionCallbacks} and {@code OnConnectionFailedListener} on the
* activities itself.
*/
@Override
protected void onResume() {
super.onResume();
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addScope(Drive.SCOPE_APPFOLDER) // required for App Folder sample
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
mGoogleApiClient.connect();
}
/**
* Handles resolution callbacks.
*/
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_RESOLUTION && resultCode == RESULT_OK) {
mGoogleApiClient.connect();
}
}
/**
* Called when activity gets invisible. Connection to Drive service needs to
* be disconnected as soon as an activity is invisible.
*/
@Override
protected void onPause() {
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
super.onPause();
}
/**
* 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()) {
// show the localized error dialog.
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);
}
}
/**
* Shows a toast message.
*/
public void showMessage(String message) {
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
/**
* Getter for the {@code GoogleApiClient}.
*/
public GoogleApiClient getGoogleApiClient() {
return mGoogleApiClient;
}
Retrieve Activity:
public class RetrieveContentsActivity extends BaseDemoActivity {
private static final String TAG = "RetrieveContentsActivity";
@Override
public void onConnected(Bundle connectionHint) {
super.onConnected(connectionHint);
Drive.DriveApi.fetchDriveId(getGoogleApiClient(), EXISTING_FILE_ID)
.setResultCallback(idCallback);
}
final private ResultCallback<DriveIdResult> idCallback = new ResultCallback<DriveIdResult>() {
@Override
public void onResult(DriveIdResult result) {
new RetrieveDriveFileContentsAsyncTask(
RetrieveContentsActivity.this).execute(result.getDriveId());
}
};
final private class RetrieveDriveFileContentsAsyncTask
extends ApiClientAsyncTask<DriveId, Boolean, String> {
public RetrieveDriveFileContentsAsyncTask(Context context) {
super(context);
}
@Override
protected String doInBackgroundConnected(DriveId... params) {
String contents = null;
DriveFile file = Drive.DriveApi.getFile(getGoogleApiClient(), params[0]);
DriveContentsResult driveContentsResult =
file.open(getGoogleApiClient(), DriveFile.MODE_READ_ONLY, null).await();
if (!driveContentsResult.getStatus().isSuccess()) {
return null;
}
DriveContents driveContents = driveContentsResult.getDriveContents();
BufferedReader reader = new BufferedReader(
new InputStreamReader(driveContents.getInputStream()));
StringBuilder builder = new StringBuilder();
String line;
try {
while ((line = reader.readLine()) != null) {
builder.append(line);
}
contents = builder.toString();
} catch (IOException e) {
Log.e(TAG, "IOException while reading from the stream", e);
}
driveContents.discard(getGoogleApiClient());
return contents;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (result == null) {
showMessage("Error while reading from the file");
return;
}
showMessage("File contents: " + result);
}
}
And there is Authentication code:
public abstract class ApiClientAsyncTask<Params, Progress, Result>
extends AsyncTask<Params, Progress, Result> {
private GoogleApiClient mClient;
public ApiClientAsyncTask(Context context) {
GoogleApiClient.Builder builder = new GoogleApiClient.Builder(context)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE);
mClient = builder.build();
}
@Override
protected final Result doInBackground(Params... params) {
Log.d("TAG", "in background");
final CountDownLatch latch = new CountDownLatch(1);
mClient.registerConnectionCallbacks(new ConnectionCallbacks() {
@Override
public void onConnectionSuspended(int cause) {
}
@Override
public void onConnected(Bundle arg0) {
latch.countDown();
}
});
mClient.registerConnectionFailedListener(new OnConnectionFailedListener() {
@Override
public void onConnectionFailed(ConnectionResult arg0) {
latch.countDown();
}
});
mClient.connect();
try {
latch.await();
} catch (InterruptedException e) {
return null;
}
if (!mClient.isConnected()) {
return null;
}
try {
return doInBackgroundConnected(params);
} finally {
mClient.disconnect();
}
}
/**
* Override this method to perform a computation on a background thread, while the client is
* connected.
*/
protected abstract Result doInBackgroundConnected(Params... params);
/**
* Gets the GoogleApliClient owned by this async task.
*/
protected GoogleApiClient getGoogleApiClient() {
return mClient;
}
Do you know the right approach with this demo, please?