在Android中从Google云端硬盘下载文件

时间:2013-12-30 06:49:52

标签: android google-drive-api

我正在开发一个应用程序,用于从G Drive上传,显示和下载文件。不幸的是,下载时我得到了   com.google.api.client.http.HttpResponseException:401未经授权。

请帮我解决这个问题。

我在这里指定

credential = GoogleAccountCredential.usingOAuth2(this,DriveScopes.DRIVE);

service=new Drive.Builder(AndroidHttp.newCompatibleTransport(),new GsonFactory(),credential).build();

我的代码是:

package com.example.googledrive;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import com.google.api.client.http.FileContent;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.Drive.Children;
import com.google.api.services.drive.Drive.Files;
import com.google.api.services.drive.Drive.Files.Get;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.ChildList;
import com.google.api.services.drive.model.ChildReference;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;

import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.StrictMode;
import android.provider.MediaStore;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends Activity {

    static final int REQUEST_ACCOUNT_PICKER = 1;
    static final int REQUEST_AUTHORIZATION = 2;
    static final int CAPTURE_IMAGE = 3;

    private static Uri fileUri;
    private static Drive service;
    private ProgressDialog progressDialog;
    private GoogleAccountCredential credential;

    String fileId;
    String fileName;
    String downloadUrl;
    ListView listView;
    Activity activity;
    String sdCardPadth;
    List<File> allFileList;
    ArrayList<String> fileType;
    ArrayList<String> mainTitleList;
    ArrayList<String> fileIdList;
    ArrayList<String> alternateUrlList;
    ArrayList<Integer> fileSizeList;
    FileTitlesAdapter myAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = (ListView) findViewById(R.id.uploadedFilesList);
        allFileList = new ArrayList<File>();
        mainTitleList = new ArrayList<String>();
        alternateUrlList = new ArrayList<String>();
        fileSizeList = new ArrayList<Integer>();
        fileType = new ArrayList<String>();
        fileIdList=new ArrayList<String>();
        progressDialog=new ProgressDialog(getApplicationContext());
        progressDialog.setTitle("Please Wait....");
        progressDialog.setCancelable(false);
        activity = this;

        credential = GoogleAccountCredential.usingOAuth2(this,DriveScopes.DRIVE);
        startActivityForResult(credential.newChooseAccountIntent(),REQUEST_ACCOUNT_PICKER);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> arg0, View view, final int arg2,long arg3) {
                // String str=itemArray.get(arg2).toString().trim();
                System.out.println("mainTitleList size==="+mainTitleList.size());
                System.out.println("arg2==="+arg2);
                fileName = (String)mainTitleList.get(arg2);             
                mainTitleList.clear();              
                //fileSizeList.clear();
                final String fileTypeStr=fileType.get(arg2);
                fileType.clear();
                if(fileTypeStr.contains("application/vnd.google-apps.folder"))
                {
                    Thread t = new Thread(new Runnable() {
                        @Override
                        public void run() {
                    boolean b=true;
                    try {                       
                        String dirUrl=alternateUrlList.get(arg2);                       
                        alternateUrlList.clear();
                        System.out.println("Folder Name Is:"+fileName);
                        System.out.println("Folder Type Is:"+fileTypeStr);
                        System.out.println("Folder URL Is:"+dirUrl);
                        String fileId=fileIdList.get(arg2);
                        System.out.println("Folder Id Is:"+fileId);                     
                        //retrieveAllFilesFromDir(service, fileId, b);                      
                        //retrieveAllFiles1(service, b, fileId);
                        //Files.List request = service.children().get(fileId, null);
                        Files.List request = service.files().list().setQ("'" + fileId + "' in parents ");
                        retrieveAllFiles(service,request,b);                        
                        //retrieveAllFiles(service, b);
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        System.out.println("Exception In retrieveAllFiles Dir Is:"+e);
                        e.printStackTrace();
                    }
                        }
                        });t.start();       
                }
                else
                {       

                try {
                    System.out.println("fileSizeList size===="+fileSizeList.size());
                    System.out.println("arg2===="+arg2);                    
                    Integer fileSize = (int) fileSizeList.get(arg2);
                    downloadUrl = alternateUrlList.get(arg2);
                    byte[] size = new byte[fileSize];
                    int byteRead = 0, byteWritten = 0;
                    sdCardPadth = Environment.getExternalStorageDirectory().getPath();


                    System.out.println("Download Url==="+downloadUrl);

                    new Thread(new Runnable() {

                        @Override
                        public void run() {
                            // TODO Auto-generated method stub
                            InputStream inStream=downloadFile(service, downloadUrl);

                            java.io.File inFile=new java.io.File(sdCardPadth+"/"+fileName+"1");
                            System.out.println("File Succesfully Stored");

                        }
                    }).start();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    System.out.println("Exception In get Integer Is:" + e);
                    e.printStackTrace();
                }
                }
            }
        });
    }

    @Override
    protected void onActivityResult(final int requestCode,
            final int resultCode, final Intent data) {      
        switch (requestCode) {
        case REQUEST_ACCOUNT_PICKER:            
            if (resultCode == RESULT_OK && data != null
                    && data.getExtras() != null) {
                String accountName = data
                        .getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
                if (accountName != null) {
                    credential.setSelectedAccountName(accountName);
                    service = getDriveService(credential);      
                    final boolean b=false;                  
                    Thread t=new Thread(new Runnable() {                        
                        @Override
                        public void run() {
                            try
                            {
                                Files.List request = service.files().list().setQ("hidden="+b);
                                    retrieveAllFiles(service,request,b);
                            } catch (Exception e) {
                                System.out.println("Exception Is:"+e);
                                e.printStackTrace();
                            }

                        }
                    }) ;t.start();

                }
            }
            break;
        case REQUEST_AUTHORIZATION:
            if (resultCode == Activity.RESULT_OK) {
                System.out.println("REQUEST_AUTHORIZATION case Is:"
                        + REQUEST_AUTHORIZATION);
                saveFileToDrive();
            } else {
                startActivityForResult(credential.newChooseAccountIntent(),
                        REQUEST_ACCOUNT_PICKER);
            }
            break;
        case CAPTURE_IMAGE:
            if (resultCode == Activity.RESULT_OK) {
                System.out.println("CAPTURE_IMAGE case Is:" + CAPTURE_IMAGE);
                saveFileToDrive();
            }
        }
    }
    private void saveFileToDrive() {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // File's binary content
                    System.out.println("run method");
                    java.io.File fileContent = new java.io.File(fileUri.getPath());
                    FileContent mediaContent = new FileContent("image/jpeg",fileContent);
                    // File's metadata.
                    File body = new File();
                    body.setTitle(fileContent.getName());
                    body.setMimeType("image/jpeg");
                    File file=null;
                    try {

                        file = service.files().insert(body, mediaContent).execute();
                    } catch (Exception e) {

                        System.out.println("Exception In Insert File Is"+e);
                        e.printStackTrace();
                    }
                    if (file != null) {
                        showToast("Photo uploaded: " + file.getTitle());
                        System.out.println("photo sucessfullly uploaded:"+ fileId);boolean b=false;
Files.List request = service.files().list().setQ("hidden="+b);
                        retrieveAllFiles(service,request,b);                        
                    }
                } catch (UserRecoverableAuthIOException e) {
                    startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();
    }
    private Drive getDriveService(GoogleAccountCredential credential) {
        return new Drive.Builder(AndroidHttp.newCompatibleTransport(),
                new GsonFactory(), credential).build();
    }

    public void showToast(final String toast) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getApplicationContext(), toast,Toast.LENGTH_SHORT).show();
            }
        });
    }

    private List<File> retrieveAllFiles(Drive service,Files.List request,boolean b) throws IOException {
        List<File> result = new ArrayList<File>();
        final ArrayList<String> titleList = new ArrayList<String>();
        String fileUrl = "";
        do {
            try {
                FileList files = request.execute();
                result.addAll(files.getItems());
                request.setPageToken(files.getNextPageToken());
                for (int i = 0; i < result.size(); i++) {
                    File tempFile = result.get(i);
                    String fileTypeStr = tempFile.getMimeType();                
                    String fileName = tempFile.getTitle();
                    titleList.add(fileName);    
                    fileId = tempFile.getId();
                    fileIdList.add(fileId);                 
                    fileUrl = tempFile.getAlternateLink();
                    System.out.println("<><>< fileUrl Is:" + fileUrl);
                    alternateUrlList.add(fileUrl);

                    fileType.add(fileTypeStr);
                    mainTitleList.add(fileName);                    

                    try {
                        Integer fileSize =tempFile.getFileSize()==null?100:(int) (long) tempFile.getFileSize();
                        fileSizeList.add(fileSize);
                        System.out.println("<><>< fileSize Is:" + fileSize);
                    } catch (Exception e) {

                        fileSizeList.add(2000);
                        e.printStackTrace();
                    }


                }



                try {
                    runOnUiThread(new Runnable() {
                        public void run() {

                            myAdapter = new FileTitlesAdapter(activity,
                                    fileType, mainTitleList, alternateUrlList,
                                    fileSizeList);
                            listView.setAdapter(myAdapter);
                        }
                    });

                } catch (Exception e) {


                    System.out.println("Exception Setting ListView Is:" + e);
                    e.printStackTrace();
                }
            } catch (IOException e) {
                System.out.println("An error occurred in retrieveAllFiles:"+ e);
                request.setPageToken(null);
            }
        } while (request.getPageToken() != null
                && request.getPageToken().length() > 0);
        return result;
    }


     private static InputStream downloadFile(Drive service, String url) {
         System.out.println("downloadFile is called service=="+service);
            if (url != null && url.length() > 0) {
              try {
                  System.out.println("downloadFile is called try");
                HttpResponse resp =service.getRequestFactory().buildGetRequest(new GenericUrl(url)).execute();
                System.out.println("resp.getContent()===="+resp.getContent());
                return resp.getContent();
              } catch (Exception e) {
                System.out.println("Exception Is:"+e);
                e.printStackTrace();
                return null;
              }
            } else {
                 System.out.println("No Exception No Output");
              return null;
            }
          }


}

