Android Open and Save files to / from Google Drive SDK
나는 지난 6 시간 동안 구글의 문서를 넘겨 왔지만 어떻게 시작해야할지 모르겠다. 내가 원하는 것은 기존 Android 앱이 Google 드라이브에서 파일을 읽고 Google 드라이브에 새 파일을 업로드하고 Google 드라이브의 기존 파일을 편집 할 수 있도록 만드는 것입니다.
Drive SDK v2는 Android (및 일반적으로 모바일) 개발자가 쉽게 사용할 수 있도록하는 데에만 초점을 맞추고 있지만 문서에는 거의 아무것도없는 것 같습니다.
이상적으로는 누군가가이 작업을 수행하는 방법을 다루는 괜찮은 문서, 예제 또는 자습서를 지적 해 주었으면합니다 (Android를 사용하고 있다는 점을 명심하십시오. Google App Engine과 함께 드라이브를 사용하는 방법에 대한 많은 자료가 있습니다. 이미 살펴 봤고 Android 앱으로 이동하는 방법을 모르겠습니다.)
프로젝트에 다운로드하여 추가해야하는 라이브러리, 매니페스트에 추가해야하는 라이브러리, 궁극적으로 Google 드라이브에서 파일 목록을 가져 와서 다운로드 한 다음 수정 된 버전을 업로드하는 방법을 알아야합니다.
이상적으로는 공식적으로 Google 드라이브 앱이 수행하는 방식으로 계정을 자동으로 처리하고 싶습니다.
편집 : Claudio Cherubino는 이제 Google Play 서비스를 사용할 수 있으며이 프로세스를 훨씬 쉽게 만들 것이라고 말합니다. 그러나 사용할 수있는 샘플 코드가 없습니다 (그러나 곧 출시 될 예정이라고합니다 ... 그들은 Google Play 서비스가 4 개월 전에 "곧 출시 될 예정"이라고 말했습니다. 따라서이 답변이 계속해서 액세스에 대한 유일한 완전 작동 예제가 될 가능성이 높습니다.) Android 애플리케이션에서 2013으로 Google 드라이브.)
2X 편집 : Google이 내년까지 작동하는 예제가 없을 것이라고 말했을 때 약 한 달이 지난 것 같습니다. Google의 공식 가이드는 여기에 있습니다.
https://developers.google.com/drive/quickstart-android
아직 방법을 테스트하지 않았으므로 2012 년 9 월 (아래)의 솔루션이 여전히 최고 일 수 있습니다.
이를 위해 Google Play 서비스가 필요하지 않습니다. 엉덩이가 아파서 50 시간 이상 (편집 : 100 시간 이상) 모든 것을 알아 내는데 보냈지 만 여기에 도움이 될 많은 것들이 있습니다.
도서관
일반적으로 Google의 온라인 서비스의 경우 프로젝트에 다음 라이브러리가 필요합니다. ( 지침 및 다운로드 링크 )
- google-api-client-1.11.0-beta.jar
- google-api-client-android-1.11.0-beta.jar
- google-http-client-1.11.0-beta.jar
- google-http-client-android-1.11.0-beta.jar
- google-http-client-jackson-1.11.0-beta.jar
- google-oauth-client-1.11.0-beta.jar
- 구아바 -11.0.1.jar
- jackson-core-asl-1.9.9.jar
- jsr305-1.3.9.jar
특히 Google 드라이브의 경우 다음이 필요합니다.
- google-api-services-drive-v2-rev9-1.8.0-beta.jar ( 다운로드 링크 )
콘솔 설정
다음으로 Google 콘솔 로 이동합니다 . 새 프로젝트를 만드십시오. 서비스에서 DRIVE API 와 DRIVE SDK의 두 가지를 켜야합니다 ! 그들은 분리되어 있고, 하나는 자동으로 다른 하나를 켜지 않으며, 둘 다 켜야합니다 ! (이것을 알아내는 데 혼자서 적어도 20 시간을 낭비했습니다.)
콘솔에서 API 액세스로 이동합니다. 클라이언트를 만들고 Android 앱으로 만듭니다. 번들 ID를 제공하십시오. 나는 잘못된 것을 사용했다고 확신하기 때문에 지문이 실제로 중요하다고 생각하지 않지만 어쨌든 올바른 방법을 시도하십시오 (Google에서 지침을 제공합니다).
클라이언트 ID를 생성합니다 . 당신은 그것을 필요로 할 것입니다. 잡아.
편집 : 실수로 Drive API 만 켜면되고 Drive SDK는 전혀 켜지 않아도되며 설정이 아닌 단순 API 키만 사용하면된다고 들었습니다. Android 용으로 나는 지금 그것을 조사하고 있으며 내가 그것을 알아 낸다면 몇 분 안에이 답변을 편집 할 것입니다 ...
ANDROID 코드-설정 및 업로드
먼저 인증 토큰을받습니다.
AccountManager am = AccountManager.get(activity);
am.getAuthToken(am.getAccounts())[0],
"oauth2:" + DriveScopes.DRIVE,
new Bundle(),
true,
new OnTokenAcquired(),
null);
다음으로 OnTokenAcquired ()를 다음과 같이 설정해야합니다.
private class OnTokenAcquired implements AccountManagerCallback<Bundle> {
@Override
public void run(AccountManagerFuture<Bundle> result) {
try {
final String token = result.getResult().getString(AccountManager.KEY_AUTHTOKEN);
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
Drive.Builder b = new Drive.Builder(httpTransport, jsonFactory, null);
b.setJsonHttpRequestInitializer(new JsonHttpRequestInitializer() {
@Override
public void initialize(JSonHttpRequest request) throws IOException {
DriveRequest driveRequest = (DriveRequest) request;
driveRequest.setPrettyPrint(true);
driveRequest.setKey(CLIENT ID YOU GOT WHEN SETTING UP THE CONSOLE BEFORE YOU STARTED CODING)
driveRequest.setOauthToken(token);
}
});
final Drive drive = b.build();
final com.google.api.services.drive.model.File body = new com.google.api.services.drive.model.File();
body.setTitle("My Test File");
body.setDescription("A Test File");
body.setMimeType("text/plain");
final FileContent mediaContent = new FileContent("text/plain", an ordinary java.io.File you'd like to upload. Make it using a FileWriter or something, that's really outside the scope of this answer.)
new Thread(new Runnable() {
public void run() {
try {
com.google.api.services.drive.model.File file = drive.files().insert(body, mediaContent).execute();
alreadyTriedAgain = false; // Global boolean to make sure you don't repeatedly try too many times when the server is down or your code is faulty... they'll block requests until the next day if you make 10 bad requests, I found.
} catch (IOException e) {
if (!alreadyTriedAgain) {
alreadyTriedAgain = true;
AccountManager am = AccountManager.get(activity);
am.invalidateAuthToken(am.getAccounts()[0].type, null); // Requires the permissions MANAGE_ACCOUNTS & USE_CREDENTIALS in the Manifest
am.getAuthToken (same as before...)
} else {
// Give up. Crash or log an error or whatever you want.
}
}
}
}).start();
Intent launch = (Intent)result.getResult().get(AccountManager.KEY_INTENT);
if (launch != null) {
startActivityForResult(launch, 3025);
return; // Not sure why... I wrote it here for some reason. Might not actually be necessary.
}
} catch (OperationCanceledException e) {
// Handle it...
} catch (AuthenticatorException e) {
// Handle it...
} catch (IOException e) {
// Handle it...
}
}
}
THE ANDROID CODE - Downloading
private java.io.File downloadGFileToJFolder(Drive drive, String token, File gFile, java.io.File jFolder) throws IOException {
if (gFile.getDownloadUrl() != null && gFile.getDownloadUrl().length() > 0 ) {
if (jFolder == null) {
jFolder = Environment.getExternalStorageDirectory();
jFolder.mkdirs();
}
try {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(gFile.getDownloadUrl());
get.setHeader("Authorization", "Bearer " + token);
HttpResponse response = client.execute(get);
InputStream inputStream = response.getEntity().getContent();
jFolder.mkdirs();
java.io.File jFile = new java.io.File(jFolder.getAbsolutePath() + "/" + getGFileName(gFile)); // getGFileName() is my own method... it just grabs originalFilename if it exists or title if it doesn't.
FileOutputStream fileStream = new FileOutputStream(jFile);
byte buffer[] = new byte[1024];
int length;
while ((length=inputStream.read(buffer))>0) {
fileStream.write(buffer, 0, length);
}
fileStream.close();
inputStream.close();
return jFile;
} catch (IOException e) {
// Handle IOExceptions here...
return null;
}
} else {
// Handle the case where the file on Google Drive has no length here.
return null;
}
}
One last thing... if that intent gets sent off, you'll need to handle when it returns with a result.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 3025) {
switch (resultCode) {
case RESULT_OK:
AccountManager am = AccountManager.get(activity);
am.getAuthToken(Same as the other two times... it should work this time though, because now the user is actually logged in.)
break;
case RESULT_CANCELED:
// This probably means the user refused to log in. Explain to them why they need to log in.
break;
default:
// This isn't expected... maybe just log whatever code was returned.
break;
}
} else {
// Your application has other intents that it fires off besides the one for Drive's log in if it ever reaches this spot. Handle it here however you'd like.
}
}
THE ANDROID CODE - Updating
Two quick notes on updating the last modified date of a file on Google Drive:
- You must provide a fully initialized DateTime. If you do not, you'll get a response of "Bad Request" from Google Drive.
- You must use both setModifiedDate() on the File from Google Drive and setSetModifiedDate(true) on the update request itself. (Fun name, huh? "setSet[...]", there's no way people could mistype that one...)
Here's some brief sample code showing how to do an update, including updating the file time:
public void updateGFileFromJFile(Drive drive, File gFile, java.io.File jFile) throws IOException {
FileContent gContent = new FileContent("text/csv", jFile);
gFile.setModifiedDate(new DateTime(false, jFile.lastModified(), 0));
gFile = drive.files().update(gFile.getId(), gFile, gContent).setSetModifiedDate(true).execute();
}
THE MANIFEST
You'll need the following permissions: GET_ACCOUNTS, USE_CREDENTIALS, MANAGE_ACCOUNTS, INTERNET, and there's a good chance you'll need WRITE_EXTERNAL_STORAGE as well, depending on where you'd like to store the local copies of your files.
YOUR BUILD TARGET
Right click your project, go into it's properties, and under Android change the build target to Google APIs if you must. If they aren't there, download them from the android download manager.
If you're testing on an emulator, make sure its target is Google APIs, not generic Android.
You'll need a Google Account set up on your test device. The code as written will automatically use the first Google Account it finds (that's what the [0] is.) IDK if you need to have downloaded the Google Drive app for this to have worked. I was using API Level 15, I don't know how far back this code will work.
THE REST
The above should get you started and hopefully you can figure your way out from there... honestly, this is just about as far as I've gotten so far. I hope this helps A LOT of people and saves them A LOT of time. I'm fairly certain I've just written the most comprehensive set up guide to setting up an Android app to use Google Drive. Shame on Google for spreading the necessary material across at least 6 different pages that don't link to each other at all.
Check this video from Google I/O to learn how to integrate your Android app with Drive:
http://www.youtube.com/watch?v=xRGyzqD-vRg
Please be aware that what you see in the video is based on Google Play Services
, which hasn't launched to the general public yet
:
https://developers.google.com/android/google-play-services/
It's 2015, things have changed!
Get the 'Drive API for Android' with gradle:
compile 'com.google.android.gms:play-services-drive:7.8.0'
There's some new doco (although still lackluster IMO):
https://developers.google.com/drive/web/quickstart/android
And for those about to go caving...the biggest problem I encountered thus far is that there is absolutely no way of distinguishing folders that have been permanently deleted from folders that are normal...you can find them, you can create folders and files within them, only writing to the file DriveContents will always fail.
Take a look at Google's DrEdit Example, which has a folder called android/
. Copy it, follow the readme
, and it should work (works for me on an Android emulator with KitKat).
.
P.S.
Sorry for reviving this, but the new Google Drive Android API doesn't support full Drive access, only drive.file
and drive.appdata
authorization scopes, so if you need full access you have to go back to the good 'ol Google API's Client for Java (which the DrEdit example uses).
ReferenceURL : https://stackoverflow.com/questions/12164024/android-open-and-save-files-to-from-google-drive-sdk
'developer tip' 카테고리의 다른 글
C ++에서 typename T를 문자열로 변환하는 방법 (0) | 2020.12.25 |
---|---|
드라이버 실행 파일은 webdriver.ie.driver 시스템 속성으로 설정해야합니다. (0) | 2020.12.25 |
특정 virtualenv에 설치된 패키지 목록을 어떻게 만들 수 있습니까? (0) | 2020.12.25 |
Django Rest Framework : 개체 생성 후 필드 업데이트 비활성화 (0) | 2020.12.25 |
느린 요청이있을 때 Android Volley 이중 게시 (0) | 2020.12.25 |