10

アプリは「インストール済みアプリケーション」として「GoogleAPIコンソール」に登録されました。これはAndroidアプリに適した設定のようです。

したがって、Client-Idはあり、Secret-Idはありません。明確にするために:これはWebアプリでもGoogleドライブアプリでもありません-Googleドライブクラウド内の他のユーザーデータにアクセスするAndroidアプリです。

アプリ内でアカウントを取得し(動作し)、トークンを要求します(動作します)。次に、そのトークンとClient-Idを使用してGoogleドライブに接続します。結果は「401、無効なクレデンシャル」です。このコードの何が問題になっていますか?

public class ActivityMain extends Activity implements DialogInterface.OnClickListener {

    // https://developers.google.com/drive/scopes
    private static final String AUTH_TOKEN_TYPE = "oauth2:https://www.googleapis.com/auth/drive";

    // https://code.google.com/apis/console/
    private static final String CLIENT_ID = "999999999999999.apps.googleusercontent.com";

    private AccountManager accountManager;
    private Account[] accounts;
    private String authName;
    private String authToken;

    @Override
    public void onClick(final DialogInterface dialogInterface, final int item) {

        processAccountSelected(accounts[item]);
    }

    @Override
    public void onCreate(final Bundle bundle) {
        super.onCreate(bundle);

        setContentView(R.layout.activitymain);

        accountManager = AccountManager.get(this);
        accounts = accountManager.getAccountsByType("com.google");

        if (accounts == null || accounts.length == 0) {
            // TODO
        } else if (accounts.length == 1) {
            processAccountSelected(accounts[0]);
        } else if (accounts.length > 1) {
            showDialog(MyConstants.DIALOG_ACCOUNTCHOSER);
        }
    }

    @Override
    protected Dialog onCreateDialog(final int id) {
        switch (id) {
            case MyConstants.DIALOG_ACCOUNTCHOSER:
                AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);

                String[] names = new String[accounts.length];

                for (int i = 0; i < accounts.length; i++) {
                    names[i] = accounts[i].name;
                }

                alertDialogBuilder.setItems(names, this);
                alertDialogBuilder.setTitle("Select a Google account");
                return alertDialogBuilder.create();
        }

        return null;
    }

    private void processAccountSelected(final Account account) {
        if (account != null) {
            authName = account.name.toString();
            if (!Tools.isEmpty(authName)) {
                Toast.makeText(this, authName, Toast.LENGTH_LONG).show();

                accountManager.getAuthToken(account, AUTH_TOKEN_TYPE, null, this,
                        new AccountManagerCallback<Bundle>() {

                            public void run(final AccountManagerFuture<Bundle> future) {
                                try {
                                    authToken = future.getResult().getString(
                                            AccountManager.KEY_AUTHTOKEN);
                                    processTokenReceived();
                                } catch (OperationCanceledException exception) {
                                    // TODO
                                } catch (Exception exception) {
                                    Log.d(this.getClass().getName(), exception.getMessage());
                                }
                            }
                        }, null);
            }
        }
    }

    private void processListFiles(final Drive drive) {
        List<File> result = new ArrayList<File>();
        Files.List request = null;
        try {
            request = drive.files().list();
        } catch (IOException exception) {
        }

        do {
            try {
                FileList files = request.execute();

                result.addAll(files.getItems());
                request.setPageToken(files.getNextPageToken());
            } catch (IOException exception) {
                // --> 401 invalid credentials
            }
        } while (request.getPageToken() != null && request.getPageToken().length() > 0);
    }

    private void processTokenReceived() {
        if (!Tools.isEmpty(authToken)) {
            final HttpTransport transport = AndroidHttp.newCompatibleTransport();
            final JsonFactory jsonFactory = new GsonFactory();
            GoogleCredential credential = new GoogleCredential();
            credential.setAccessToken(authToken);
            Drive drive = new Drive.Builder(transport, jsonFactory, credential)
                    .setApplicationName(getString(R.string.txt_appname))
                    .setJsonHttpRequestInitializer(new GoogleKeyInitializer(CLIENT_ID))
                    .build();

            if (drive != null) {
                processListFiles(drive);
            }
        }
    }
}

私はこれが混乱の完全な負荷であると言わなければなりません。Webにはパーツのみを表示するページが非常に多く、同じことを行うために非推奨、欠落、または異なる方法を使用しているページが非常に多くあります。私の意見では、Androidアプリ内からGoogleドライブからデータを取得する同じ方法を示す2つのページはありません。

