在Google API中申请授权

时间:2016-09-19 13:12:54

标签: java android authorization google-api-java-client scopes

我使用Google-API从Google-Calender获取未读电子邮件和一些事件的数量。我使用了谷歌的快速入门示例代码并且工作正常(如果没有设置请求范围权限等)。因此,我将其形成为服务和Auth-Activity,以便用户更改其帐户。我的问题是用户不再被要求授权。该应用程序仍然使用正确的帐户,如果我选择一个授权我的应用程序的帐户,它仍然有效,但如果我选择一个新帐户,则不会显示授权表单。

Google AuthUtil错误:

09-19 13:13:54.114: D/DEBUG_TEST(7072): ERROR: UserRecoverableErrorNeedPermission

这是我更改帐户的活动。每当用户选择Google帐户时,静态变量" gAccountDaten"(GoogleAccountCredential对象)都会更新。

import android.accounts.AccountManager;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;

import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.util.ExponentialBackOff;
import com.google.api.services.calendar.CalendarScopes;
import com.google.api.services.gmail.GmailScopes;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

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



public class GoogleAuthActivity extends Activity implements EasyPermissions.PermissionCallbacks {
    static GoogleAccountCredential gAccountDaten;

    static final int REQUEST_GOOGLE_PLAY_SERVICES = 1002;
    static final int REQUEST_ACCOUNT_PICKER = 1000;
    static final int REQUEST_AUTHORIZATION = 1001;
    static final int REQUEST_PERMISSION_GET_ACCOUNTS = 1003;
    private static final String PREF_ACCOUNT_NAME = "accountName";
    private static final String[] SCOPES = { GmailScopes.GMAIL_LABELS, GmailScopes.GMAIL_READONLY , GmailScopes.MAIL_GOOGLE_COM, CalendarScopes.CALENDAR_READONLY};

    private Boolean verbunden = false;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.googleauthactivitylayout);
        gAccountDaten = GoogleAccountCredential.usingOAuth2(getApplicationContext(), Arrays.asList(SCOPES)).setBackOff(new ExponentialBackOff());




        chooseAccount();

    }



    private String getGoogleAccountNameSettings(){
        String toReturn = getPreferences(Context.MODE_PRIVATE)
                .getString(PREF_ACCOUNT_NAME, null);
        Log.d("ACCOUNT_DEBUG", "FUNC: getGoogleAccountNameSettings --> " + toReturn);

        return toReturn;
    }

    private boolean setGoogleAccountNameSettings(String accountName){
        try{
            SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = settings.edit();
            editor.putString(PREF_ACCOUNT_NAME, accountName);
            editor.apply();
            Log.d("ACCOUNT_DEBUG", "FUNC: setGoogleAccountNameSettings --> " + accountName);
        }catch (Exception exc){
            Log.e("ACCOUNT_DEBUG", "FUNC: setGoogleAccountNameSettings --> ERROR");
            return false;
        }finally {
            Log.e("ACCOUNT_DEBUG", "FUNC: setGoogleAccountNameSettings --> ERROR");
            return true;
        }


    }

    private boolean removeGoogleAccountNameSettings(){
        try{
            SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = settings.edit();
            editor.remove(PREF_ACCOUNT_NAME);
            editor.apply();
            GoogleService.EMAIL_COUNT = 0;
            GoogleService.lstKalender.clear();
            Log.d("ACCOUNT_DEBUG", "FUNC: removeGoogleAccountNameSettings --> " + "rennt");
        }catch (Exception exc){
            Log.e("ACCOUNT_DEBUG", "FUNC: removeGoogleAccountNameSettings --> ERROR");
            return false;
        }finally {
            Log.e("ACCOUNT_DEBUG", "FUNC: removeGoogleAccountNameSettings --> ERROR");
            return true;
        }


    }



    @AfterPermissionGranted(REQUEST_PERMISSION_GET_ACCOUNTS)
    private void chooseAccount( ) {

        removeGoogleAccountNameSettings();
        if (EasyPermissions.hasPermissions(
                this, android.Manifest.permission.GET_ACCOUNTS)) {

            String accountName = getGoogleAccountNameSettings();

            if (accountName != null) {
                gAccountDaten.setSelectedAccountName(accountName);
                this.startService(new Intent(this, GoogleService.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK));
                Log.d("AUTH_DEBUG", "Already authed" +  " | " + gAccountDaten.getScope());

                //finish();
            } else {
                // Start a dialog from which the user can choose an account

                startActivityForResult(
                        gAccountDaten.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 .",
                    REQUEST_PERMISSION_GET_ACCOUNTS,
                    android.Manifest.permission.GET_ACCOUNTS);


        }
    }


    @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) {
                        setGoogleAccountNameSettings(accountName);
                        gAccountDaten.setSelectedAccountName(accountName);
                        Log.d("AUTH_DEBUG", "Authed after Picker -->" + accountName +  " | " + gAccountDaten.getScope());
                        this.startService(new Intent(this, GoogleService.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK));
                        finish();
                    }
                }
                break;
            case REQUEST_AUTHORIZATION:
                if (resultCode == RESULT_OK) {
                    Log.d("AUTH_DEBUG", "started aufter authorization -->" + resultCode +  " | " + gAccountDaten.getScope());
                    this.startService(new Intent(this, GoogleService.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK));
                    finish();
                }
                break;
        }
    }

    /////PERMISSION CALLBACKS


    @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) {
        Log.d("DEBUG_TEST", "NO PERM");
    }



}