2 个答案:

答案 0 :(得分:6)

这是我用来从Google云端硬盘下载文件的代码

   new AsyncTask<Void, Integer, Boolean>() {

        @Override
        protected Boolean doInBackground(Void... params) {
        try {
            File file = service.files().get("path in drive").execute();
            java.io.File toFile = new java.io.File("where you want to store");
            toFile.createNewFile();
            HttpDownloadManager downloader = new HttpDownloadManager(file, toFile);
            downloader.setListener(new HttpDownloadManager.FileDownloadProgressListener() {

                public void downloadProgress(long bytesRead, long totalBytes) {
                    Log.i("chauster",totalBytes);
                    Log.i("chauster",bytesRead);
                }

                @Override
                public void downloadFinished() {
                    // TODO Auto-generated method stub
                }

                @Override
                public void downloadFailedWithError(Exception e) {
                    // TODO Auto-generated method stub  
                }                       
            });
            return downloader.download(service);
        } catch (IOException e) {
            e.printStackTrace();
        }
            return false;
        }
        protected void onPostExecute(Boolean result) {
        };
    }.execute();

HttpDownloadManager.java

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpResponse;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.model.File;
import com.grandex.ShareInfomation.ShareData;
import com.grandex.ShareInfomation.ShareData.ToolTapState;