どんな助けでも大歓迎です。

編集:私はそれを自分で解決することができました。これは、さまざまな変更の組み合わせでした。

  • android:minSdkVersion="11"を要件として設定する必要がありました
  • この現在のライブラリを使用する必要がありました:google-api-client-1.11.0-beta.jar、google-api-client-android-1.11.0-beta.jar、google-api-services-drive-v2-rev9-1.8 .0-beta.jar、google-http-client-1.11.0-beta.jar、google-http-client-android-1.11.0-beta.jar、google-http-client-gson-1.11.0-beta .jar、google-http-client-jackson2-1.11.0-beta.jar、google-oauth-client-1.11.0-beta.jar、gson-2.1.jar、guava-11.0.1.jar、jackson-core -2.0.5.jar、jsr305-1.3.9.jar

これは、ドライブオブジェクトを取得するための現在の部分です。

    GoogleCredential credential = new GoogleCredential();
    credential.setAccessToken(authToken);

    HttpTransport transport = AndroidHttp.newCompatibleTransport();

    JsonFactory jsonFactory = new AndroidJsonFactory();

    drive = new Drive.Builder(transport, jsonFactory, credential)
            .setApplicationName(getString(R.string.txt_appname))
            .setJsonHttpRequestInitializer(
                    new GoogleKeyInitializer(APIKEY_SIMPLE))
            .build();
    if (drive != null) {
    }
4

4 に答える 4

3

ええ、ドキュメントを把握するのは非常に困難です。

変更するだけ

new GoogleKeyInitializer(CLIENT_ID)

new GoogleKeyInitializer(SIMPLE_API_ACCESS_KEY)

そしてそれは動作するはずです。

SIMPLE_API_ACCESS_KEYGoogleのAPIコンソールの[ APIアクセス]ページの[シンプルなAPIアクセス]セクション()にあります。このセクションが利用できない場合は、最初に[サービス]ページでドライブAPIアクセスをアクティブ化する必要があります。API key

于 2012-09-13T13:27:54.993 に答える
1

含めたスニペットには2つの問題があります。

  1. AccountManagerから新しいものをフェッチする前に、古いauthTokenを無効にする必要authTokenがあります。

    AccountManager.get(activity).invalidateAuthToken("com.google", authToken);
    accountManager.getAuthToken(...);
    
  2. の呼び出しsetJsonHttpRequestInitializerでは、プロジェクトのAPIコンソールで宣言されたシンプルAPIキーを使用する必要があります。

    • APIコンソールにアクセスして取得できます。
    • 左側のメニューで[ APIアクセス]をクリックします。
    • Simple API Accessを探し、 APIキーをコピーします。
    • Driveオブジェクトを作成するときにAPIキーを設定します。

      .setJsonHttpRequestInitializer(new GoogleKeyInitializer(KEY))

トークンの無効化を示す小さなサンプルがここにあります:http ://chiarg.com/?p = 429

于 2012-09-16T23:40:37.963 に答える
0

私はこれをすべて試し、最終的にこのコードがgoogleCalendarapiで動作することを発見しました。以前は、GoogleCredentialsを使用してビルドに渡すたびに401を取得していました。

HttpTransport transport = AndroidHttp.newCompatibleTransport();;
    JsonFactory jsonFactory = new GsonFactory();
    HttpRequestInitializer httpRequestInitializer;

    Log.i("Reached calendar builder", "Reached calendar builder"+accessToken);

    //GoogleCredential credential = new GoogleCredential();

     httpRequestInitializer = new HttpRequestInitializer(){
        public void initialize(HttpRequest request) throws IOException
        {
                request.getHeaders().setAuthorization(GoogleHeaders.getGoogleLoginValue(accessToken));
        }
    };

    Calendar service = new Calendar.Builder(transport, jsonFactory, httpRequestInitializer)
    .setApplicationName("Meetrbus/1.0")
    .setJsonHttpRequestInitializer(new GoogleKeyInitializer("API_KEY"))
    .build();


}
于 2012-09-15T14:02:30.717 に答える
0

私はここでAndroidでGoogleドライブを使用することについて広範な回答をしました:

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

その回答で説明した方法を使用して、次のことができることを確認できます。

  • メタデータの設定とアクセス
  • ファイルのアップロード
  • ファイルのダウンロード
  • Googleドライブディレクトリ間でファイルを移動する
  • ドライブからファイルを完全に削除します
于 2012-09-17T12:26:32.500 に答える