这是我的Google服务代码。它将每隔60秒从谷歌api收集信息并将其写入静态变量。

import android.*;
import android.app.Dialog;
import android.app.Service;
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.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.RemoteViews;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
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.calendar.Calendar;
import com.google.api.services.calendar.CalendarScopes;
import com.google.api.services.calendar.model.CalendarList;
import com.google.api.services.calendar.model.CalendarListEntry;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.EventDateTime;
import com.google.api.services.calendar.model.Events;
import com.google.api.services.gmail.GmailScopes;
import com.google.api.services.gmail.model.Label;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

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

public class GoogleService extends Service implements EasyPermissions.PermissionCallbacks{


    GoogleAccountCredential gAccountDaten;

    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 PREF_ACCOUNT_NAME = "accountName";
    static String testj = "";

    static ArrayList<Kalender> lstKalender = new ArrayList<>();
    static int       EMAIL_COUNT = 0;

    //GOOGLE BERECHTIGUNGEN
    private static final String[] SCOPES = { GmailScopes.GMAIL_LABELS, GmailScopes.GMAIL_READONLY , GmailScopes.MAIL_GOOGLE_COM, CalendarScopes.CALENDAR_READONLY};




    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("DEBUG_TEST", "onStartCommand");
        gAccountDaten = GoogleAuthActivity.gAccountDaten;
        if(gAccountDaten == null){
            Log.d("DEBUG_TEST", "gAccountDaten == NULL!");
            return  0;
        }


