Android otwieranie i zapisywanie plików do / z Dysku Google SDK

Spędziłem ostatnie sześć godzin wylewając dokumenty z Google i nadal Nie wiem, jak zacząć z tym. Wszystko, co chcę zrobić, to sprawić, aby moja istniejąca aplikacja na Androida mogła odczytywać pliki z Dysku Google, przesyłać nowe pliki na Dysk Google i edytować istniejące pliki na Dysku Google.

Czytałem, że Drive SDK v2 koncentruje się wyłącznie na ułatwieniu deweloperom Androida (i ogólnie urządzeń mobilnych) korzystania z niego, a jednak wydaje się, że praktycznie nic w ich dokumentacja na ten temat.

Najlepiej, chciałbym, aby ktoś wskazał jakąś przyzwoitą dokumentację, przykład lub tutorial opisujący jak to zrobić (Pamiętaj, że używam Androida. Mają mnóstwo rzeczy na temat korzystania z dysku z Google App Engine; już patrzyłem na to i nie mam pojęcia, jak przejść z tego do aplikacji na Androida.)

Muszę wiedzieć, które biblioteki muszę pobrać i dodać do mojego projektu, co muszę dodać do manifestu i jak ostatecznie uzyskać listę pliki z Dysku Google, pobrać jeden, a następnie przesłać zmodyfikowaną wersję.

Najlepiej, aby obsługiwał konta automatycznie, tak jak robi to oficjalna aplikacja Google Drive.

Author: ArtOfWarfare, 2012-08-28

4 answers

Edit: Claudio Cherubino mówi, że usługi Google Play są już dostępne i ułatwi ten proces. Nie ma jednak dostępnego przykładowego kodu (jeszcze mówi, że wkrótce się pojawi... powiedzieli, że usługi Google Play były" coming soon " 4 miesiące temu, więc istnieje duża szansa, że ta odpowiedź będzie nadal jedynym całkowicie działającym przykładem dostępu do Dysku Google z aplikacji na Androida w 2013 roku.)

Edit 2x: wygląda na to, że byłem wyłączony o około miesiąc, gdy powiedziałem Google dopiero w przyszłym roku. Oficjalny przewodnik od Google jest tutaj:

Https://developers.google.com/drive/quickstart-android

Nie testowałem jeszcze ich metod, więc możliwe, że moje rozwiązania z września 2012 (poniżej) są nadal najlepsze: {]}

Usługi Google Play nie są do tego wymagane. To wrzód na tyłku, a ja spędziłem ponad 50 godzin (edit: 100+ godzin) zastanawiając się nad tym wszystkim, ale tutaj jest wiele rzeczy, które pomogą wiedzieć:

BIBLIOTEKI

Dla usług internetowych Google w ogóle będziesz potrzebował tych bibliotek w swoim projekcie: (instrukcje i pobierz Link )

  • 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-1.11.0-beta.jar
  • google-OAuth-client-1.11.0-beta.jar
  • guawa-11.0.1.jar
  • Jackson-core-asl-1.9.9.jar
  • jsr305-1.3.9.jar

W szczególności dla Dysku Google będziesz również potrzebować to:

KONFIGURACJA KONSOLI

Następnie przejdź do konsoli Google. Zrób nowy projekt. W sekcji Usługi musisz włączyć dwie rzeczy: DRIVE API i DRIVE SDK! Są one oddzielne, jeden nie włącza automatycznie drugiego i musisz włączyć oba! (wymyślając to zmarnowałem co najmniej 20 godzin mojego czasu sam.)

Nadal na konsoli, przejdź do API Access. Stwórz klienta, zrób z niego aplikację na Androida. Podaj swój identyfikator pakietu. Nie sądzę, że odciski palców jest rzeczywiście ważne, ponieważ jestem prawie pewien, że użyłem niewłaściwego, ale staraj się to zrobić tak czy inaczej (Google zapewnia instrukcje dla niego.)

Wygeneruje identyfikator klienta. Będziesz tego potrzebował. Trzymaj się.

Edit: powiedziano mi, że się mylę i że wystarczy włączyć Drive API, Drive SDK nie trzeba w ogóle włączać i że wystarczy użyć prostego klucza API, a nie skonfigurować coś dla Androida. Przyglądam się temu teraz i prawdopodobnie edytuję tę odpowiedź w ciągu kilku minut, jeśli to rozgryzę...

Kod Androida-Konfiguracja i przesyłanie

Najpierw uzyskaj Token auth:

AccountManager am = AccountManager.get(activity);
am.getAuthToken(am.getAccounts())[0],
    "oauth2:" + DriveScopes.DRIVE,
    new Bundle(),
    true,
    new OnTokenAcquired(),
    null);

