Interacting with Google Tasks on Android

Since I’ve been playing with Google Tasks, I wanted to look at my task from my Android phone. Sadly, all the application I could find were using a lot more permissions than I like to give. Therefore, I decided to look into why all these permissions are needed. This will be a little tutorial on interacting with Google Tasks on Android.

Disclaimer: I have not yet published an application using this, so it is possible that something is missing. I will update this post as soon as I have more information (or remove this disclaimer if nothing more is needed).

Project Setup

There are two basic files that need modification in order to be able to use Google Tasks on Android.

The first files you need to modify is the AndroidManifest.xml file. You will need to add the android.permission.INTERNET by adding the following line:

This permission is used to allow your application to connect to the Internet.

The second file that needs modification is the app/build.gradle file. Adding the following lines to this file will add the needed libraries to your project’s dependencies:

Do note that I had to force the version of com.google.code.findbugs:jsr305 in order to fix a dependency issue.

Google API Setup

Configuring the Google Backend services for Android is a little bit different from doing so for desktop applications. I already did a quick tutorial on doing the configuration for Android here.

Handling the user’s credentials

In order to get the user’s credentials, you will need to ask for his permission. I went the easy route and asked directly for read/write access to Google Tasks, but you can get the list of scopes that can be used here. In order to be able to get the user’s token, you need to add the requestEmail permission.

Basically, the way the permission flow works is:

  1. Build a sign-in intent (with the desired permissions);
  2. Ask the system to fulfill the intent and wait for the response;
  3. Process the response

The code is quite straightforward:

Initializing the Google Tasks API

In order to initialize the Google Tasks API, you will need 3 things:

  • A JSONFactory
    I went with an instance of com.google.api.client.json.jackson2.JacksonFactory simply because it was there and worked
  • HttpTransport
    Depending on the Android version you are targeting, you must use a different class. Using AndroidHttp.newCompatibleTransport() makes this selection transparent.
  • The user’s credentials

Interacting with Google Tasks on Android

Once you got the Tasks Service in your hands, interacting with it is the same as doing so in Java. Since I’ve been using API 23, I can’t use streams like I used in my java example. Therefore, I did two little helpers ( TaskList findTaskList(TaskLists tasklists, String title)  and Task findTask(Tasks tasks, String title)).

Creating a task list

Finding a task list

Creating a task

Finding a task

Updating a task

Completing a task

Handling a large number of return values

Like any good online service, Google Tasks API handles a large number of values using pagination. By default, most APIs will return a maximum of 100 results. You are allowed to change this value, but in order to get good performance, you should not put it bigger.

Basically, the way to handle pagination is: do your normal call, check if you got a page token and if you do you know there are more results waiting. You can then call the API again with the page token in order to get the next result set:

Sources

Interacting with Google Tasks using Java

I already did a post giving an overview of interacting with Google Tasks using Ruby, but with the change in scope of my project, I now need to do the same in Java. Therefore, here is an overview of interacting with Google Tasks using Java. Do note that this probably won’t work on Android, it is meant to be used from Java Desktop editions.

Project Setup

Using gradle, the project setup is quite simple:

Google API Setup

In order to access Google Tasks using Java, you will need to use Google’s OAuth. Google’s OAuth uses what they call client secrets file. These files contain all the information needed to access the selected services.

To get a client secrets file, you can follow my other post.

Handling the user’s credentials

This project is my first Java project since a long time ago. I quickly remembered how painful it can be to play with the interface/abstract class hell. You have to instantiate 20 different things before calling anything and selecting the right implementation, or even simply finding an implementation, is sometimes tricky. Here, I selected the following implementations:

  • JsonFactory: com.google.api.client.json.jackson2.JacksonFactory, it was there and worked, so I used it;
  • HttpTransportcom.google.api.client.http.javanet.NetHttpTransport, according to the API’s documentation “NetHttpTransport is based on the HttpURLConnection built into the Java SDK, so it is normally the preferred choice“;
  • DataStoreFactorycom.google.api.client.util.store.FileDataStoreFactory, this implementation will store the tokens in a file (Ok … multiple files …). In my case, it will be in a directory called tokens in the current working directory;

Here is the authentication code I used. It will take care of caching the tokens, opening the browser if a new token is needed and getting the result token.

Initializing the Google Tasks API

In order to use the Google Tasks API, you need to build the service. Doing so requires most of the things that were initialized in the previous section:

Interacting with Google Tasks using Java

Creating a task list

Once you have all the boilerplate done for the initialization of the API and the service, creating a tasklist becomes quite easy:

Finding a task list

The Google Tasks API only allows you to search by tasklist ID, not a title. This ID is automatically generated and therefore not really easy to use. The easiest way to find a task list is to list all task lists and find the one you are looking for in there:

Creating a task

In order to create a task, you first need a tasklist. Once you got that, creating the task is easy enough:

Finding a task

Just like finding a tasklist, you can’t directly search by task title. Therefore, you need to go iterate over the full list to find the one you are looking for:

Updating a task

Once you have a task (and a tasklist) in your hands, updating most of its fields can be done directly on the Task instance. The following example updates the due date of a task:

Completing a task

Just like updating a task, completing it is quite easy: set its status field to completed:

Handling a large number of return values

Like any good online service, Google Tasks API handles a large number of values using pagination. By default, most APIs will return a maximum of 100 results. You are allowed to change this value, but in order to get good performance, you should not put it bigger.

Basically, the way to handle pagination is: do your normal call, check if you got a page token and if you do you know there are more results waiting. You can then call the API again with the page token in order to get the next result set:

 

Sources

