如何在Android应用程序中设置Google Drive凭据?

该应用程序已在“Google API控制台”中注册为“已安装的应用程序” – 似乎这是Android应用程序的正确设置,不是吗?

所以我有一个客户端ID和没有秘密ID。 要说清楚:这不是networking应用程序,也不是Google Drive-App – 这是一个Android应用程序访问Google云端硬盘中的其他用户数据。

在应用程序中获取帐户(工作),我确实要求令牌(工程)。 现在我要使用该令牌和客户端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); } } } } 

我不得不说这是一团糟。 networking上有很多页面只显示部分内容,而且有太多的页面使用不赞成,缺less或不同的方法来做同样的事情。 在我看来,并不是两页显示的是从Android应用程序中获取Google云端硬盘数据的相同方式。

任何帮助,高度赞赏。

编辑:我可以自己解决。 这是不同的变化的组合:

  • 必须设置android:minSdkVersion =“11”作为要求
  • 不得不使用这个目前的库:谷歌API的客户端1.11.0 beta.jar,谷歌API客户端的Android 1.11.0 beta.jar,谷歌API的服务驱动器V2的修正9-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

这是获取Drive对象的当前部分:

  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) { } 

Solutions Collecting From Web of "如何在Android应用程序中设置Google Drive凭据?"

是的,这个文档是很难理解的。

只是改变

 new GoogleKeyInitializer(CLIENT_ID) 

 new GoogleKeyInitializer(SIMPLE_API_ACCESS_KEY) 

它应该工作。

您可以在API访问页面( API key )的简单API访问部分下find您的SIMPLE_API_ACCESS_KEY 。 如果此部分不可用,则必须先在“ 服务”页面上激活Drive API访问权限。

有2个问题,你包括的片段。

  1. 在从AccountManager获取新的authToken之前,您必须使旧的authToken无效。

     AccountManager.get(activity).invalidateAuthToken("com.google", authToken); accountManager.getAuthToken(...); 
  2. setJsonHttpRequestInitializer的调用必须使用在您的项目的API控制台中声明的简单API密钥。

    • 可以通过访问API控制台获取 。
    • 点击左侧菜单中的API访问
    • 寻找简单的API访问 ,并复制API密钥
    • 构buildDrive对象时设置API密钥。

      .setJsonHttpRequestInitializer(新的GoogleKeyInitializer(KEY))

有一个小样本在这里显示令牌失效: http : //chiarg.com/?p=429

我试了这一切,终于find了这个代码与谷歌日历API工作。 我以前每次使用GoogleCredentials时都会得到一个401,并将其传递给构build。

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

我在这里介绍了如何在Android上使用Google云端硬盘:

Android打开并保存文件到/从Google Drive SDK

使用我在答案中列出的方法,我可以确认您可以执行以下操作:

  • 设置和访问元数据
  • 上传文件
  • 下载文件
  • 在Google云端硬盘目录之间移动文件
  • 完全删除驱动器中的文件