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

时间:2017-04-02 14:30:12

标签: android google-drive-android-api android-googleapiclient

我在我的应用程序中使用Google Drive API ,我可以从谷歌驱动器中选择(在我的案例中为.doc / docx / .pdf)文件,直到现在一切都很好。但我想下载所选文件,需要使用Multipart将该文件发送到我们的服务器。我尝试了多种方式,我收到了DriveIdDriveFile,但遗憾的是我无法下载下载所选文件。

我已经完成了Android developer documentation

我正在使用以下代码

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);
        }
     }
  }
}

有人可以帮助我以编程方式从谷歌硬盘下载所选文件吗?

提前致谢。

2 个答案:

答案 0 :(得分:0)

有两种方法可以通过RESTGDAA下载。您可以根据您编码的位置轻松使用。

使用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;
  }

检查此differentiation of Drive Rest in GDAA

的帖子
  

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

     

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

     

3由于GDAA根据自己的时间表(系统优化)“缓冲”网络请求,因此REST Api让您的应用程序控制等待响应,因此会遇到很多时间问题。一般来说,如果你扫描这些问题,你会发现很多关于这些问题的喋喋不休(虽然这很麻烦)。

希望这有帮助。

答案 1 :(得分:0)

下载时要传递的上传文件和文件名的DriveID

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();
}