[英]Create / Edit / Retrieve DB file with GDAA (Google Drive Api for Android)
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.
我正在尝试使用GDAA(适用于Android的Google Drive API = https://developers.google.com/drive/android/appfolder )来备份和还原我的数据库文件。 Not REST API.
不是REST API。 I tried use their demo classes from here: https://github.com/googledrive/android-demos/ , but no positive result.
我尝试从这里使用他们的演示类: https : //github.com/googledrive/android-demos/ ,但是没有积极的结果。
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. 我通过身份验证并将数据库文件保存到Google云端硬盘中的“应用程序文件夹”中,但无法编辑或检索此文件。 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: 如果得到“!result.getStatus()。isSuccess()”,我想调用“创建活动”:
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? 请问您知道此演示的正确方法吗?
Unfortunately, I don't have time to dig through all of the code above, but I can (at least) give you some general pointers. 不幸的是,我没有时间深入研究上面的所有代码,但是我可以(至少)为您提供一些通用的指针。
First, the demos you mention do work, I've tested it and have it running. 首先,您提到的演示可以正常工作,我已经对其进行了测试并使其运行。 But since the demos cover just about any scenario, it is difficult to trace your possible error.
但是,由于演示几乎涵盖了所有情况,因此很难跟踪您可能的错误。
Now, the pointers: 现在,指针:
I've put together a basic CRUD wrapper for the GDAA, you can find it here . 我为GDAA整理了一个基本的CRUD包装器,您可以在这里找到它。
In the GDAA.java class, you'll find ' createFile() ' method. 在GDAA.java类中,您将找到“ createFile() ”方法。 I think you have to give it the ' result.getDriveFile().getDriveId() ' that you received in your ' fileCallback ' above (as a parent).
我认为您必须给它在您的“ fileCallback ”中作为父母收到的“ result.getDriveFile()。getDriveId() ”。 The content is passed in as a standard java.io.File
内容作为标准java.io.File传入
That method returns DriveId (in String form so I can easily cache it) and you can pass that DriveId to the 'read()' method that will give you a byte array (stream) back. 该方法返回DriveId(以String形式,因此我可以轻松地对其进行缓存),并且您可以将该DriveId传递给“ read()”方法,该方法将为您提供一个字节数组(流)。 Dump it to a java.io.File and you're done (don't forget to run it off-UI thread, they are blocking methods).
将其转储到java.io.File中,您就可以完成操作(不要忘记在非UI线程中运行它,它们是阻塞方法)。
I would recommend to test it first using Drive's root (not app folder), so you can actually see the file in drive.google.com 我建议先使用云端硬盘的根目录(而不是应用程序文件夹)对其进行测试,以便您可以实际在drive.google.com中看到该文件
Good Luck 祝好运
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.