        getResultsFromApi();
        final Handler handler = new Handler();
        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                getResultsFromApi();
                handler.postDelayed(this, 60000);
            }
        };
        handler.postDelayed(runnable, 60000);





        return START_STICKY;
    }


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {



        return null;
    }

    @Override
    public void onPermissionsGranted(int requestCode, List<String> perms) {

    }

    @Override
    public void onPermissionsDenied(int requestCode, List<String> perms) {

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

    }




    //HELFER FUNKTIONEN
    private void getResultsFromApi() {
        if (! isGooglePlayServicesAvailable()) {
            acquireGooglePlayServices();
        } else if (gAccountDaten.getSelectedAccountName() == null) {
            Log.d("DEBUG_TEST", "ChooseAccount");

        } else if (! isDeviceOnline()) {
            //Gerät Offline

        } else {
            Log.d("DEBUG_TEST", "MakeRequestTask -->" + gAccountDaten.getSelectedAccountName());
            new MakeRequestTask(gAccountDaten).execute();
        }
    }
    //CHECK: GERÄT ONLINE ?
    private boolean isDeviceOnline() {
        ConnectivityManager connMgr =
                (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
        return (networkInfo != null && networkInfo.isConnected());
    }

    //CHECK: GOOGLE SERVICE ONLINE ?
    private boolean isGooglePlayServicesAvailable() {
        GoogleApiAvailability apiAvailability =
                GoogleApiAvailability.getInstance();
        final int connectionStatusCode =
                apiAvailability.isGooglePlayServicesAvailable(this);
        return connectionStatusCode == ConnectionResult.SUCCESS;
    }
    private void acquireGooglePlayServices() {
        GoogleApiAvailability apiAvailability =
                GoogleApiAvailability.getInstance();
        final int connectionStatusCode =
                apiAvailability.isGooglePlayServicesAvailable(this);

    }





    /////////////////////////MAKE REQUEST KLASSE////////////////////////////////////
    private class MakeRequestTask extends AsyncTask<Void, Void, List<String>> {
        private com.google.api.services.gmail.Gmail mService = null;
        private com.google.api.services.calendar.Calendar mServiceKalender = null;


        private Exception mLastError = null;

        public MakeRequestTask(GoogleAccountCredential credential) {

            HttpTransport transport = AndroidHttp.newCompatibleTransport();
            JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();

            HttpTransport transport2 = AndroidHttp.newCompatibleTransport();
            JsonFactory jsonFactory2 = JacksonFactory.getDefaultInstance();


            mService = new com.google.api.services.gmail.Gmail.Builder(
                    transport, jsonFactory, credential)
                    .setApplicationName("Gmail API Android Quickstart")
                    .build();



            mServiceKalender = new com.google.api.services.calendar.Calendar.Builder(
                    transport2, jsonFactory2, credential)
                    .setApplicationName("Google Calendar API Android Quickstart")
                    .build();

            Log.d("DEBUG_TEST", "mService und mServiceKalender Objecte instanzieren --> " + credential.getSelectedAccountName());
        }

        /**
         * Background task to call Gmail 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 Gmail labels attached to the specified account.
         * @return List of Strings labels.
         * @throws IOException
         */
        private List<String> getDataFromApi() throws IOException {
            // Get the labels in the user's account.
            String user = "me";
            List<String> labels = new ArrayList<String>();


            Label label = mService.users().labels().get(user, "INBOX").execute();

            Log.d("DEBUG_TEST", "getDataFromApi() --> " + user );

            //EMAIL_COUNT = label.getMessagesUnread();
            EMAIL_COUNT = label.getMessagesTotal();

            labels.add("E-Mails: " + EMAIL_COUNT);

            lstKalender.clear();
            String pageToken = null;
            do {
                CalendarList calendarList = mServiceKalender.calendarList().list().setPageToken(pageToken).execute();
                List<CalendarListEntry> items = calendarList.getItems();

                for (CalendarListEntry calendarListEntry : items) {
                    String KALENDERNAME = calendarListEntry.getSummary();
                    String KALENDER_ID = calendarListEntry.getId();


                    Kalender neuerKalender = new Kalender();
                    neuerKalender.setKalenderName(KALENDERNAME);
                    neuerKalender.setKalenderId(KALENDER_ID);
                    Log.d("KALENDER_DEBUG", "Kalender: " + KALENDERNAME + "wurde angelegt! ID: " + KALENDER_ID);
                    String pageToken2 = null;
                    do {
                        Events events = mServiceKalender.events().list(KALENDER_ID).setPageToken(pageToken2).execute();
                        List<Event> items2 = events.getItems();
                        for (Event event : items2) {
                            String calName = event.getSummary();
                            EventDateTime calStart = event.getStart();
                            EventDateTime calEnde = event.getEnd();
                            String calLocation = event.getLocation();
                            String calID = event.getId();
                            if(neuerKalender.addEvent(calName,calStart,calEnde,calLocation,calID)){
                                //Log.d("KALENDER_DEBUG", "Event: " + calName + " wurde zum Kalender " + KALENDERNAME + " hinzugefügt!");
                            }

                        }
                        pageToken2 = events.getNextPageToken();


                    } while (pageToken2 != null);
                    lstKalender.add(neuerKalender);

                    Log.d("KALENDER_DEBUG", "Kalender: " + neuerKalender.getKalenderName() + " durchgelaufen und zur Globalen Liste hinzugefügt!");
                }

                pageToken = calendarList.getNextPageToken();
            } while (pageToken != null);


            DaWidgetProvider.updateEventList(getBaseContext());
            UpdateService updateService = new UpdateService();
            updateService.buildUpdate(getBaseContext());
            DaWidgetProvider.updateAllWidgets(getBaseContext());
            return labels;
        }





        @Override
        protected void onPreExecute() {


        }

        @Override
        protected void onPostExecute(List<String> output) {

            if (output == null || output.size() == 0) {
                // mOutputText.setText("No results returned.");
            } else {
                //output.add(0, "Data retrieved using the Gmail API:");
                //mOutputText.setText(TextUtils.join("\n", output));
                //mProgress.dismiss();

                Context mContext = getApplicationContext();





            }
        }

        @Override
        protected void onCancelled() {

            if (mLastError != null) {
                if (mLastError instanceof GooglePlayServicesAvailabilityIOException) {
                    Log.d("DEBUG_TEST", "ERROR: " + mLastError.getMessage());
                } else if (mLastError instanceof UserRecoverableAuthIOException) {
                    Log.d("DEBUG_TEST", "ERROR: UserRecoverableError" + mLastError.getMessage());



                } else {
                    Log.d("DEBUG_TEST", "ERROR: " + mLastError.getMessage());
                }
            } else {
                Log.d("DEBUG_TEST", "abgebrochen");
            }
        }
    }





}

