谷歌驱动器SDK异常 [英] Google Drive SDK Exception

查看:228
本文介绍了谷歌驱动器SDK异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图运行下面的code(从斯蒂芬·怀利<主要采取/ A>):

I am trying to run the following code (taken largely from Stephen Wylie):

package com.googledrive.googledriveapp;
// For Google Drive / Play Services
// Version 1.1 - Added new comments & removed dead code
// Stephen Wylie - 10/20/2012
import java.io.IOException;
import java.util.ArrayList;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.UserRecoverableAuthException;
import com.google.android.gms.common.AccountPicker;
import com.google.api.client.auth.oauth2.BearerToken;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.android2.AndroidHttp;
import com.google.api.client.googleapis.extensions.android2.auth.GoogleAccountManager;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.json.JsonHttpRequest;
import com.google.api.client.http.json.JsonHttpRequestInitializer;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.Drive.Apps.List;
import com.google.api.services.drive.Drive.Files;
import com.google.api.services.drive.DriveRequest;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;

public class MainActivity extends Activity {
    private static final int CHOOSE_ACCOUNT=0;
    private static String accountName;
    private static int REQUEST_TOKEN=0;
    private Button btn_drive;
    private Context ctx = this;
    private Activity a = this;

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        // set up the GUI layout
        setContentView(R.layout.activity_main);
        // set the variables to access the GUI controls
        btn_drive = (Button) findViewById(R.id.btn_drive);
            btn_drive.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                chooseAccount();
            }
            });
    }

    public void chooseAccount() {
        Intent intent = AccountPicker.newChooseAccountIntent(null, null, new String[]{"com.google"}, false, null, null, null, null);
        startActivityForResult(intent, CHOOSE_ACCOUNT);
    }

    // Fetch the access token asynchronously.
    void getAndUseAuthTokenInAsyncTask(Account account) {
        AsyncTask<Account, String, String> task = new AsyncTask<Account, String, String>() {
            ProgressDialog progressDlg;
            AsyncTask<Account, String, String> me = this;

            @Override
            protected void onPreExecute() {
                progressDlg = new ProgressDialog(ctx, ProgressDialog.STYLE_SPINNER);
                progressDlg.setMax(100);
                progressDlg.setTitle("Validating...");
                progressDlg.setMessage("Verifying the login data you entered...\n\nThis action will time out after 10 seconds.");
                progressDlg.setCancelable(false);
                progressDlg.setIndeterminate(false);
                progressDlg.setOnCancelListener(new android.content.DialogInterface.OnCancelListener() {
                    public void onCancel(DialogInterface d) {
                        progressDlg.dismiss();
                        me.cancel(true);
                    }
                });
                progressDlg.show();
            }

            @Override
            protected String doInBackground(Account... params) {
                return getAccessToken(params[0]);
            }

            @Override
            protected void onPostExecute(String s) {
                if (s == null) {
                    // Wait for the extra intent
                } else {
                    accountName = s;
                    getDriveFiles();
                }
                progressDlg.dismiss();
            }
        };
        task.execute(account);
    }

    /**
     * Fetches the token from a particular Google account chosen by the user.  DO NOT RUN THIS DIRECTLY.  It must be run asynchronously inside an AsyncTask.
     * @param activity
     * @param account
     * @return
     */
    private String getAccessToken(Account account) {
        try {
            return GoogleAuthUtil.getToken(ctx, account.name, "oauth2:" + DriveScopes.DRIVE);  // IMPORTANT: DriveScopes must be changed depending on what level of access you want
        } catch (UserRecoverableAuthException e) {
            // Start the Approval Screen intent, if not run from an Activity, add the Intent.FLAG_ACTIVITY_NEW_TASK flag.
            a.startActivityForResult(e.getIntent(), REQUEST_TOKEN);
            e.printStackTrace();
            return null;
        } catch (GoogleAuthException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    private Drive getDriveService() {
        HttpTransport ht = AndroidHttp.newCompatibleTransport();             // Makes a transport compatible with both Android 2.2- and 2.3+
        JacksonFactory jf = new JacksonFactory();                            // You need a JSON parser to help you out with the API response
        Credential credential = new Credential(BearerToken.authorizationHeaderAccessMethod()).setAccessToken(accountName);
        HttpRequestFactory rf = ht.createRequestFactory(credential);
        Drive.Builder b = new Drive.Builder(ht, jf, null);
        b.setJsonHttpRequestInitializer(new JsonHttpRequestInitializer() {

            @Override
            public void initialize(JsonHttpRequest request) throws IOException {
                DriveRequest driveRequest = (DriveRequest) request;
                driveRequest.setPrettyPrint(true);
                driveRequest.setOauthToken(accountName);
            }
        });
        return b.build();
    }

    /**
     * Obtains a list of all files on the signed-in user's Google Drive account.
     */
    private void getDriveFiles() {
        Drive service = getDriveService();
        Log.d("SiteTrack", "FUNCTION getDriveFiles()");
        Files.List request;
        try {
            request = service.files().list(); // .setQ("mimeType=\"text/plain\"");
        } catch (IOException e) {


            e.printStackTrace();
            return;
        }
        do {
            FileList files;
            try {
                System.out.println("got here");
                Log.d("SiteTrack", request.toString());
                **files = request.execute();**
            } catch (IOException e) {
                e.printStackTrace();
                Log.d("SiteTrack", "Exception");
                return;
            }
            ArrayList<File> fileList = (ArrayList<File>) files.getItems();
            Log.d("SiteTrack", "Files found: " + files.getItems().size());
            for (File f : fileList) {
                String fileId = f.getId();
                String title = f.getTitle();
                Log.d("SiteTrack", "File " + fileId + ": " + title);
            }
            request.setPageToken(files.getNextPageToken());
        } while (request.getPageToken() != null && request.getPageToken().length() >= 0);
    }

    protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        if (requestCode == CHOOSE_ACCOUNT && resultCode == RESULT_OK) {
            accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
            GoogleAccountManager gam = new GoogleAccountManager(this);
            getAndUseAuthTokenInAsyncTask(gam.getAccountByName(accountName));
            Log.d("SiteTrack", "CHOOSE_ACCOUNT");
        } else if (requestCode == REQUEST_TOKEN && resultCode == RESULT_OK) {
            accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
            Log.d("SiteTrack", "REQUEST_TOKEN");
        }
    }   
}

