getDriveResourceClient方法无法解析

时间:2018-03-04 22:10:56

标签: android import google-drive-android-api

我正在尝试使用google drive api直接从Android应用创建一个谷歌电子表格。我运行了快速启动https://developers.google.com/drive/v3/web/quickstart/android#step_5_setup_the_sample中给出的代码,它运行正常。现在在创建电子表格时,android studio无法解析

getDriveResourceClient()
谷歌文档中提供的方法:https://developers.google.com/drive/android/create-file。任何人都可以告诉我,我必须添加哪个导入语句,因为android studio本身并不暗示任何? This is how my code looks

我在getDataFromApi()方法中遇到错误

    package com.example.kriti.kidharhai;

import android.Manifest;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.text.TextUtils;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.drive.DriveContents;
import com.google.android.gms.drive.DriveFile;
import com.google.android.gms.drive.DriveFolder;
import com.google.android.gms.drive.*;
import com.google.android.gms.drive.MetadataChangeSet;
import com.google.android.gms.tasks.Continuation;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.Tasks;
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.googleapis.extensions.android.gms.auth.GooglePlayServicesAvailabilityIOException;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.ExponentialBackOff;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.FileList;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executor;





import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.EasyPermissions;

public class Door5 extends Activity
        implements EasyPermissions.PermissionCallbacks {
    GoogleAccountCredential mCredential;
    private TextView mOutputText;
    private Button mCallApiButton;
    ProgressDialog mProgress;

static final int REQUEST_ACCOUNT_PICKER = 1000;
static final int REQUEST_AUTHORIZATION = 1001;
static final int REQUEST_GOOGLE_PLAY_SERVICES = 1002;
static final int REQUEST_PERMISSION_GET_ACCOUNTS = 1003;

private static final String BUTTON_TEXT = "Call Drive API";
private static final String PREF_ACCOUNT_NAME = "accountName";
private static final String[] SCOPES = { DriveScopes.DRIVE_METADATA_READONLY };

/**
 * Create the main activity.
 * @param savedInstanceState previously saved instance data.
 */
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    LinearLayout activityLayout = new LinearLayout(this);
    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT,
            LinearLayout.LayoutParams.MATCH_PARENT);
    activityLayout.setLayoutParams(lp);
    activityLayout.setOrientation(LinearLayout.VERTICAL);
    activityLayout.setPadding(16, 16, 16, 16);

    ViewGroup.LayoutParams tlp = new ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT);

    mCallApiButton = new Button(this);
    mCallApiButton.setText(BUTTON_TEXT);
    mCallApiButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mCallApiButton.setEnabled(false);
            mOutputText.setText("");
            getResultsFromApi();
            mCallApiButton.setEnabled(true);
        }
    });
    activityLayout.addView(mCallApiButton);

    mOutputText = new TextView(this);
    mOutputText.setLayoutParams(tlp);
    mOutputText.setPadding(16, 16, 16, 16);
    mOutputText.setVerticalScrollBarEnabled(true);
    mOutputText.setMovementMethod(new ScrollingMovementMethod());
    mOutputText.setText(
            "Click the \'" + BUTTON_TEXT +"\' button to test the API.");
    activityLayout.addView(mOutputText);

    mProgress = new ProgressDialog(this);
    mProgress.setMessage("Calling Drive API ...");

    setContentView(activityLayout);

    // Initialize credentials and service object.
    mCredential = GoogleAccountCredential.usingOAuth2(
            getApplicationContext(), Arrays.asList(SCOPES))
            .setBackOff(new ExponentialBackOff());
}



/**
 * Attempt to call the API, after verifying that all the preconditions are
 * satisfied. The preconditions are: Google Play Services installed, an
 * account was selected and the device currently has online access. If any
 * of the preconditions are not satisfied, the app will prompt the user as
 * appropriate.
 */
private void getResultsFromApi() {
    if (! isGooglePlayServicesAvailable()) {
        acquireGooglePlayServices();
    } else if (mCredential.getSelectedAccountName() == null) {
        chooseAccount();
    } else if (! isDeviceOnline()) {
        mOutputText.setText("No network connection available.");
    } else {
        new MakeRequestTask(mCredential).execute();
    }
}

