如何以编程方式从 Android 中的 Google 驱动器选择的文件下载并保存在本地目录中?

问题描述 投票:0回答:2

我在我的应用程序中使用谷歌Drive API,我可以从谷歌驱动器中选择(.doc/docx/.pdf)文件,到目前为止一切都很好。但是我想下载选定的文件并需要使用

Multipart
将该文件发送到我们的服务器。我尝试了多种方法,我得到了
DriveId
DriveFile
但不幸的是我无法下载下载选定的文件。

我已经阅读了Android开发者文档

我正在使用下面的代码

import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.drive.Drive; 
import com.google.android.gms.drive.DriveFile;
import com.google.android.gms.drive.DriveId;
import com.google.android.gms.drive.DriveResource;
import com.google.android.gms.drive.OpenFileActivityBuilder;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory; 
import com.google.api.services.drive.DriveScopes;

public class DriveActivity extends Activity implements GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener {
/**
 * 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;
private static final String TAG = "===GoogleDriveActivity";
private static final int REQUEST_CODE_OPENER = 2;
/**
 * Google API client.
 */
private GoogleApiClient mGoogleApiClient;
private static final String[] SCOPES = {DriveScopes.DRIVE_FILE};

final HttpTransport transport = AndroidHttp.newCompatibleTransport();
final JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
private String accountName;
DriveResource.MetadataResult metadataResult;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    connect();
}

@Override
protected void onStop() {
    if (mGoogleApiClient != null) {
        mGoogleApiClient.disconnect();
    }
    super.onStop();
}

@Override
protected void onRestart() {
    super.onRestart();
    connect();
}


private void connect() {
    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();
}

/**
 * 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.
        GoogleApiAvailability.getInstance().getErrorDialog(this, result.getErrorCode(), 0).show();
        return;
    }
    try {
        result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
    } catch (IntentSender.SendIntentException e) {
        Log.e(TAG, "Exception while starting resolution activity", e);
    }
}


/**
 * Getter for the {@code GoogleApiClient}.
 */
public GoogleApiClient getGoogleApiClient() {
    return mGoogleApiClient;
}

@Override
public void onConnected(Bundle connectionHint) {
    IntentSender intentSender = Drive.DriveApi
            .newOpenFileActivityBuilder()
            .setMimeType(new String[]{"application/msword", " application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.google-apps.document", "application/pdf"})
            .build(getGoogleApiClient());
    AccountManager manager = (AccountManager) getSystemService(ACCOUNT_SERVICE);
    Account[] list = manager.getAccountsByType("com.google");
    //Getting the first account because that is the primary account for that user
    accountName = list[0].name;
    try {
        startIntentSenderForResult(
                intentSender, REQUEST_CODE_OPENER, null, 0, 0, 0);
    } catch (IntentSender.SendIntentException e) {
        Log.w(TAG, "Unable to send intent", e);
    }
  }

 /**
 * Handles resolution callbacks.
 */
@Override
protected void onActivityResult(int requestCode, int resultCode,
                                Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
        switch (requestCode) {
            case REQUEST_CODE_OPENER:
                Intent intent = null;
                if (resultCode == RESULT_OK) {
                    DriveId driveId = data.getParcelableExtra(
                            OpenFileActivityBuilder.EXTRA_RESPONSE_DRIVE_ID);
                    String resourceId = driveId.getResourceId();
                    DriveFile file = driveId.asDriveFile();
                }
                break;
            case REQUEST_CODE_RESOLUTION:
                mGoogleApiClient.connect();
                break;
            default:
                super.onActivityResult(requestCode, resultCode, data);
        }
     }
  }
}

有人可以帮我以编程方式从谷歌驱动器下载选定的文件吗?

提前致谢。

android google-drive-android-api android-googleapiclient
2个回答
0
投票

您可以通过两种方式下载它,通过REST或使用GDAA。您可以使用其中任何一种,具体取决于您舒适编码的位置。

使用 REST 时:

/*************************************************************************
   * 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;
  }

使用 GDAA 时:

/************************************************************************************************
   * get file contents
   * @param id file driveId
   * @return file's content  / null on fail
   */
  static byte[] read(String id) {
    byte[] buf = null;
    if (mGAC != null && mGAC.isConnected() && id != null) try {
      DriveFile df = Drive.DriveApi.getFile(mGAC, DriveId.decodeFromString(id));
      DriveContentsResult rslt = df.open(mGAC, DriveFile.MODE_READ_ONLY, null).await();
      if ((rslt != null) && rslt.getStatus().isSuccess()) {
        DriveContents cont = rslt.getDriveContents();
        buf = UT.is2Bytes(cont.getInputStream());
        cont.discard(mGAC);    // or cont.commit();  they are equiv if READONLY
      }
    } catch (Exception e) { UT.le(e); }
    return buf;
  }

查看此 SO 帖子以了解 GDAA 中 Drive Rest 的差异化

1 GDAA 的主要标识符 DriveId 仅存在于 GDAA (GooPlaySvcs) 中,不存在于 REST Api 中。您必须检索“ResourceId”,它是 REST Api 中的主要标识符(请参阅 SO 29030110)。

2 只有在 GDAA 提交(上传)文件/文件夹后才能从 DriveId 获取 ResourceId(参见 SO 22874657)

3 由于 GDAA 按其自己的时间表(系统优化)“缓冲”网络请求,您会遇到很多时间问题,而 REST Api 让您的应用程序控制等待响应。一般来说,如果你浏览这些 SO 问题,你会发现很多关于这些问题的讨论(虽然很乱)。

希望这有帮助。


0
投票

只需传递上传文件的驱动器 ID 和下载时要提供的文件名

public void DownloadFile(final DriveId driveId, final File filename, final GoogleApiClient mGoogleApiClient) {

    if (!filename.exists()) {
        try {
            filename.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    final DriveFile file = Drive.DriveApi.getFile(mGoogleApiClient, driveId);
    file.getMetadata(mGoogleApiClient).setResultCallback(metadataRetrievedCallback);

    DriveFolder folder = Drive.DriveApi.getFolder(mGoogleApiClient, driveId);
    folder.getMetadata(mGoogleApiClient).setResultCallback(metadataRetrievedCallback1);

    new Thread(new Runnable()
    {

        @Override
        public void run()
        {
            DriveApi.DriveContentsResult driveContentsResult = file.open(mGoogleApiClient,DriveFile.MODE_READ_ONLY, null).await();
            DriveContents driveContents = driveContentsResult.getDriveContents();
            InputStream inputstream = driveContents.getInputStream();

            try
            {
                FileOutputStream fileOutput = new FileOutputStream(filename);

                byte[] buffer = new byte[1024];
                int bufferLength = 0;
                while ((bufferLength = inputstream.read(buffer)) > 0)
                {
                    fileOutput.write(buffer, 0, bufferLength);
                }
                fileOutput.close();
                inputstream.close();

            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();
}
© www.soinside.com 2019 - 2024. All rights reserved.