web-dev-qa-db-ja.com

Android GoogleドライブSDKとの間でファイルを開いて保存する

過去6時間、Googleからのドキュメントを注いできましたが、これを始める方法がまだわかりません。既存のAndroidアプリがGoogleドライブからファイルを読み取り、Googleドライブに新しいファイルをアップロードし、Googleドライブ上の既存のファイルを編集できるようにするだけです。

Drive SDK v2は、Android(および一般的にはモバイル)開発者が簡単に使用できるようにすることだけに焦点を当てていましたが、ドキュメントにはほとんど何もありませんでした。 。

理想的には、これを行うための適切なドキュメント、例、チュートリアルを誰かに指摘してもらいたいと思います(Androidを使用していることを覚えておいてください。GoogleApp Engineでドライブを使用する方法についてはたくさんあります。すでにそれを見ており、そこからAndroidアプリ)に移行する方法がわかりません。

どのライブラリをダウンロードしてプロジェクトに追加する必要があるか、マニフェストに追加する必要があるもの、そして最終的にGoogleドライブからファイルのリストを取得し、1つをダウンロードしてから修正バージョンをアップロードする方法を知る必要があります。

理想的には、公式のGoogleドライブアプリが行うように、アカウントを自動的に処理したいと思います。

57
ArtOfWarfare

編集:Claudio Cherubinoは、Google Play Servicesが利用可能になり、このプロセスがずっと簡単になると言います。ただし、使用可能なサンプルコードはありません(まだ、近日公開予定です... 4か月前にGoogle Play開発者サービスは「近日公開」と言われたため、この回答がアクセスの唯一の完全に機能する例である可能性が高いAndroidアプリケーションから2013へのGoogleドライブ。)

編集2X:来年までGoogleに実例がないと言ったとき、私は約1か月遅れていたようです。 Googleの公式ガイドはこちらです。

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

私はまだそれらのメソッドをテストしていませんので、2012年9月(以下)からの私のソリューションはまだ最高である可能性があります

これにはGoogle Playサービスは必要ありません。それはお尻の痛みであり、私はそれをすべて理解するのに50時間以上(編集:100時間以上)を費やしましたが、ここで知っておくと役立つことがたくさんあります:

ライブラリー

一般的なGoogleのオンラインサービスの場合、プロジェクトでこれらのライブラリが必要になります:( Instructions and Download 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-jackson-1.11.0-beta.jar
  • google-oauth-client-1.11.0-beta.jar
  • guava-11.0.1.jar
  • jackson-core-asl-1.9.9.jar
  • jsr305-1.3.9.jar

特にGoogleドライブの場合、これも必要になります。

コンソールのセットアップ

次に、 Googleコンソール に進みます。新しいプロジェクトを作成します。 [サービス]で、2つの項目をオンにする必要があります:DRIVE APIおよびDRIVE SDK!それらは別々であり、一方は自動的に他方をオンにしません、そして、あなたは両方をオンにしなければなりません!単独で。)

コンソールで、API Accessに移動します。クライアントを作成し、Androidアプリにします。バンドルIDを指定します。間違ったものを使用したと確信しているので、指紋が実際に重要だとは思いませんが、とにかく正しい方法を試してください(Googleが指示を提供します)。

クライアントIDを生成します。それが必要になります。つかまって。

編集:私は間違っていると言われ、ドライブAPIをオンにするだけでよく、ドライブSDKをオンにする必要はなく、設定しないSimple APIキーを使用するだけでよいと言われましたAndroid向けに何かをセットアップします。私は今それを調べていますが、おそらく私がそれを理解したら数分でこの答えを編集します...

THE Android CODE-セットアップとアップロード

まず、認証トークンを取得します。

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-ダウンロード中

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

THE Android CODE-更新中

Googleドライブ上のファイルの最終変更日を更新する際の2つの簡単なメモ:

  1. 完全に初期化されたDateTimeを提供する必要があります。そうしないと、Googleドライブから「Bad Request」の応答が返されます。
  2. GoogleドライブのファイルでsetModifiedDate()を使用し、更新要求自体で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ビルドターゲットをGoogle APIに変更します。存在しない場合は、Androidダウンロードマネージャー。

エミュレータでテストする場合は、そのターゲットが汎用のAndroidではなくGoogle APIであることを確認してください。

テストデバイスでGoogleアカウントを設定する必要があります。書かれたコードは、最初に見つかったGoogleアカウントを自動的に使用します(これが[0]です)。これを機能させるためにGoogleドライブアプリをダウンロードする必要がある場合は、IDKです。私はAPIレベル15を使用していましたが、このコードがどれくらい前に機能するかわかりません。

THE REST

上記はあなたを開始するはずであり、うまくいけばそこからあなたの道を理解できることを願っています...正直に言って、これはちょうど私がこれまでに得た限りです。これが多くの人々の助けとなり、多くの時間を節約できることを願っています。 Google Driveを使用するためのAndroidアプリをセットアップするための最も包括的なセットアップガイドを書いたところだと確信しています。互いにリンクしていません。

78
ArtOfWarfare

2015年、事態は変化しました!

Gradleで「Android用ドライブAPI」を入手してください:

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

いくつかの新しいドコがあります(それでもIMOはまだまだ光りません):

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

そして、洞窟に行く人のために...これまで私が遭遇した最大の問題は、永久に削除されたフォルダと通常のフォルダを区別する方法がまったくないということです...それらを見つけることができ、フォルダを作成して、ファイル内のファイル、DriveContentsファイルへの書き込みのみが常に失敗します。

4
straya

Androidアプリとドライブを統合する方法については、Google I/Oのこの動画をご覧ください。

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

動画に表示される内容はGoogle Play開発者サービスに基づいていることに注意してください、まだ一般公開されていない

https://developers.google.com/Android/google-play-services/

4

Googleの DrEditの例 を見てください。これには、Android/というフォルダーがあります。コピーして、readmeをたどると動作します(Androidエミュレーターで動作します)。

P.S。

これを復活させてすみませんが、新しい Google Drive Android API は完全なドライブアクセスをサポートせず、drive.filedrive.appdataのみをサポートします- 承認スコープ 。したがって、フルアクセスが必要な場合は、「ol Google APIのJavaクライアント 」(DrEditの例で使用)に戻る必要があります。

2
woojoo666