/**
 * Attempts to set the account used with the API credentials. If an account
 * name was previously saved it will use that one; otherwise an account
 * picker dialog will be shown to the user. Note that the setting the
 * account to use with the credentials object requires the app to have the
 * GET_ACCOUNTS permission, which is requested here if it is not already
 * present. The AfterPermissionGranted annotation indicates that this
 * function will be rerun automatically whenever the GET_ACCOUNTS permission
 * is granted.
 */
@AfterPermissionGranted(REQUEST_PERMISSION_GET_ACCOUNTS)
private void chooseAccount() {
    if (EasyPermissions.hasPermissions(
            this, Manifest.permission.GET_ACCOUNTS)) {
        String accountName = getPreferences(Context.MODE_PRIVATE)
                .getString(PREF_ACCOUNT_NAME, null);
        if (accountName != null) {
            mCredential.setSelectedAccountName(accountName);
            getResultsFromApi();
        } else {
            // Start a dialog from which the user can choose an account
            startActivityForResult(
                    mCredential.newChooseAccountIntent(),
                    REQUEST_ACCOUNT_PICKER);
        }
    } else {
        // Request the GET_ACCOUNTS permission via a user dialog
        EasyPermissions.requestPermissions(
                this,
                "This app needs to access your Google account (via Contacts).",
                REQUEST_PERMISSION_GET_ACCOUNTS,
                Manifest.permission.GET_ACCOUNTS);
    }
}

/**
 * Called when an activity launched here (specifically, AccountPicker
 * and authorization) exits, giving you the requestCode you started it with,
 * the resultCode it returned, and any additional data from it.
 * @param requestCode code indicating which activity result is incoming.
 * @param resultCode code indicating the result of the incoming
 *     activity result.
 * @param data Intent (containing result data) returned by incoming
 *     activity result.
 */
@Override
protected void onActivityResult(
        int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch(requestCode) {
        case REQUEST_GOOGLE_PLAY_SERVICES:
            if (resultCode != RESULT_OK) {
                mOutputText.setText(
                        "This app requires Google Play Services. Please install " +
                                "Google Play Services on your device and relaunch this app.");
            } else {
                getResultsFromApi();
            }
            break;
        case REQUEST_ACCOUNT_PICKER:
            if (resultCode == RESULT_OK && data != null &&
                    data.getExtras() != null) {
                String accountName =
                        data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
                if (accountName != null) {
                    SharedPreferences settings =
                            getPreferences(Context.MODE_PRIVATE);
                    SharedPreferences.Editor editor = settings.edit();
                    editor.putString(PREF_ACCOUNT_NAME, accountName);
                    editor.apply();
                    mCredential.setSelectedAccountName(accountName);
                    getResultsFromApi();
                }
            }
            break;
        case REQUEST_AUTHORIZATION:
            if (resultCode == RESULT_OK) {
                getResultsFromApi();
            }
            break;
    }
}

/**
 * Respond to requests for permissions at runtime for API 23 and above.
 * @param requestCode The request code passed in
 *     requestPermissions(android.app.Activity, String, int, String[])
 * @param permissions The requested permissions. Never null.
 * @param grantResults The grant results for the corresponding permissions
 *     which is either PERMISSION_GRANTED or PERMISSION_DENIED. Never null.
 */
@Override
public void onRequestPermissionsResult(int requestCode,
                                       @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    EasyPermissions.onRequestPermissionsResult(
            requestCode, permissions, grantResults, this);
}

/**
 * Callback for when a permission is granted using the EasyPermissions
 * library.
 * @param requestCode The request code associated with the requested
 *         permission
 * @param list The requested permission list. Never null.
 */
@Override
public void onPermissionsGranted(int requestCode, List<String> list) {
    // Do nothing.
}

/**
 * Callback for when a permission is denied using the EasyPermissions
 * library.
 * @param requestCode The request code associated with the requested
 *         permission
 * @param list The requested permission list. Never null.
 */
@Override
public void onPermissionsDenied(int requestCode, List<String> list) {
    // Do nothing.
}

/**
 * Checks whether the device currently has a network connection.
 * @return true if the device has a network connection, false otherwise.
 */
