我正在开发一个应用程序,用于从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;
}
}
}
答案 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上运行。试试这个