Interacting with Google Tasks using Ruby

On the first iteration of a project of mine, I wanted to access Google Tasks using Ruby. Therefore, I did a little bit of tinkering with using the Google Tasks API using Ruby. In this post, I will go over your project’s setup, the Google backend setup and the basic usage of the API.

Project Setup

All of the Google Tasks APIs are basically REST endpoints. One could simply call all these HTTP endpoints manually, but this would be painful. I decided to use google-api-client to do all the heavy lifting. In order to include it in your project, simply add the following to your Gemfile:

Google API Setup

In order to access Google Tasks using Ruby, you will need to use Google’s OAuth. Google’s OAuth uses what they call client secrets file. These files contain all the information needed to access the selected services.

To get a client secrets file, you can follow my other post.

Handling the user’s credentials

The way the Google APIs work, an URL will be provided to you. Opening that URL and grabbing the authentication token is all on you. Therefore, there is three consideration when handling the user’s credential:

  1. Storing the credentials (so that you don’t ask access every time);
  2. Showing the consent webpage;
  3. Grabbing the authentication token;

For this quick test, I decided to use a file storage for the token. The FileTokenStore token store will simply use a YAML file to store the user’s tokens. To show the consent webpage, I went with launchy. This cross-platform library will handle opening URLs in the default browser and such. Finally, I decided to basically do nothing to grab the token: I expect the user to paste it on the command line.

Initializing the Google Tasks API

Now that you have the user’s credentials, you can initialize the API you want to use. In my case, this is the task API. In order to do so, simply create a new instance of the service you want to use (Google::Apis::TasksV1::TasksService) and set its authorization member to the credentials you got from the client.

Interacting with Google Tasks using Ruby

Creating a task list

The tasklist is basically a grouping of tasks. It is the root concept of Google Tasks. Creating one is quite straightforward:

Finding a task list

The Google Tasks API only allows you to search by tasklist ID, not a title. This ID is automatically generated and therefore not really easy to use. The easiest way to find a task list is to list all task lists and find the one you are looking for in there:

Creating a task

Creating a simple task, at the top of the task list is quite straightforward:

Finding a task

Just like finding a task list, finding a task by its title can’t be done directly through the API. In order to do so, you need to iterate over the tasks and check them:

Updating a task

Once you have your hand on the task you want to update, simply update the field you want to update and call update_task:

Completing a task

Completing a task is done by setting its status to “completed” and updating the task:

Handling a large number of return values

Google’s Task API uses pagination in order to handle a large number of return values. By default, a maximum of 100 return values will be returned by calls to list_tasklists and list_tasks. The return values of these two APIs will contain a next_page_token value. You can then use this token in a subsequent call to the API specifying the optional argument page_token in order to get another set of return values.

Here is a quick example of handling of pagination with the list_tasks call. Do note that in this example, I set the max_results value in the call so that I do not have to create 100+ tasks.

Sources

Fix Eclipse not finding javax.annotation

I recently started playing with Java again and I had to get up to date with the recent tooling. Gradle was my first target. While playing with it, I got really annoyed at some point: I had a working Gradle build, but Eclipse was telling me that it could not find javax.annotation.CheckForNull and a few other friends. Here is how to fix Eclipse not finding javax.annotation.

In my case, some generated code I was using needed @Nonnull and @CheckForNull. Both of these were introduced in JSR-305 (aka Annotations for Software Defect Detection).

Step 1 – Ensure that you have the library

The easiest implementation I could find was the one shipped with FindBugs (com.google.code.findbugs:jsr305). In order to include this dependency into your project, simply modify your build.gradle file to add the following:

 

In my specific case, I was already using org.anarres.gradle:gradlesablecc-plugin:1.0.4, and this already requires jsr305. Therefore, I did not have to manually add it.

 

Figure 1: Gradle dependencies output

In order to validate your dependency, you can get the dependency tree from Gradle. To do so, get a command prompt open in your project root directory. In there, simply run: .\gradlew.bat dependencies –configuration testCompileClasspath. Since I am using other dependencies, the output from this command in my project is what is shown in figure 1.

 

Step 2 – Refresh your Eclipse project

This step is where I lost quite a bit of time …

If you are using Eclipse Buildship, you can refresh the project by simply right-clicking it, and in the menu hit Gradle->Refresh Gradle Project. This will update your Eclipse project to ensure that all classpath setting and other stuff is valid.

Sources

Fix Gradle Eclipse task ignoring JAVA_HOME

I started playing with Java again recently and lost quite a bit of time fixing a stupid issue: when running a Gradle task from Eclipse, Gradle was ignoring JAVA_HOME environment variable. Here is how I fixed that issue.

The issue

When installing Java 8, I decided to install both the JRE and the JDK (in that order). Looks like Java now creates a symlink from C:\ProgramData\Oracle\Java\javapath to your Java bin directory and puts that as the first entry in the PATH environment variable. Doing so makes your first Java installation be your default installation.

I could not find a clean way to modify this behavior or to change the path in C:\ProgramData\Oracle\Java\javapath. Yeah, sure, I could simply modify it or remove it from the path, but without being certain that it won’t break anything I did not want to change it.

As a second issue, it looks like Eclipse ignores the Gradle wrapper (gradlew.bat on windows) or eats the environment variable. If it was using the wrapper, you’d be able to change the Java used by using the JAVA_HOME environment variable.

The fix

I decided to go the easy route and simply add my java installation into the path (as the first entry). I really don’t like this solution, it pollutes my path and prevents me from easily switching. I’ll continue to investigate why Eclipse eats the configuration and update this post (or link to a new one) once I get something cleaner.

Sources