不过,我得到以下异常:

However, I get the following exception:

11-19 16:35:27.758: W/System.err(23287): com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
11-19 16:35:27.758: W/System.err(23287): {
11-19 16:35:27.758: W/System.err(23287):   "code" : 403,
11-19 16:35:27.758: W/System.err(23287):   "errors" : [ {
11-19 16:35:27.758: W/System.err(23287):     "domain" : "usageLimits",
11-19 16:35:27.762: W/System.err(23287):     "message" : "Access Not Configured",
11-19 16:35:27.762: W/System.err(23287):     "reason" : "accessNotConfigured"
11-19 16:35:27.762: W/System.err(23287):   } ],
11-19 16:35:27.762: W/System.err(23287):   "message" : "Access Not Configured"
11-19 16:35:27.762: W/System.err(23287): }
11-19 16:35:27.762: W/System.err(23287):    at com.google.api.client.googleapis.services.GoogleClient.executeUnparsed(GoogleClient.java:237)
11-19 16:35:27.762: W/System.err(23287):    at com.google.api.client.http.json.JsonHttpRequest.executeUnparsed(JsonHttpRequest.java:207)
11-19 16:35:27.762: W/System.err(23287):    at com.google.api.services.drive.Drive$Files$List.execute(Drive.java:1071)
11-19 16:35:27.762: W/System.err(23287):    at com.googledrive.googledriveapp.MainActivity.getDriveFiles(MainActivity.java:173)
11-19 16:35:27.762: W/System.err(23287):    at com.googledrive.googledriveapp.MainActivity.access$3(MainActivity.java:156)
11-19 16:35:27.762: W/System.err(23287):    at com.googledrive.googledriveapp.MainActivity$2.onPostExecute(MainActivity.java:104)
11-19 16:35:27.765: W/System.err(23287):    at com.googledrive.googledriveapp.MainActivity$2.onPostExecute(MainActivity.java:1)
11-19 16:35:27.765: W/System.err(23287):    at android.os.AsyncTask.finish(AsyncTask.java:417)
11-19 16:35:27.765: W/System.err(23287):    at android.os.AsyncTask.access$300(AsyncTask.java:127)
11-19 16:35:27.765: W/System.err(23287):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)
11-19 16:35:27.765: W/System.err(23287):    at android.os.Handler.dispatchMessage(Handler.java:99)
11-19 16:35:27.765: W/System.err(23287):    at android.os.Looper.loop(Looper.java:123)
11-19 16:35:27.765: W/System.err(23287):    at android.app.ActivityThread.main(ActivityThread.java:4627)
11-19 16:35:27.765: W/System.err(23287):    at java.lang.reflect.Method.invokeNative(Native Method)
11-19 16:35:27.769: W/System.err(23287):    at java.lang.reflect.Method.invoke(Method.java:521)
11-19 16:35:27.769: W/System.err(23287):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
11-19 16:35:27.769: W/System.err(23287):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
11-19 16:35:27.769: W/System.err(23287):    at dalvik.system.NativeStart.main(Native Method)

它跟踪到行文件= request.execute(); 在我的code以上(我已经有星号标记的话)。我已经启用了这两个驱动器的SDK,并在我的谷歌API控制台驱动器的API。下面是我的几个驱动器的SDK设置快照: 对于没有合照客户端ID部分,我只是粘贴从API访问部分中的已安装的应用程序客户端ID(我也尝试了驱动器的SDK客户端ID)。任何人都知道是什么问题?

