问题
I am using Google Drive.Api in order to get user's app data synced with users drive account.
The user database is in sqlite database format. I have successfully uploaded the file in binary to the drive but failing to download the file from within the app.
How I get the file URl :
final GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(this, Arrays.asList(DriveScopes.DRIVE_FILE));
credential.setSelectedAccountName(accountName);
service = new com.google.api.services.drive.Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), credential).build();
Query query = new Query.Builder()
.addFilter(Filters.eq(SearchableField.TITLE, "BackupFile"))
.build();
final DriveFolder folder = Drive.DriveApi.getRootFolder(mGoogleApiClient);
folder.queryChildren(mGoogleApiClient, query).setResultCallback(new ResultCallback<DriveApi.MetadataBufferResult>() {
@Override
public void onResult(DriveApi.MetadataBufferResult metadataBufferResult) {
final MetadataBuffer metadataBuffer = metadataBufferResult.getMetadataBuffer();
int iCount = metadataBuffer.getCount();
if (iCount == 1) {
Log.i("Tag", "file was found");
final DriveId myFileId = metadataBuffer.get(0).getDriveId();
final DriveFile file = Drive.DriveApi.getFile(mGoogleApiClient, myFileId);
new Thread(new Runnable() {
@Override
public void run() {
DriveResource.MetadataResult mdRslt = file.getMetadata(mGoogleApiClient).await();
if (mdRslt != null && mdRslt.getStatus().isSuccess()) {
String link = mdRslt.getMetadata().getWebContentLink();
Log.d("TAG", "Link to File:" + link);
DownloadBackup(link);
}
}
}).start();
}
metadataBuffer.release();
}
});
Trying to download the File via:
public void DownloadBackup(String url){
InputStream mInput=null;
FileOutputStream mOutput=null;
if(url != null && url.length() > 0 ){
try {
GoogleAccountCredential crd = GoogleAccountCredential.usingOAuth2(this, Arrays.asList(DriveScopes.DRIVE_FILE));
crd.setSelectedAccountName(accountName);
com.google.api.services.drive.Drive srv = new com.google.api.services.drive.Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), crd).build();
mInput = srv.getRequestFactory().buildGetRequest(new GenericUrl(url)).execute().getContent();
String outFileName = getApplicationContext().getDatabasePath(DatabaseHandler.DATABASE_NAME).getPath();
mOutput = new FileOutputStream(outFileName);
byte[] mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer)) > 0) {
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
Log.d("TAG", "Successfully Downloaded contents");
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
//Close the streams
if(mOutput != null){
mOutput.close();
}
if(mInput != null){
mInput.close();
}
} catch (IOException e) {
Log.e("Tag", "failed to close databases");
}
}
} else {
// The file doesn't have any content stored on Drive.
// return null;
Log.e("Tag", "No content on Drive");
}
}
Error Log:
W/System.err﹕ com.google.api.client.http.HttpResponseException: 401 Unauthorized
W/System.err﹕ <HTML>
W/System.err﹕ <HEAD>
W/System.err﹕ <TITLE>Unauthorized</TITLE>
W/System.err﹕ </HEAD>
W/System.err﹕ <BODY BGCOLOR="#FFFFFF" TEXT="#000000">
W/System.err﹕ <H1>Unauthorized</H1>
W/System.err﹕ <H2>Error 401</H2>
W/System.err﹕ </BODY>
W/System.err﹕ </HTML>
W/System.err﹕ [ 06-12 11:01:05.447 26208:26236 W/System.err ]
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1061)
W/System.err﹕ at com.example.app.activities.Main.DownloadBackup(Main.java:487)
W/System.err﹕ at com.example.app.activities.Main$15$1.run(Main.java:332)
W/System.err﹕ at java.lang.Thread.run(Thread.java:841)
回答1:
Here is how I do it successfully. Instead of saving the result of 'getWebContentLink', I save a file/folder ID (it is a string). And pass this ID to a method like this one:
/*************************************************************************
* get file contents
* @param resId file driveId
* @return file's content / null on fail
*/
static InputStream read(String resId) {
if (mGOOSvc != null && mConnected && resId != null) try {
File gFl = mGOOSvc.files().get(resId).setFields("downloadUrl").execute();
if (gFl != null){
String strUrl = gFl.getDownloadUrl();
return mGOOSvc.getRequestFactory()
.buildGetRequest(new GenericUrl(strUrl)).execute().getContent();
}
} catch (Exception e) { /* error handling */ }
return null;
}
retrieving a "downloadURL" and get the content. The full context of this method can be seen here.
Good Luck
来源:https://stackoverflow.com/questions/30795999/how-to-download-file-from-google-drive-using-drive-api