private boolean isDeviceOnline() {
    ConnectivityManager connMgr =
            (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
    return (networkInfo != null && networkInfo.isConnected());
}

/**
 * Check that Google Play services APK is installed and up to date.
 * @return true if Google Play Services is available and up to
 *     date on this device; false otherwise.
 */
private boolean isGooglePlayServicesAvailable() {
    GoogleApiAvailability apiAvailability =
            GoogleApiAvailability.getInstance();
    final int connectionStatusCode =
            apiAvailability.isGooglePlayServicesAvailable(this);
    return connectionStatusCode == ConnectionResult.SUCCESS;
}

/**
 * Attempt to resolve a missing, out-of-date, invalid or disabled Google
 * Play Services installation via a user dialog, if possible.
 */
private void acquireGooglePlayServices() {
    GoogleApiAvailability apiAvailability =
            GoogleApiAvailability.getInstance();
    final int connectionStatusCode =
            apiAvailability.isGooglePlayServicesAvailable(this);
    if (apiAvailability.isUserResolvableError(connectionStatusCode)) {
        showGooglePlayServicesAvailabilityErrorDialog(connectionStatusCode);
    }
}


/**
 * Display an error dialog showing that Google Play Services is missing
 * or out of date.
 * @param connectionStatusCode code describing the presence (or lack of)
 *     Google Play Services on this device.
 */
void showGooglePlayServicesAvailabilityErrorDialog(
        final int connectionStatusCode) {
    GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
    Dialog dialog = apiAvailability.getErrorDialog(
            Door5.this,
            connectionStatusCode,
            REQUEST_GOOGLE_PLAY_SERVICES);
    dialog.show();
}

/**
 * An asynchronous task that handles the Drive API call.
 * Placing the API calls in their own task ensures the UI stays responsive.
 */
private class MakeRequestTask extends AsyncTask<Void, Void, List<String>> {
    private com.google.api.services.drive.Drive mService = null;
    private Exception mLastError = null;

    MakeRequestTask(GoogleAccountCredential credential) {
        HttpTransport transport = AndroidHttp.newCompatibleTransport();
        JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
        mService = new com.google.api.services.drive.Drive.Builder(
                transport, jsonFactory, credential)
                .setApplicationName("Drive API Android Quickstart")
                .build();
    }

    /**
     * Background task to call Drive API.
     * @param params no parameters needed for this task.
     */
    @Override
    protected List<String> doInBackground(Void... params) {
        try {
            return getDataFromApi();
        } catch (Exception e) {
            mLastError = e;
            cancel(true);
            return null;
        }
    }

    /**
     * Fetch a list of up to 10 file names and IDs.
     * @return List of Strings describing files, or an empty list if no files
     *         found.
     * @throws IOException
     */
    private List<String> getDataFromApi() throws IOException {
        // Get a list of up to 10 files.
        List<String> fileInfo = new ArrayList<String>();
        FileList result = mService.files().list()
                .setFields("nextPageToken, files(id, name)")
                .execute();
        /*List<File> files = result.getFiles();
        if (files != null) {
            for (File file : files) {
                fileInfo.add(String.format("%s (%s)\n",
                        file.getName()));
            }
        }*/

        final Task<DriveFolder> rootFolderTask = getDriveResourceClient().getRootFolder();
        final Task<DriveContents> createContentsTask = getDriveResourceClient().createContents();
        Tasks.whenAll(rootFolderTask, createContentsTask)
                .continueWithTask(new Continuation<Void, Task<DriveFile>>() {
                    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
                    @Override
                    public Task<DriveFile> then(@NonNull Task<Void> task) throws Exception {
                        DriveFolder parent = rootFolderTask.getResult();
                        DriveContents contents = createContentsTask.getResult();
                        OutputStream outputStream = contents.getOutputStream();
                        try (Writer writer = new OutputStreamWriter(outputStream)) {
                            writer.write("Hello World!");
                        }

                        MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
                                .setTitle("HelloWorld.txt")
                                .setMimeType("text/plain")
                                .setStarred(true)
                                .build();

                        return getDriveResourceClient().createFile(parent, changeSet, contents);
                    }
                })
                .addOnSuccessListener((Executor) this,
                        new OnSuccessListener<DriveFile>() {
                            @Override
                            public void onSuccess(DriveFile driveFile) {
                                mOutputText.setText("Created");
                                finish();
                            }
                        })
                .addOnFailureListener(this, new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Log.e(TAG, "Unable to create file", e);
                        showMessage(getString(R.string.file_create_error));
                        finish();
                    }
                });





        return fileInfo;
    }


    @Override
    protected void onPreExecute() {
        mOutputText.setText("");
        mProgress.show();
    }

    @Override
    protected void onPostExecute(List<String> output) {
        mProgress.hide();
        if (output == null || output.size() == 0) {
            mOutputText.setText("No results returned.");
        } else {
            output.add(0, "Data retrieved using the Drive API:");
            mOutputText.setText(TextUtils.join("\n", output));
        }
    }

    @Override
    protected void onCancelled() {
        mProgress.hide();
        if (mLastError != null) {
            if (mLastError instanceof GooglePlayServicesAvailabilityIOException) {
                showGooglePlayServicesAvailabilityErrorDialog(
                        ((GooglePlayServicesAvailabilityIOException) mLastError)
                                .getConnectionStatusCode());
            } else if (mLastError instanceof UserRecoverableAuthIOException) {
                startActivityForResult(
                        ((UserRecoverableAuthIOException) mLastError).getIntent(),
                        Door5.REQUEST_AUTHORIZATION);
            } else {
                mOutputText.setText("The following error occurred:\n"
                        + mLastError.getMessage());
            }
        } else {
            mOutputText.setText("Request cancelled.");
        }
    }
}

}