public class HttpDownloadManager {
    private String donwloadUrl;
    private String toFile;
    private FileDownloadProgressListener listener;
    private long totalBytes;

    public void setListener(FileDownloadProgressListener listener) {
        this.listener = listener;
    } 

    public HttpDownloadManager(File sourceFile, java.io.File destinationFile) {
        super(); 
        this.donwloadUrl = sourceFile.getDownloadUrl();
        this.toFile = destinationFile.toString();
        this.totalBytes = sourceFile.getFileSize();
    } 

    public static interface FileDownloadProgressListener {
        public void downloadProgress(long bytesRead, long totalBytes);

        public void downloadFinished();

        public void downloadFailedWithError(Exception e);
    }

    public boolean download(Drive service) {
        HttpResponse respEntity = null;
        try {
            // URL url = new URL(urlString);
            respEntity = service.getRequestFactory()
                    .buildGetRequest(new GenericUrl(donwloadUrl)).execute();
            InputStream in = respEntity.getContent();
            if(totalBytes == 0) {
                totalBytes = respEntity.getContentLoggingLimit();
            } 
            try { 
                FileOutputStream f = new FileOutputStream(toFile) {

                    @Override
                    public void write(byte[] buffer, int byteOffset,
                            int byteCount) throws IOException {
                        // TODO Auto-generated method stub
                        super.write(buffer, byteOffset, byteCount);
                        }
                    }
                };
                byte[] buffer = new byte[1024];
                int len1 = 0;
                long bytesRead = 0;
                while ((len1 = in.read(buffer)) > 0) {
                    f.write(buffer, 0, len1);
                    if (listener != null) {
                        bytesRead += len1;
                        listener.downloadProgress(bytesRead, totalBytes);
                    }
                }
                f.close();
            } catch (Exception e) {
                if (listener != null) {
                    listener.downloadFailedWithError(e);
                }
                return false;
            }
            if (listener != null) {
                listener.downloadFinished();
            }
            return true;

        } catch (IOException ex) {
            if (listener != null) {
                listener.downloadFailedWithError(ex);
                return false;
            }
        } finally {
            if(respEntity != null) {
                try {
                    respEntity.disconnect();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        return false;
    }
}

答案 1 :(得分:1)

您的代码中没有任何地方设置授权标头。

你需要像

这样的东西
setRequestProperty("Authorization", "OAuth " + "***ACCESS_TOKEN***");

对于任何401/403错误,非常值得让您的请求在Oauth上运行。试试这个