Następnie OnTokenAcquired () musi być ustawione tak:

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...
        }
    }
}

ANDROID CODE-pobieranie

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 rzecz... jeśli ta intencja zostanie odrzucona, będziesz musiał poradzić sobie, gdy powróci z wynikiem.

@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.
    }
}

Kod Androida-Aktualizacja

Dwie szybkie uwagi na temat aktualizacji daty ostatniej modyfikacji pliku na Dysku Google:

  1. musisz podać w pełni zainicjalizowaną DateTime. Jeśli tego nie zrobisz, otrzymasz odpowiedź "złe żądanie" z Dysku Google.
  2. musisz użyć zarówno setModifiedDate () na pliku z Dysku Google, jak i setSetModifiedDate (true) podczas aktualizacji sama Prośba. Fajna nazwa, co? "setSet[...] ", nie ma mowy, żeby ludzie pomylili ten jeden...)

Oto krótki przykładowy kod pokazujący, jak wykonać aktualizację, w tym zaktualizować czas Pliku:

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

MANIFEST

Będziesz potrzebował następujących uprawnień: GET_ACCOUNTS, USE_CREDENTIALS, MANAGE_ACCOUNTS, INTERNET, i jest duża szansa, że będziesz potrzebował również WRITE_EXTERNAL_STORAGE, w zależności od tego, gdzie chcesz przechowywać lokalne kopie Twojego konta pliki.

TWÓJ CEL BUDOWY

Kliknij prawym przyciskiem myszy swój projekt, przejdź do jego właściwości i pod Androidem Zmień cel kompilacji na Google API, jeśli musisz. Jeśli ich tam nie ma, pobierz je z menedżera pobierania Androida.

Jeśli testujesz emulator, upewnij się, że jego celem jest Google API, a nie ogólny Android.

Będziesz potrzebował konta Google skonfigurowanego na urządzeniu testowym. Zapisany kod automatycznie użyje pierwszego konta Google, które znajdzie (tym właśnie jest [0].) IDK, jeśli musisz pobrać aplikację Dysk Google, aby to zadziałało. Używałem API Level 15, Nie wiem jak daleko wstecz ten kod będzie działał.

RESZTA

Powyższe powinno cię zacząć i mam nadzieję, że uda ci się stamtąd wydostać... szczerze mówiąc, to tylko tyle, ile zaszedłem do tej pory. Mam nadzieję, że pomoże to wielu ludziom i zaoszczędzi im dużo czasu. Jestem pewien, że właśnie napisałem najbardziej wyczerpujący zestaw up przewodnik konfigurowania aplikacji na Androida do korzystania z Dysku Google. Wstydź się Google za rozpowszechnianie niezbędnych materiałów na co najmniej 6 różnych stronach, które nie łączą się ze sobą w ogóle.

 80
Author: ArtOfWarfare,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-29 23:22:39

Jest rok 2015, wiele się zmieniło!

Pobierz' Drive API dla Androida ' za pomocą gradle:
compile 'com.google.android.gms:play-services-drive:7.8.0'

Jest jakiś nowy doco (choć wciąż mało znany IMO):

Https://developers.google.com/drive/web/quickstart/android

I dla tych, którzy chcą się poddać...największym problemem, z jakim do tej pory się spotkałem, jest to, że nie ma absolutnie żadnego sposobu na odróżnienie folderów, które zostały trwale usunięte od folderów, które są normalne...możesz je znaleźć, ty może tworzyć foldery i pliki w nich, tylko zapis do pliku DriveContents zawsze się nie powiedzie.
 4
Author: straya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-18 01:36:33

Sprawdź ten film z Google I / O, aby dowiedzieć się, jak zintegrować aplikację na Androida z dyskiem:

Http://www.youtube.com/watch?v=xRGyzqD-vRg

Pamiętaj, że to, co widzisz w filmie, opiera się na usługach Google Play:

Https://developers.google.com/android/google-play-services/

 4
Author: Claudio Cherubino,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-28 21:08:55

Spójrz na przykład Google DrEdit , który ma folder o nazwie android/. Skopiuj go, postępuj zgodnie z readme, i powinno działać(działa dla mnie na emulatorze Androida z KitKat).

.

P. S.

Sorry za odświeżenie tego, ale nowy Google Drive Android API nie obsługuje pełnego dostępu do Dysku, tylko drive.file i drive.appdata zakresy autoryzacji , więc jeśli potrzebujesz pełnego dostępu, musisz wrócić do dobrego klienta API Google dla Java (którego używa przykład DrEdit).

 2
Author: woojoo666,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-07 04:29:04