我花了数百个小时尝试创建一个Android应用程序,该应用程序将使我无法打开和编辑存储在Google云端硬盘帐户中的文件,但没有成功。我相信一旦有了DriveService对象,我就知道如何处理这些文件,但是我根本无法理解凭据,令牌和授权。所有文档和示例要么已过时,过于混乱,要么对我不起作用。
我最近的尝试是使用https://github.com/google/google-api-java-client-samples/tree/master/tasks-android-sample处的Google API示例,但是该应用在选择所需帐户后立即崩溃。有人可以告诉我我的代码有什么问题吗,或者有一种更简单的方法来访问我的帐户的DriveService对象?我的MainActivity如下(其他类应与GitHub上的示例相同)。
package com.example.googledrivetestapp;
import android.app.Activity;
import android.os.Environment;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.tasks.TasksScopes;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import android.os.AsyncTask;
public final class MainActivity extends Activity {
private static final Level LOGGING_LEVEL = Level.OFF;
private static final String PREF_ACCOUNT_NAME = "accountName";
static final String TAG = "GoogleDriveTestApp";
static final int REQUEST_GOOGLE_PLAY_SERVICES = 0;
static final int REQUEST_AUTHORIZATION = 1;
static final int REQUEST_ACCOUNT_PICKER = 2;
final HttpTransport httpTransport = AndroidHttp.newCompatibleTransport();
final JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
GoogleAccountCredential credential;
List<String> tasksList;
ArrayAdapter<String> adapter;
com.google.api.services.tasks.Tasks service;
int numAsyncTasks;
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnChooseAccount = (Button) findViewById(R.id.btnChooseAccount);
btnChooseAccount.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
chooseAccount();
}
});
// enable logging
Logger.getLogger("com.google.api.client").setLevel(LOGGING_LEVEL);
// Google Accounts
credential =
GoogleAccountCredential.usingOAuth2(this, Collections.singleton(TasksScopes.TASKS));
SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
credential.setSelectedAccountName(settings.getString(PREF_ACCOUNT_NAME, null));
// Tasks client
service =
new com.google.api.services.tasks.Tasks.Builder(httpTransport, jsonFactory, credential)
.setApplicationName("GoogleDriveTestApp").build();
}
void showGooglePlayServicesAvailabilityErrorDialog(final int connectionStatusCode) {
runOnUiThread(new Runnable() {
public void run() {
Dialog dialog =
GooglePlayServicesUtil.getErrorDialog(connectionStatusCode, MainActivity.this,
REQUEST_GOOGLE_PLAY_SERVICES);
dialog.show();
}
});
}
void refreshView() {
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, tasksList);
listView.setAdapter(adapter);
}
@Override
protected void onResume() {
super.onResume();
if (checkGooglePlayServicesAvailable()) {
haveGooglePlayServices();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_GOOGLE_PLAY_SERVICES:
if (resultCode == Activity.RESULT_OK) {
haveGooglePlayServices();
} else {
checkGooglePlayServicesAvailable();
}
break;
case REQUEST_AUTHORIZATION:
if (resultCode == Activity.RESULT_OK) {
AsyncLoadTasks.run(this);
} else {
chooseAccount();
}
break;
case REQUEST_ACCOUNT_PICKER:
if (resultCode == Activity.RESULT_OK && data != null && data.getExtras() != null) {
String accountName = data.getExtras().getString(AccountManager.KEY_ACCOUNT_NAME);
if (accountName != null) {
credential.setSelectedAccountName(accountName);
SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString(PREF_ACCOUNT_NAME, accountName);
editor.commit();
AsyncLoadTasks.run(this);
}
}
break;
}
}
/** Check that Google Play services APK is installed and up to date. */
private boolean checkGooglePlayServicesAvailable() {
final int connectionStatusCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (GooglePlayServicesUtil.isUserRecoverableError(connectionStatusCode)) {
showGooglePlayServicesAvailabilityErrorDialog(connectionStatusCode);
return false;
}
return true;
}
private void haveGooglePlayServices() {
// check if there is already an account selected
if (credential.getSelectedAccountName() == null) {
// ask user to choose account
chooseAccount();
} else {
// load calendars
AsyncLoadTasks.run(this);
}
}
private void chooseAccount() {
startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
}
}
这是我的build.gradle文件:
apply plugin: 'com.android.application'
repositories {
mavenCentral()
mavenLocal() // For google-play-services is not on Maven Central.
}
dependencies {
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:design:26.1.0'
implementation 'com.google.apis:google-api-services-tasks:v1-rev48-1.23.0' exclude module: 'httpclient'
implementation 'com.google.api-client:google-api-client-android:1.23.0' exclude module: 'httpclient'
implementation 'com.google.http-client:google-http-client-gson:1.23.0' exclude module: 'httpclient'
implementation 'com.google.android.gms:play-services-identity:7.3.0'
implementation 'com.android.support:support-annotations:+'
}
android {
compileSdkVersion 26
defaultConfig {
minSdkVersion 14
targetSdkVersion 26
}
buildTypes {
release {
minifyEnabled true
proguardFile 'proguard-google-api-client.txt'
proguardFile getDefaultProguardFile('proguard-android.txt')
}
}
}
这是崩溃后立即从帐户选择器中选择我的帐户的Logcat。
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.example.googledrivetestapp, PID: 25164
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:309)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.IllegalArgumentException: the name must not be empty: null
at android.accounts.Account.<init>(Account.java:48)
at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential.getToken(GoogleAccountCredential.java:267)
at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:292)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:868)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
at com.example.googledrivetestapp.AsyncLoadTasks.doInBackground(AsyncLoadTasks.java:19)
at com.example.googledrivetestapp.CommonAsyncTask.doInBackground(CommonAsyncTask.java:34)
at com.example.googledrivetestapp.CommonAsyncTask.doInBackground(CommonAsyncTask.java:12)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
有没有人可以结束我的痛苦?
答案 0 :(得分:0)
通过链接下载: https://github.com/gsuitedevs/android-samples.git
打开项目“弃用”。此示例将帮助访问帐户。如果您在开发者控制台中收到了应用程序凭据:https://console.cloud.google.com