这是我的build.gradle文件

    apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.1"
    configurations.all {
        resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'
    }
    defaultConfig {
        applicationId "com.example.kriti.kidharhai"
        minSdkVersion 16
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.0.1'

    //Added for firebase and Sheets
    compile 'com.google.firebase:firebase-core:11.4.0'    
    compile 'com.google.firebase:firebase-database:11.4.0'
    compile 'com.google.android.gms:play-services-auth:11.4.0'
    compile 'pub.devrel:easypermissions:0.3.0'
    testCompile 'junit:junit:4.12'

    compile('com.google.api-client:google-api-client-android:1.23.0') {
        exclude group: 'org.apache.httpcomponents'
    }
    compile('com.google.apis:google-api-services-sheets:v4-rev506-1.23.0') {
        exclude group: 'org.apache.httpcomponents'
    }
    //For drive

    compile 'com.google.android.gms:play-services-drive:11.4.0'
    compile 'com.google.android.gms:play-services:11.4.0'
    compile 'com.google.api-client:google-api-client-xml:1.18.0-rc'
    compile 'com.google.http-client:google-http-client-gson:1.18.0-rc'
    compile 'com.google.api-client:google-api-client-android:1.18.0-rc'
    compile 'com.google.apis:google-api-services-drive:v2-rev155-1.19.0'
    compile 'com.android.support.test.espresso:espresso-core:2.2.2'
}
apply plugin: 'com.google.gms.google-services'

AndroidManifest.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.kriti.kidharhai">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".Door1"
            android:parentActivityName=".MainActivity"></activity>
        <activity
            android:name=".Door2"
            android:parentActivityName=".MainActivity"></activity>
        <activity
            android:name=".Door3"
            android:parentActivityName=".Door1"></activity>
        <activity
            android:name=".Door4"
            android:parentActivityName=".Door1"></activity>
        <activity
            android:name=".Door5"
            android:parentActivityName=".Door2"></activity>
        <activity
            android:name=".door6"
            android:parentActivityName=".Door2"></activity>

        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value=".MainActivity" />

    </application>

</manifest>

3 个答案:

答案 0 :(得分:4)

问题是getdriveresourceclient函数是一个内部项目函数。

protected DriveResourceClient getDriveResourceClient() {
        return mDriveResourceClient;
    }

而mDriveResourceClient是

mDriveResourceClient = Drive.getDriveResourceClient(getApplicationContext(), signInAccount);

所有都可以在以下链接中找到:

https://github.com/gsuitedevs/drive-android-demos/blob/71105dc51d466d4892e3798fcaa8cdde06e34a07/app/src/main/java/com/google/android/gms/drive/sample/demo/BaseDemoActivity.java

最佳,

答案 1 :(得分:0)

在我看来,您可能尚未导入modules/package。无论如何,有关创建文件的完整代码示例,请参阅Drive API Android: Create a File

答案 2 :(得分:0)

尝试导入这些文件

isActive

您需要客户端才能访问云端硬盘资源