Java – Android / Google drive image upload

First of all, I'm a French student. Please forgive my English

I've launched a photo app, and now I hope it can save these photos on Google drive I followed the Google tutorial. Now I have an error I can't explain. I don't know how to solve it:

400 error request {"code": 400, "error": [{"domain name": "global", "location": "fields", "locationtype": "parameters", "message": "invalid field selection", "reason": "invalidparameter"}], "message": "invalid field selection"}]

This link may help https://developers.google.com/drive/v3/web/handle-errors , even if I really don't understand how it helps

Of course, I did everything Google asked: https://developers.google.com/drive/quickstart/android

This is a wrong activity

I hope you can understand my problem. If you do this and help solve it, I just need to say thank you (even if you have just finished reading)

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
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.*;

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.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.text.method.ScrollingMovementMethod;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import com.google.api.client.json.gson.GsonFactory;

public class DriveActivity extends Activity {
GoogleAccountCredential mCredential;
private TextView mOutputText;
ProgressDialog mProgress;

static final int REQUEST_ACCOUNT_PICKER = 1000;
static final int REQUEST_AUTHORIZATION = 1001;
static final int REQUEST_GOOGLE_PLAY_SERVICES = 1002;
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);

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

    mOutputText = new TextView(this);
    mOutputText.setLayoutParams(tlp);
    mOutputText.setPadding(16,16);
    mOutputText.setVerticalScrollBarEnabled(true);
    mOutputText.setMovementMethod(new ScrollingMovementMethod());
    activityLayout.addView(mOutputText);

    mProgress = new ProgressDialog(this);
    mProgress.setMessage("Connexion Google Drive ...");

    setContentView(activityLayout);

    // Initialize credentials and service object.
    SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
    mCredential = GoogleAccountCredential.usingOAuth2(
            getApplicationContext(),Arrays.asList(SCOPES))
            .setBackOff(new ExponentialBackOff())
            .setSelectedAccountName(settings.getString(PREF_ACCOUNT_NAME,null));
}


/**
 * Called whenever this activity is pushed to the foreground,such as after
 * a call to onCreate().
 */
@Override
protected void onResume() {
    super.onResume();
    if (isGooglePlayServicesAvailable()) {
        refreshResults();
    } else {
        mOutputText.setText("Google Play Services requièrent: " +
                "après l'installation,fermer et relancer l'app.");
    }
}

/**
 * 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) {
                isGooglePlayServicesAvailable();
            }
            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) {
                    mCredential.setSelectedAccountName(accountName);
                    SharedPreferences settings =
                            getPreferences(Context.MODE_PRIVATE);
                    SharedPreferences.Editor editor = settings.edit();
                    editor.putString(PREF_ACCOUNT_NAME,accountName);
                    editor.apply();
                }
            } else if (resultCode == RESULT_CANCELED) {
                mOutputText.setText("Compte non spécifié.");
            }
            break;
        case REQUEST_AUTHORIZATION:
            if (resultCode != RESULT_OK) {
                chooseAccount();
            }
            break;
    }

    super.onActivityResult(requestCode,data);
}

/**
 * Attempt to get a set of data from the Drive API to display. If the
 * email address isn't kNown yet,then call chooseAccount() method so the
 * user can pick an account.
 */
private void refreshResults() {
    if (mCredential.getSelectedAccountName() == null) {
        chooseAccount();
    } else {
        if (isDeviceOnline()) {
            new MakeRequestTask(mCredential).execute();
        } else {
            mOutputText.setText("Pas de connexion internet.");
        }
    }
}

/**
 * Starts an activity in Google Play Services so the user can pick an
 * account.
 */
private void chooseAccount() {
    startActivityForResult(
            mCredential.newChooseAccountIntent(),REQUEST_ACCOUNT_PICKER);
}

/**
 * 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. Will
 * launch an error dialog for the user to update Google Play Services if
 * possible.
 * @return true if Google Play Services is available and up to
 *     date on this device; false otherwise.
 */
private boolean isGooglePlayServicesAvailable() {
    final int connectionStatusCode =
            GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
    if (GooglePlayServicesUtil.isUserRecoverableError(connectionStatusCode)) {
        showGooglePlayServicesAvailabilityErrorDialog(connectionStatusCode);
        return false;
    } else if (connectionStatusCode != ConnectionResult.SUCCESS ) {
        return false;
    }
    return true;
}

/**
 * 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) {
    Dialog dialog = GooglePlayServicesUtil.getErrorDialog(
            connectionStatusCode,DriveActivity.this,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;

    public MakeRequestTask(GoogleAccountCredential credential) {
        HttpTransport transport = AndroidHttp.newCompatibleTransport();
        JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
        mService = new com.google.api.services.drive.Drive.Builder(
                transport,jsonFactory,credential)
                .setApplicationName("AthexisPics")
                .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()
                .setPageSize(10)
                .setFields("nextPageToken,items(id,name)")
                .execute();
        List<File> files = result.getFiles();
        if (files != null) {
            for (File file : files) {
                fileInfo.add(String.format("%s (%s)\n",file.getName(),file.getId()));
            }
        }
        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("Pas de résultats trouvés.");
        } else {
            output.add(0,"Données récupérées:");
            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(),DriveActivity.REQUEST_AUTHORIZATION);
            } else {
                mOutputText.setText("L'erreur suivante vient de se produire:\n"
                        + mLastError.getMessage());
            }
        } else {
            mOutputText.setText("Requête annulée.");
        }
    }
}
}

Solution

Man, I see!

When running the sample code of rest API for drive in Android, the same error message is displayed to me

The error message "invalid field selection" indicates that the API does not recognize the field item ' In fact, you must change the field name in the API code without changing the sample code (bad Google)

So in your code, not this line:

setFields("nextPageToken,name)")

Try this row with the changed field name:

setFields("nextPageToken,files(id,name)")

In addition to the project < -- > file, the title (given in online DOCS) < -- > name

Again, bad Google

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>