Search code examples
androidgoogle-calendar-apigoogle-oauth

Google Calendar API on Android access token


I want to query and add events to the primary calendar of a user that is already logged into the app (with his/her/its' google account).

I have come this far:

class CalendarClient {
    private static final String APPLICATION_NAME = "TrackTransfer";
    private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

    private final String token;

    CalendarClient (String token){
        this.token = token;
    }

    private Credential getCredentials() {
        return new GoogleCredential().setAccessToken(token);
    }

    void print() throws IOException {
        // Build a new authorized API client service.
        final NetHttpTransport HTTP_TRANSPORT = new com.google.api.client.http.javanet.NetHttpTransport();
        Calendar service = new Calendar.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials())
                .setApplicationName(APPLICATION_NAME)
                .build();

        // List the next 10 events from the primary calendar.
        DateTime now = new DateTime(System.currentTimeMillis());
        Events events = service.events().list("primary")
                .setMaxResults(10)
                .setTimeMin(now)
                .setOrderBy("startTime")
                .setSingleEvents(true)
                .execute();
        List<Event> items = events.getItems();
        if (items.isEmpty()) {
            System.out.println("No upcoming events found.");
        } else {
            System.out.println("Upcoming events");
            for (Event event : items) {
                DateTime start = event.getStart().getDateTime();
                if (start == null) {
                    start = event.getStart().getDate();
                }
                System.out.printf("%s (%s)\n", event.getSummary(), start);
            }
        }
    }

}

and I call it like this from an activity where the user is already signed in and the signed in account is represented by account.

private void writeToCalendar()  {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Log.d("CAL", "token: " + account.getIdToken());
                CalendarClient c = new CalendarClient(account.getIdToken());
                c.print();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }).start();

}

However, the account.getIdToken() is Null even though the user is signed in. I also tried setting the token to the client-ID that I get for my application in the google developer console, which doesn't work either.

Naturally when the token is Null I get an exception stating that the contingent for non-signed in api calles is exceeded.

Accessing the Fitness API just before the call of writeToCalendar() wasn't a problem with that account (so it is signed in).

I have looked at various resources, but neither proved helpful. The Google API documentation was about Java and used the credentials obtained from the developer console; however as I want to authenticate using OAuth, this is not the right thing to do (i guess?). Then I found that one can use GoogleCredential().setAccessToken(token) but I couldn't figure out what token is used.

How do I obtain the correct token?

Update

When requesting scopes for the account to be logged in, it is straight forward with the fitness api:

FitnessOptions fitnessOptions = FitnessOptions.builder()
                .addDataType(DataType.TYPE_DISTANCE_DELTA, FitnessOptions.ACCESS_READ)
                .addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
                .build();
GoogleSignInAccount gsa = GoogleSignIn.getAccountForExtension(this, fitnessOptions);

with a callback that looks something like this:

account = completedTask.getResult(ApiException.class);

However, when requesting a scope for the calendar api is the following correct?

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .requestScopes(new Scope("https://www.googleapis.com/auth/calendar"))
                .build();
GoogleSignInClient tempClient = GoogleSignIn.getClient(this, gso);

Solution

  • Sign in

    sign in

    I also found this, you may need to use oauth before the api gives you an access token:

    auth

    Then I would check to see if its one of the api's you need to enable a billing account for. It might be. That does not mean you need to pay...depending on the api google makes you 'enable' billing. Not sure if the this api is one of those.

    info