which traces to the line files = request.execute(); in my code above (I have marked it with asterisks). I have enabled both the Drive SDK and the Drive API in my Google APIs Console. Here are a couple of snapshots of my Drive SDK settings: For the Client ID section that is not pictured, I simply pasted the "Client ID for installed applications" from the API Access section (I also tried the "Client ID for Drive SDK"). Anyone know what the problem is?

推荐答案

编辑:对不起,我只是意识到,我们可以使用debug.keystore登录调试模式下的APK。 所以,最重要的是插入您的谷歌API控制台正确的SHA1键。 (使用JRE7工具生成在他的Google+信息中提到了由斯蒂芬·怀利)

EDITED: Sorry I just realized that we can sign the apk in debugging mode using debug.keystore. SO, the most important thing is insert the correct SHA1 key in your Google API console. (generated using the JRE7 tool as mentioned by Stephen Wylie in his Google+ post)

另请参阅(developer.android.com/tool​​s/publishing/app-signing.html#debugmode)的存储密码

Also see (developer.android.com/tools/publishing/app-signing.html#debugmode) for the keystore password

在一些试验和错误,我终于能够在我的谷歌驱动器列表文件 虽然我不知道这是否是最正确的答案,但至少我可以现在就列出文件

After some trial and error, I finally able to list files in my google drive Although I am not sure whether this is the most correct answer, but at least I am able to list files now

首先,请参考斯蒂芬卫理更新Google+的帖子 <一href="https://plus.google.com/u/0/114042449736049687152/posts/CD3L8zcJg5Z">https://plus.google.com/u/0/114042449736049687152/posts/CD3L8zcJg5Z

First, please refer to Stephen Wylie updated Google+ post https://plus.google.com/u/0/114042449736049687152/posts/CD3L8zcJg5Z

生成SHA1密钥使用JRE7工具您的.keystore

generate the SHA1 key with your .keystore using the JRE7 tool

我使用,我一直在使用我的谷歌Play商店已经在的.keystore文件 (如果您没有任何密钥库,你可以去你的项目,单击导出,然后它会要求你创建的.keystore文件)

I am using the .keystore file that I had been using with my google play store (If you do not have any keystore, you can go to your project, click export, then it will request you to create a .keystore file)

与生成SHA1密钥,去你的谷歌API控制台(这是最好的,如果你从全新的开始,删除当前项目并开始一个新的)

with the generated SHA1 key, go to your Google API console (it is best if you start from fresh, delete the current project and start a new one)

- 启用驱动器API

-enable Drive API

- 启用驱动器的SDK

-enable Drive SDK

-go到API访问

-create客户端ID

-create CLIENT ID

-IMPORTANT这里,选择安装的应用程序和放大器;安卓

-IMPORTANT here, choose Installed application & Android

- 也重要,在生成的SHA1键键

-ALSO IMPORTANT, key in your generated SHA1 key

- 键在您在Eclipse项目使用了正确的包名(com.example.xxx)

-key in your CORRECT package name (com.example.xxx) that you are using in your eclipse project

-GO到驱动器的SDK标签-upload图标

-Go to Drive SDK tab -upload icon

-IMPORTANT,从API访问选项卡您的客户端ID(安装的应用程序客户端ID)键

-IMPORTANT, key in your CLIENT ID (Client ID for installed applications) from the API Access tab

- 插入斯蒂芬·怀利帖子中提到3范围,[/userinfo.email,/userinfo.profile,/认证/驱动器]

-Insert 3 scopes mentioned in Stephen Wylie post, [/userinfo.email, /userinfo.profile, /auth/drive]

- 插入一个网址

-TICK多文件支持

再次使您的code确保你的包的名字是一样的,你插入到谷歌API控制台

Again, make sure your package name in your code is same as the package name you inserted into Google API Console

最后,在Eclipse中,使用您创建刚才的.keystore文件导出项目

Finally, in eclipse, export your project using the .keystore file you created just now

将导出的APK文件到您的手机,安装和尝试。

Put the exported APK file into your phone, install and try.

检查您的LogCat中从您的谷歌驱动器显示列出的文件

Check your LogCat to show the listed files from your Google Drive

我用这种方法成功了。

编辑:如果您生成的SHA1键与debug.keystore,你可以跳过出口的一部分。只是调试应用程序就可以了。 Eclipse将自动签署debug.keystore的APK。

EDITED: If you generated the SHA1 key with the debug.keystore, you can skip the "Export" part. Just debug your application is OK. Eclipse will automatically sign the apk with debug.keystore.

编辑:接下来的时间你的code是准备好了,你需要生成一个新的SHA1键与你的真实的.keystore,然后输入到谷歌API控制台

EDITED: Next time your code is ready, you need to generate a new SHA1 key with your real .keystore, then input into the Google API console.

EDITED 2:确保你的清单包括这些

EDITED 2: Make sure your manifest include these

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />

这篇关于谷歌驱动器SDK异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