Подтвердить что ты не робот

Android Открыть и сохранить файлы в/из Google Диска SDK

Я провел последние шесть часов, перелистывая документы из Google, и я до сих пор не знаю, как начать с этого. Все, что я хочу сделать, это сделать так, чтобы мое существующее приложение Android могло читать файлы с Google Диска, загружать новые файлы на Google Диск и редактировать существующие файлы на Google Диске.

Я читал, что Drive SDK v2 был сосредоточен исключительно на том, чтобы облегчить разработчикам Android (и мобильных в целом) его использование, и все же в их документации об этом практически ничего не говорится.

В идеале, я хотел бы, чтобы кто-то указал на какую-то приличную документацию, например, или учебное пособие, посвященное тому, как это сделать (имейте в виду, что я использую Android. У них много материала о том, как использовать Диск с Google App Engine, я уже посмотрел на него, и я понятия не имею, как перейти от него к Android-приложению.)

Мне нужно знать, какие библиотеки мне нужно загрузить и добавить в мой проект, что мне нужно добавить в мой манифест, и как я могу в конечном итоге получить список файлов с Google Диска, загрузить его, а затем загрузить измененный версия.

В идеале я бы хотел, чтобы он автоматически обрабатывал учетные записи, как это делает официальное приложение Google Диска.

4b9b3361

Ответ 1

Изменить: Клаудио Керубино говорит, что Google Play Services теперь доступна и сделает этот процесс намного проще. Тем не менее, нет образца кода (все же, он говорит, что это скоро... они сказали, что Google Play Services "скоро появится" 4 месяца назад, так что есть хороший шанс, что этот ответ будет оставаться единственным полностью рабочим примером доступа Google Диска из приложения Android в 2013 году.)

Edit 2X: Похоже, я был около месяца, когда сказал, что у Google не будет рабочего примера до следующего года. Официальное руководство от Google находится здесь:

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

Я еще не тестировал свои методы, поэтому возможно, что мои решения с сентября 2012 года (ниже) все же самые лучшие:

Службы Google Play НЕ НЕОБХОДИМО для этого. Это боль в прикладе, и я провел более 50 часов (отредактируйте: 100 часов), выясняя все это, но здесь много всего, что это поможет узнать:

БИБЛИОТЕКИ

Для онлайн-сервисов Google в целом вам понадобятся эти библиотеки в вашем проекте: (Инструкции и ссылка на скачивание)

  • Google-апи-клиент-1.11.0-beta.jar
  • Google-апи-клиент-андроид-1.11.0-beta.jar
  • Google-клиент-клиент-1.11.0-beta.jar
  • Google-HTTP-клиент-андроид-1.11.0-beta.jar
  • Google-клиент-клиент-ДЖЕКСОН-1.11.0-beta.jar
  • Google-OAuth-клиент-1.11.0-beta.jar
  • гуавы-11.0.1.jar
  • ДЖЕКСОНА-ядро-ASL-1.9.9.jar
  • jsr305-1.3.9.jar

Для Google Диска, в частности, вам также понадобится следующее:

НАСТРОЙКА КОНСОЛИ

Затем перейдите в Консоль Google. Сделайте новый проект. В разделе "Службы" вам нужно включить две вещи: DRIVE API и DRIVE SDK! Они отделены друг от друга, один не включается автоматически, а ВЫ ДОЛЖНЫ ОБРАТИТЬСЯ ОБОИХ! (рискуя потратить впустую как минимум 20 часов моего времени.)

Еще на консоли перейдите к API Access. Создайте клиент, сделайте его Android-приложение. Дайте ему свой идентификатор связки. Я не думаю, что отпечатки пальцев на самом деле важны, поскольку я уверен, что я использовал неправильный, но стараюсь получить это право в любом случае (Google предоставляет инструкции для него.)

Он будет генерировать идентификатор клиента. Тебе это понадобится. Держитесь за него.

