3

I seem to be failing to authorize using OAuth2.0 while trying to insert and event within Google Calendar using the Google Calendar API.

The issue seems to be taking place somewhere within this block of code for some reason, and ends up throwing an exception which is caught in GoogleAuthException. It is also worth noting that if I remove the try/catch block, it will successfully get to the event.insert in CreateCalenderEventTask (which is later being called) but will be caught by UserRecoverableAuthIOException instead.

    try {
        // If the application has the appropriate access then a token will be retrieved, otherwise
        // an error will be thrown.
        mCredential = GoogleAccountCredential.usingOAuth2(mActivity,
                                                                                                            Arrays.asList(GoogleCalendarUtils.SCOPES));
        mCredential.setSelectedAccountName(emailAccount);
        String accessToken = mCredential.getToken();
        Log.e(TAG, "ACCESS TOKEN" + accessToken);
        // Success.
        return true;
    } catch (GoogleAuthException unrecoverableException) {
        // Failure.
        Log.e(TAG, "UNRECOVERABLE: " + Log.getStackTraceString(unrecoverableException));
        return false;
    } catch (IOException ioException) {
        // Failure or cancel request.
        Log.e(TAG, "IO EXCEPTION: " + Log.getStackTraceString(ioException));
        return false;
    }

GoogleCalendarUtils - Using this class to handle async requests for OAUTH and Event insert

public class GoogleCalendarUtils {

    private static String TAG = GoogleCalendarUtils.class.getCanonicalName();

    //CALENDAR REQUEST
    public static final int REQUEST_ACCOUNT_PICKER = 1000;
    public static final int REQUEST_AUTHORIZATION = 1001;
    public static final int REQUEST_GOOGLE_PLAY_SERVICES = 1002;
    public static final String PREF_ACCOUNT_NAME = ""; //possibly retrieve this data from the server, or store your preferred account in shared prefs
    public static final String[] SCOPES = { CalendarScopes.CALENDAR };

    public static final JsonFactory JSON_FACTORY = new AndroidJsonFactory();
    public static final HttpTransport HTTP_TRANSPORT = AndroidHttp.newCompatibleTransport();
    private static AuthorizationCheckTask mAuthTask;
    public static GoogleAccountCredential mCredential = null;

    public static Calendar getCalendarServiceHandle(@Nullable GoogleAccountCredential credential) {
        return new Calendar.Builder(
                                                                HTTP_TRANSPORT, JSON_FACTORY, credential).build();
    }

    public static int countGoogleAccounts(Context context) {
        AccountManager am = AccountManager.get(context);
        Account[] accounts = am.getAccountsByType(GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE);
        if (accounts == null || accounts.length < 1) {
            return 0;
        } else {
            return accounts.length;
        }
    }

    public static ArrayList<Account> getGoogleAccounts(Context context) {
        AccountManager am = AccountManager.get(context);
        Account[] accounts = am.getAccountsByType(GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE);
        ArrayList<Account> accountArray = new ArrayList<Account>();
        for (Account acct : accounts) {
            accountArray.add(acct);
        }

        return accountArray;
    }

    public static boolean checkGooglePlayServicesAvailable(Activity activity) {
        final int connectionStatusCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(activity);
        if (GooglePlayServicesUtil.isUserRecoverableError(connectionStatusCode)) {
            showGooglePlayServicesAvailabilityErrorDialog(activity, connectionStatusCode);
            return false;
        }
        return true;
    }