谢谢, J. Doe;)

1 个答案:

答案 0 :(得分:0)

好看,这似乎是问题所在。但我有一个问题要解决它,因为我的Google服务和我的Google帐户选择器活动是不同的。我试图将mLastError传递给我在Intent中的Activity并在那里启动Authentication-Request但是我得到以下错误:

09-19 13:44:18.508: E/AndroidRuntime(7959): java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException)

我的代码在Google服务和GoogleAuthActivity中发生了变化:

谷歌-服务:

protected void onCancelled() {

    if (mLastError != null) {
        if (mLastError instanceof GooglePlayServicesAvailabilityIOException) {
            Log.d("DEBUG_TEST", "ERROR: " + mLastError.getMessage());
        } else if (mLastError instanceof UserRecoverableAuthIOException) {
            Log.d("DEBUG_TEST", "ERROR: UserRecoverableError" + mLastError.getCause().getMessage());
            //KEINE BERECHTIGUNG GESETZT
[代码更改]

Intent startIntent = new Intent(getApplicationContext(),GoogleAuthActivity.class);                 startIntent.putExtra(&#34; auththis&#34;,mLastError);                 startIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                 startActivity(startIntent);

[/代码更改]
        } else {
            Log.d("DEBUG_TEST", "ERROR: " + mLastError.getMessage());
        }
    } else {
        Log.d("DEBUG_TEST", "abgebrochen");
    }
}

GoogleAuthActivity:

//EXTRA DATA???
        if(getIntent().hasExtra("auththis")){

            Intent edIntent = getIntent();
            Bundle extras = edIntent.getExtras();
            UserRecoverableAuthIOException mLastError = null;
            mLastError = (UserRecoverableAuthIOException) extras.get("auththis");
            startActivityForResult(
                    mLastError.getIntent(),
                    GoogleAuthActivity.REQUEST_AUTHORIZATION);
        }else{
            chooseAccount();
        }