Изменить: мне сказали, что я ошибаюсь, и что вам нужно всего лишь включить Drive API, Drive SDK вообще не нужно включать, и вам просто нужно использовать Simple API Key, не настроил что-то для 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 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 - Загрузка

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

Последнее: если это намерение будет отправлено, вам нужно будет обработать, когда он вернется с результатом.

@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 log in if it ever reaches this spot. Handle it here however you'd like.
    }
}

КОД ANDROID - Обновление

Две быстрые заметки об обновлении последней измененной даты файла на Google Диске:

  • Вы должны предоставить полностью инициализированное DateTime. Если вы этого не сделаете, вы получите ответ "Плохой запрос" с Google Диска.
  • Вы должны использовать как setModifiedDate() в Файле с Google Диска, так и setSetModifiedDate (true) в самом запросе на обновление. (Забавное имя, да? "SetSet [...]", там люди не могут ошибаться в этом...)

Вот несколько кратких примеров кода, показывающих, как выполнить обновление, включая обновление времени файла:

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

МАНИФЕСТ

Вам понадобятся следующие разрешения: GET_ACCOUNTS, USE_CREDENTIALS, MANAGE_ACCOUNTS, INTERNET, и есть хорошие шансы, что вам понадобится WRITE_EXTERNAL_STORAGE, в зависимости от того, где вы хотите хранить локальные копии ваших файлов.

ВАША СТРОИТЕЛЬНАЯ ЦЕЛЬ

Щелкните правой кнопкой мыши свой проект, перейдите в его свойства и под Android измените цель сборки на API Google, если нужно. Если их там нет, загрузите их из диспетчера загрузки Android.

Если вы тестируете эмулятор, убедитесь, что его целью является API Google, а не общий Android.

Вам понадобится учетная запись Google, настроенная на вашем тестовом устройстве. При написании кода автоматически будет использоваться первая найденная им учетная запись Google (что означает [0].) IDK, если вам нужно загрузить приложение Google Диска для этого. Я использовал API-уровень 15, я не знаю, как далеко этот код будет работать.

ОТДЫХ

Вышесказанное должно помочь вам начать, и, надеюсь, вы сможете понять, откуда это происходит... честно говоря, это примерно так, как я до сих пор понял. Надеюсь, это поможет МНОМУ людей и сэкономит им много времени. Я уверен, что я только что написал наиболее полное руководство по настройке приложения Android для использования Google Диска. Позор в Google для распространения необходимого материала по крайней мере на 6 разных страницах, которые вообще не связаны друг с другом.

Ответ 3

В 2015 году все изменилось!

Получить "Drive API для Android" с помощью gradle:

compile 'com.google.android.gms:play-services-drive:7.8.0'

Там есть несколько новых doco (хотя все еще тусклый IMO):

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

И для тех, кто собирается совершить обрушение... Самая большая проблема, с которой я столкнулся до сих пор, заключается в том, что нет абсолютно никакой возможности различать папки, которые были окончательно удалены из нормальных папок... вы можете их найти, вы можете создавать папки и файлы внутри них, только запись в файл DriveContents будет всегда терпеть неудачу.

Ответ 4

Взгляните на Google Пример DrEdit, в котором есть папка с именем android/. Скопируйте его, следуйте readme, и он должен работать (работает для меня на эмуляторе Android с KitKat).

.

P.S.

Извините за восстановление этого, но новый Google Android API для Android не поддерживает полный доступ к диску, только drive.file и drive.appdata области авторизации, поэтому, если вам нужен полный доступ, вам нужно вернуться к хорошему 'ol Google API Client для Java (который используется в примере DrEdit).

Ответ 5

Чтобы загрузить общедоступный файл с Google Drive:

Скопируйте вашу ссылку. Используйте ID файла, встроенный в него:

https://drive.google.com/open?id=<FILE_ID>

Вы можете использовать его для загрузки общедоступной ссылки, например:

https://drive.google.com/uc?id=<FILE_ID>&export=download 

Затем используйте некоторый код для загрузки файла через HTTP.