    public static void showGooglePlayServicesAvailabilityErrorDialog(final Activity activity,
                                                                                                                                        final int connectionStatusCode) {
        final int REQUEST_GOOGLE_PLAY_SERVICES = 0;
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Dialog dialog = GooglePlayServicesUtil.getErrorDialog(
                                                                                                                            connectionStatusCode, activity,
                                                                                                                            REQUEST_GOOGLE_PLAY_SERVICES);
                dialog.show();
            }
        });
    }

    public static class CreateCalendarEventTask extends AsyncTask<Void, Void, Void> {
        private Calendar mService = null;
        Reservation reservation = null;

        public CreateCalendarEventTask(GoogleAccountCredential credential, Reservation res) {
            if (res != null) {
                this.reservation = res;
            }
            mService = getCalendarServiceHandle(credential);
        }

        @Override
        protected Void doInBackground(Void... params) {
            createCalendarEvent();
            return null;
        }

        @Override
        protected void onCancelled() {}

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
        }

        private void createCalendarEvent() {
            Event event = new Event()
                                                                .setSummary("TEST EVENT 11/7/2015")
                                                                .setLocation("800 Howard St., San Francisco, CA 94103")
                                                                .setDescription("A chance to hear more about Google's developer products.");

            Log.e(TAG, reservation.getReqDatetime().toString());

            DateTime startDateTime = new DateTime("2015-11-07T09:00:00-07:00");
            EventDateTime start = new EventDateTime()
                .setDateTime(startDateTime)
                .setTimeZone("America/Los_Angeles");
            event.setStart(start);

            DateTime endDateTime = new DateTime("2015-11-07T17:00:00-07:00");
            EventDateTime end = new EventDateTime()
                .setDateTime(endDateTime)
                .setTimeZone("America/Los_Angeles");
            event.setEnd(end);

            String calendarId = "primary";
            try {
                Log.e(TAG, "ABOUT TO INSERT THE EVENT");
                event = mService.events().insert(calendarId, event).execute();
            } catch (UserRecoverableAuthIOException e1) {
                Log.e(TAG, Log.getStackTraceString(e1));
            } catch (IOException e) {}
        }
    }

    public static void performAuthCheck(Activity activity, String emailAccount, AuthorizationCheckCallback callback) {
        // Cancel previously running tasks.
        if (mAuthTask != null) {
            try {
                mAuthTask.cancel(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        new AuthorizationCheckTask(activity, callback).execute(emailAccount);
    }

    public static class AuthorizationCheckTask extends AsyncTask<String, Integer, Boolean> {

        Activity mActivity;
        AuthorizationCheckCallback mCallback;

        public AuthorizationCheckTask(Activity activity, AuthorizationCheckCallback callback) {
            this.mActivity = activity;
            this.mCallback = callback;
        }

        @Override
        protected Boolean doInBackground(String... emailAccounts) {

            if (!checkGooglePlayServicesAvailable(mActivity)) { return false; }

            String emailAccount = emailAccounts[0];
            // Ensure only one task is running at a time.
            mAuthTask = this;

            // Ensure an email was selected.
            if (Strings.isNullOrEmpty(emailAccount)) {
                // Failure.
                return false;
            }

            try {
                // If the application has the appropriate access then a token will be retrieved, otherwise
                // an error will be thrown.
                mCredential = GoogleAccountCredential.usingOAuth2(mActivity,
                                                                                                                    Arrays.asList(GoogleCalendarUtils.SCOPES));
                mCredential.setSelectedAccountName(emailAccount);
                String accessToken = mCredential.getToken();
                Log.e(TAG, "ACCESS TOKEN" + accessToken);
                // Success.
                return true;
            } catch (GoogleAuthException unrecoverableException) {
                // Failure.
                Log.e(TAG, "UNRECOVERABLE: " + Log.getStackTraceString(unrecoverableException));
                return false;
            } catch (IOException ioException) {
                // Failure or cancel request.
                Log.e(TAG, "IO EXCEPTION: " + Log.getStackTraceString(ioException));
                return false;
            }
        }

        @Override
        protected void onPostExecute(Boolean success) {
            if (success) {
                // Authorization check successful, set internal variable.
                mCallback.onSuccess(mCredential);
            } else {
                // Authorization check unsuccessful.
                mCallback.onFailure();
            }
            mAuthTask = null;
        }

        @Override
        protected void onCancelled() {
            mAuthTask = null;
        }

        public interface AuthorizationCheckCallback {
            void onSuccess(GoogleAccountCredential credential);

            void onFailure();
        }
    }
}

STACK TRACE:

    11-06 15:11:47.502: E/com.limosys.jlimomapprototype.utils.google.GoogleCalendarUtils(13925): com.google.android.gms.auth.UserRecoverableAuthException: NeedPermission
    11-06 15:11:47.502: E/com.limosys.jlimomapprototype.utils.google.GoogleCalendarUtils(13925):    at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
    11-06 15:11:47.502: E/com.limosys.jlimomapprototype.utils.google.GoogleCalendarUtils(13925):    at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
    11-06 15:11:47.502: E/com.limosys.jlimomapprototype.utils.google.GoogleCalendarUtils(13925):    at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential.getToken(GoogleAccountCredential.java:255)
    11-06 15:11:47.502: E/com.limosys.jlimomapprototype.utils.google.GoogleCalendarUtils(13925):    at com.limosys.jlimomapprototype.utils.google.GoogleCalendarUtils$AuthorizationCheckTask.doInBackground(GoogleCalendarUtils.java:198)
    11-06 15:11:47.502: E/com.limosys.jlimomapprototype.utils.google.GoogleCalendarUtils(13925):    at com.limosys.jlimomapprototype.utils.google.GoogleCalendarUtils$AuthorizationCheckTask.doInBackground(GoogleCalendarUtils.java:1)
    11-06 15:11:47.502: E/com.limosys.jlimomapprototype.utils.google.GoogleCalendarUtils(13925):    at android.os.AsyncTask$2.call(AsyncTask.java:288)
    11-06 15:11:47.502: E/com.limosys.jlimomapprototype.utils.google.GoogleCalendarUtils(13925):    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    11-06 15:11:47.502: E/com.limosys.jlimomapprototype.utils.google.GoogleCalendarUtils(13925):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
    11-06 15:11:47.502: E/com.limosys.jlimomapprototype.utils.google.GoogleCalendarUtils(13925):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    11-06 15:11:47.502: E/com.limosys.jlimomapprototype.utils.google.GoogleCalendarUtils(13925):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    11-06 15:11:47.502: E/com.limosys.jlimomapprototype.utils.google.GoogleCalendarUtils(13925):    at java.lang.Thread.run(Thread.java:818)
Coova
  • 1,818
  • 5
  • 36
  • 63
  • You don't have any error message that could help us helping you? Can't you print the stack trace of the exception? – dguay Nov 05 '15 at 21:14
  • I just got it. It is in the question now. – Coova Nov 05 '15 at 21:42
  • Catch `UserRecoverableAuthIOException` and print `exception.getIntent()`. Also take a look here: http://stackoverflow.com/questions/17428066/no-intent-from-userrecoverableauthioexception-using-drive-sdk-for-android – dguay Nov 05 '15 at 21:50
  • I am still receiving the exact same error. I added the UserRecoverableAuthIOException as a catch, but it still results in the same issue. – Coova Nov 05 '15 at 22:00
  • Check [this](http://stackoverflow.com/a/14386248/562840) answer, it is for drive, but the error is the same. – Mikel Nov 06 '15 at 15:14
  • I have all that setup properly. I think the issue is with oAuth2.0, perhaps I didnt set that up right. – Coova Nov 06 '15 at 18:23

0 Answers0