Android から"Google Calendar API"を使って、Googleカレンダーに新規カレンダーを追加する

Windows環境を前提として、Android から"Google Calendar API"を使って、Googleカレンダーに新規カレンダーを追加する方法を紹介します。

多くの部分が、以下の内容を元に加筆・修正しています。
- [Android Quickstart  |  Google Calendar API  |  Google Developers](https://developers.google.com/google-apps/calendar/quickstart/android)

# 環境の準備

まず、以下を準備してください。

- JDK 1.8.0 以降
- Android Studio 1.2 以降
- Android SDK Packages
    - Android 6.0 (API 23) 以降
    - 最新版のGoogle Repository
    - 最新版のGoogle Play Services
    - 最新版のAndroid Support Library
- インターネットに接続可能なAndroidデバイス
- Googleカレンダーを使用可能なGoogleアカウント

以降は、下記の環境にて確認を行っています。

> Windows 8.1 (64bit)
> JDK 1.8.0 (Java SE Development Kit 8u101)
> Android Studio 2.2
> Android 7.0 (API 24) Packages
> Google Repository rev.36
> Google Play Services rev.33
> Android Support Library rev.24
> Xperia Z3 Compact (SO-02G) / Android 6.0.1 (Marshmallow)

また、環境変数 Path に以下を追加しておきます。

- JDK 1.8.0 の bin ディレクトリ
    - 例) C:\Program Files\Java\jdk1.8.0_101\bin

なお、%USERPROFILE%で表わされる「C:\Users\ユーザー名」ディレクトリの直下に「.android」ディレクトリが存在するものとします。


# Step 1: SHA1のfingerprintを取得する

JDKに含まれる"Keytool"を使用して、"Google Calendar API"を使用するためにSHA1のfingerprintを取得します。
（"KeyTool"の詳しい使用方法は["アプリケーションへの署名 | Android Developers"](https://developer.android.com/guide/publishing/app-signing.html?hl=ja)などを参照してください）

1. コマンドプロンプトを起動してください
2. 以下を入力してください<br>
```
>  keytool -exportcert -alias androiddebugkey -keystore %USERPROFILE%\.android\debug.keystore -list -v
```
3. パスワードを聞かれたら **android** と入力してください

コマンドプロンプトに、以下のように出力されます。

```
> keytool -exportcert -alias androiddebugkey -keystore %USERPROFILE%\.android\debug.keystore -list -v
キーストアのパスワードを入力してください: android
別名: androiddebugkey
作成日: 2014/12/04
エントリ・タイプ: PrivateKeyEntry
証明書チェーンの長さ: 1
証明書[1]:
所有者: C=US, O=Android, CN=Android Debug
発行者: C=US, O=Android, CN=Android Debug
シリアル番号: 503bd581
有効期間の開始日: Mon Aug 27 13:16:01 PDT 2012終了日: Wed Aug 20 13:16:01 PDT 2042
証明書のフィンガプリント:
         MD5:  1B:2B:2D:37:E1:CE:06:8B:A0:F0:73:05:3C:A3:63:DD
         SHA1: D8:AA:43:97:59:EE:C5:95:26:6A:07:EE:1C:37:8E:F4:F0:C8:05:C8
         SHA256: F3:6F:98:51:9A:DF:C3:15:4E:48:4B:0F:91:E3:3C:6A:A0:97:DC:0A:3F:B2:D2:E1:FE:23:57:F5:EB:AC:13:30
         署名アルゴリズム名: SHA1withRSA
         バージョン: 3
```

上記の"D8:AA:43:97:59:EE:C5:95:26:6A:07:EE:1C:37:8E:F4:F0:C8:05:C8"がSHA1のfingerprintになります。

> production用のアプリの場合には、debug.keystoreの代わりに、production用のkeystoreを指定する必要があります。


# Step 2: Google Calendar API を有効にする

1. 以下のlinkをクリックして、Google Developers Console を開いてください
     - https://console.developers.google.com/start/api?id=calendar
2. 「Google API コンソールで Google Calendar API を有効にするアプリケーションの登録」画面が表示されるので、[同意して続行]/[続行]を押してください
     - ![api1-a.png](https://qiita-image-store.s3.amazonaws.com/0/93531/5541e787-a778-2744-ea5a-89f10f9ab1b9.png)
     -
     - ![api1-b.png](https://qiita-image-store.s3.amazonaws.com/0/93531/46d46e12-368c-45ed-2876-ca63a2cad9ae.png)
3. 「API が有効化されました」画面が表示されるので、**[認証情報に進む]**を押してください
     - ![api2.png](https://qiita-image-store.s3.amazonaws.com/0/93531/7af99708-baad-aaac-5b97-d15b820085ea.png)
4. 「プロジェクトへの認証情報の追加」画面が表示されるで、**[キャンセル]**を押してください
     - ![api3.png](https://qiita-image-store.s3.amazonaws.com/0/93531/fb7d8816-3839-a990-bb25-f182037904c5.png)
5. 画面上部の**[OAuth同意画面]**タブを選択してください
     - ![api4.png](https://qiita-image-store.s3.amazonaws.com/0/93531/008743c9-5d68-cbdd-3bc1-93d4ab3445c6.png)
6. 「OAuth同意画面」で**メールアドレス**と**サービス名**を入力し、**[保存]**を押してください
     - ![api5.png](https://qiita-image-store.s3.amazonaws.com/0/93531/7c679a1f-4a2f-0a28-07c0-1b5a0ae2680e.png)
7. 画面上部の**[認証情報]**タブを選択してください
8. [認証情報を作成]を押し、**[OAuthクライアントID]**を選択してください
     - ![api6.png](https://qiita-image-store.s3.amazonaws.com/0/93531/6efda3c7-fa6a-eedc-a199-706eeef79aaa.png)
9. 「クライアントIDの作成」画面が表示されるので、以下を入力し、**[作成]**を押してください
     - アプリケーションの種類:  **Android**
     - 名前: Calendar Quick Start (OAuthクライアントIDの管理用の名前)
     - 署名証明書フィンガープリント: **Step 1 で取得した SHA1 fingerprint の値**
     - パッケージ名: **com.example.calendarquickstart**
     - ![api7.png](https://qiita-image-store.s3.amazonaws.com/0/93531/f35fb242-1c8d-cb90-a732-30096bbab0f9.png)

# Step 3: Android のプロジェクトを新規に作成する

1. Android Studioを起動し、**"Start a new Android Studio project"**を選択してください
    - 既に別のprojectを開いている場合にはメニューバーから [File]->[New]->[New Project...] を選択してください
2. [New Project]画面が表示されたら、以下を入力して[Next]を押してください
    - Application name:  **CalendarQuickstart**
    - Company Domain: **example.com**
3. [Target Android Devices]画面が表示されたら、以下を設定して[Next]を押してください
    - **"Phone and Tablet"**のみにチェックを入れてください
    - "Phone and Tablet"の"Minimum SDK"を**[API 15: Android 4.0.3 (IceCreamSandwich)]**に設定してください
4. [Add an Activity to Mobile]画面が表示されたら**[Add No Activity]**を選択して[Finish]を押してください

# Step 4: プロジェクトを準備する

## a) テスト用のプロジェクトを削除する

1. Android Studioの左側に表示されている"1: Project"ウィンドウから[app]->[java]を開いてください
2. 今回は不要のため、以下のフォルダは削除してください
    - com.example.calendarquickstart (androidTest)
    - com.example.calendarquickstart (test)

## b) build.gradle (Module: app) を編集する

1. "1: Project"ウィンドウから[Gradle Scripts]->**[build.gradle (Module: app)]**を開いてください
2. "build.gradle (Module: app)"を以下の内容で差し換えてください

```groovy:build.gradle
apply plugin: 'com.android.application'
 
android {
    compileSdkVersion 24
    buildToolsVersion "24.0.3"
    defaultConfig {
        applicationId "com.example.calendarquickstart"
        minSdkVersion 15
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
 
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:24.2.1'
    compile 'com.google.android.gms:play-services-auth:9.6.1'
    compile 'pub.devrel:easypermissions:0.1.5'
    compile('com.google.api-client:google-api-client-android:1.22.0') {
        exclude group: 'org.apache.httpcomponents'
    }
    compile('com.google.apis:google-api-services-calendar:v3-rev214-1.22.0') {
        exclude group: 'org.apache.httpcomponents'
    }
}
```

- 編集後にメニューバーから [Tools]->[Android]->**[Sync Project with Gradle Files]**を選択してください
    - build.gradleの内容を元に必要なファイルがdownloadされ、makeが実行されます


## c) AndroidManifest.xml を編集する

1. "1: Project"ウィンドウから[app]->[manifests]->**[AndroidManifest.xml]**を開いてください
2. "AndroidManifest.xml"を以下の内容で差し換えてください

```xml:AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.calendarquickstart">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="Google Calendar API Android Quickstart"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="Google Calendar API Android Quickstart" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
    </application>
</manifest>
```

# Step 5: アプリをセットアップする

1. "1: Project"ウィンドウから[app]->[java]->[com.example.calendarquickstart]を選択する
2. 右クリックメニューから[New]->[Java Class]を選択する
3. [Create New Class]ダイアログが表示されたら、以下を入力して[OK]を押す
    - Name: **MainActivity**
4. "MainActivity.java"を以下の内容で差し換えてください

```java:MainActivity.java
package com.example.calendarquickstart;

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.CalendarScopes;
import com.google.api.client.util.DateTime;

import com.google.api.services.calendar.model.*;

import android.Manifest;
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.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.text.method.ScrollingMovementMethod;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

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 MainActivity extends Activity implements EasyPermissions.PermissionCallbacks {

    GoogleAccountCredential mCredential;
    private TextView mOutputText;
    private Button mCallApiButton;
    ProgressDialog mProgress;

    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 BUTTON_TEXT = "Call Google Calendar API";
    private static final String PREF_ACCOUNT_NAME = "accountName";
    private static final String[] SCOPES = {CalendarScopes.CALENDAR};

    /**
     * Activityを作成する。
     *
     * @param savedInstanceState 以前に保存されたインスタンスのデータ
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Activity のレイアウトを準備する
        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, 16);

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

        // Google Calendar API を呼び出す　Button を準備する
        mCallApiButton = new Button(this);
        mCallApiButton.setText(BUTTON_TEXT);
        mCallApiButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCallApiButton.setEnabled(false);
                mOutputText.setText("");
                getResultsFromApi();
                mCallApiButton.setEnabled(true);
            }
        });
        activityLayout.addView(mCallApiButton);

        // Google Calendar API の呼び出し結果を表示する　TextView を準備する
        mOutputText = new TextView(this);
        mOutputText.setLayoutParams(tlp);
        mOutputText.setPadding(16, 16, 16, 16);
        mOutputText.setVerticalScrollBarEnabled(true);
        mOutputText.setMovementMethod(new ScrollingMovementMethod());
        mOutputText.setText("Click the \'" + BUTTON_TEXT + "\' button to test the API.");
        activityLayout.addView(mOutputText);

        // Google Calendar API の呼び出し中を表す PrgressDialog を準備する
        mProgress = new ProgressDialog(this);
        mProgress.setMessage("Calling Google Calendar API ...");

        // ActivityにViewを設定する
        setContentView(activityLayout);

        // Google Calendar API の呼び出しのための認証情報を初期化する
        mCredential = GoogleAccountCredential.usingOAuth2(
                getApplicationContext(),
                Arrays.asList(SCOPES)
        ).setBackOff(new ExponentialBackOff());
    }


    /**
     * Google Calendar API の呼び出しの事前条件を確認し、条件を満たしていればAPIを呼び出す。
     *
     * 事前条件：
     * - 有効な Google Play Services がインストールされていること
     * - 有効な Google アカウントが選択されていること
     * - 端末がインターネット接続可能であること
     *
     * 事前条件を満たしていない場合には、ユーザーに説明を表示する。
     */
    private void getResultsFromApi() {
        if (!isGooglePlayServicesAvailable()) {
            // Google Play Services が無効な場合
            acquireGooglePlayServices();
        }
        else if (mCredential.getSelectedAccountName() == null) {
            // 有効な Google アカウントが選択されていない場合
            chooseAccount();
        }
        else if (!isDeviceOnline()) {
            // 端末がインターネットに接続されていない場合
            mOutputText.setText("No network connection available.");
        }
        else {
            new MakeRequestTask(mCredential).execute();
        }
    }

    /**
     * 端末に Google Play Services がインストールされ、アップデートされているか否かを確認する。
     *
     * @return 利用可能な Google Play Services がインストールされ、アップデートされている場合にはtrueを、
     * そうでない場合にはfalseを返す。
     */
    private boolean isGooglePlayServicesAvailable() {
        GoogleApiAvailability apiAvailability =
                GoogleApiAvailability.getInstance();
        final int connectionStatusCode =
                apiAvailability.isGooglePlayServicesAvailable(this);
        return connectionStatusCode == ConnectionResult.SUCCESS;
    }

    /**
     * ユーザーにダイアログを表示して、Google Play Services を利用可能な状態に設定するように促す。
     * ただし、ユーザーが解決できないようなエラーの場合には、ダイアログを表示しない。
     */
    private void acquireGooglePlayServices() {
        GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
        final int connectionStatusCode = apiAvailability.isGooglePlayServicesAvailable(this);
        if (apiAvailability.isUserResolvableError(connectionStatusCode)) {
            showGooglePlayServicesAvailabilityErrorDialog(connectionStatusCode);
        }
    }

    /**
     * 有効な Google Play Services が見つからないことをエラーダイアログで表示する。
     *
     * @param connectionStatusCode Google Play Services が無効であることを示すコード
     */
    void showGooglePlayServicesAvailabilityErrorDialog(
            final int connectionStatusCode
    ) {
        GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
        Dialog dialog = apiAvailability.getErrorDialog(
                MainActivity.this,
                connectionStatusCode,
                REQUEST_GOOGLE_PLAY_SERVICES
        );
        dialog.show();
    }

    /**
     * Google　Calendar API の認証情報を使用するGoogleアカウントを設定する。
     *
     * 既にGoogleアカウント名が保存されていればそれを使用し、保存されていなければ、
     * Googleアカウントの選択ダイアログを表示する。
     *
     * 認証情報を用いたGoogleアカウントの設定には、"GET_ACCOUNTS"パーミッションを
     * 必要とするため、必要に応じてユーザーに"GET_ACCOUNTS"パーミッションを要求する
     * ダイアログが表示する。
     */
    @AfterPermissionGranted(REQUEST_PERMISSION_GET_ACCOUNTS)
    private void chooseAccount() {
        // "GET_ACCOUNTS"パーミッションを取得済みか確認する
        if (EasyPermissions.hasPermissions(this, Manifest.permission.GET_ACCOUNTS)) {
            // SharedPreferencesから保存済みGoogleアカウントを取得する
            String accountName = getPreferences(Context.MODE_PRIVATE)
                    .getString(PREF_ACCOUNT_NAME, null);
            if (accountName != null) {
                mCredential.setSelectedAccountName(accountName);
                getResultsFromApi();
            } else {
                // Googleアカウントの選択を表示する
                // GoogleAccountCredentialのアカウント選択画面を使用する
                startActivityForResult(
                        mCredential.newChooseAccountIntent(),
                        REQUEST_ACCOUNT_PICKER);
            }
        }
        else {
            // ダイアログを表示して、ユーザーに"GET_ACCOUNTS"パーミッションを要求する
            EasyPermissions.requestPermissions(
                    this,
                    "This app needs to access your Google account (via Contacts).",
                    REQUEST_PERMISSION_GET_ACCOUNTS,
                    Manifest.permission.GET_ACCOUNTS);
        }
    }

    /**
     * アカウント選択や認証など、呼び出し先のActivityから戻ってきた際に呼び出される。
     *
     * @param requestCode Activityの呼び出し時に指定したコード
     * @param resultCode  呼び出し先のActivityでの処理結果を表すコード
     * @param data        呼び出し先のActivityでの処理結果のデータ
     */
    @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) {
                        SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
                        SharedPreferences.Editor editor = settings.edit();
                        editor.putString(PREF_ACCOUNT_NAME, accountName);
                        editor.apply();
                        mCredential.setSelectedAccountName(accountName);
                        getResultsFromApi();
                    }
                }
                break;

            case REQUEST_AUTHORIZATION:
                if (resultCode == RESULT_OK) {
                    getResultsFromApi();
                }
                break;
        }
    }

    /**
     * Android 6.0 (API 23) 以降にて、実行時にパーミッションを要求した際の結果を受け取る。
     *
     * @param requestCode  requestPermissions(android.app.Activity, String, int, String[])
     *                     を呼び出した際に渡した　request code
     * @param permissions  要求したパーミッションの一覧
     * @param grantResults 要求したパーミッションに対する承諾結果の配列
     *                     PERMISSION_GRANTED または PERMISSION_DENIED　が格納される。
     */
    @Override
    public void onRequestPermissionsResult(
            int requestCode,
            @NonNull String[] permissions,
            @NonNull int[] grantResults
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    /**
     * 要求したパーミッションがユーザーに承諾された際に、EasyPermissionsライブラリから呼び出される。
     *
     * @param requestCode 要求したパーミッションに関連した request code
     * @param list        要求したパーミッションのリスト
     */
    @Override
    public void onPermissionsGranted(int requestCode, List<String> list) {
        // 何もしない
    }

    /**
     * 要求したパーミッションがユーザーに拒否された際に、EasyPermissionsライブラリから呼び出される。
     *
     * @param requestCode 要求したパーミッションに関連した request code
     * @param list        要求したパーミッションのリスト
     */
    @Override
    public void onPermissionsDenied(int requestCode, List<String> list) {
        // 何もしない
    }

    /**
     * 現在、端末がネットワークに接続されているかを確認する。
     *
     * @return ネットワークに接続されている場合にはtrueを、そうでない場合にはfalseを返す。
     */
    private boolean isDeviceOnline() {
        ConnectivityManager connMgr =
                (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
        return (networkInfo != null && networkInfo.isConnected());
    }

    /**
     * 非同期で　Google Calendar API の呼び出しを行うクラス。
     */
    private class MakeRequestTask extends AsyncTask<Void, Void, String> {

        private com.google.api.services.calendar.Calendar mService = null;
        private Exception mLastError = null;

        public MakeRequestTask(GoogleAccountCredential credential) {
            HttpTransport transport = AndroidHttp.newCompatibleTransport();
            JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
            mService = new com.google.api.services.calendar.Calendar
                    .Builder(transport, jsonFactory, credential)
                    .setApplicationName("Google Calendar API Android Quickstart")
                    .build();
        }

        /**
         * Google Calendar API を呼び出すバックグラウンド処理。
         *
         * @param params 引数は不要
         */
        @Override
        protected String doInBackground(Void... params) {
            try {
                return createCalendar();
            } catch (Exception e) {
                mLastError = e;
                cancel(true);
                return null;
            }
        }

        /**
         * 選択されたGoogleアカウントに対して、新規にカレンダーを追加する。
         *
         * @return 作成したカレンダーのID
         * @throws IOException
         */
        private String createCalendar() throws IOException {
            // 新規にカレンダーを作成する
            com.google.api.services.calendar.model.Calendar calendar = new Calendar();
            // カレンダーにタイトルを設定する
            calendar.setSummary("CalendarTitle");
            // カレンダーにタイムゾーンを設定する
            calendar.setTimeZone("Asia/Tokyo");

            // 作成したカレンダーをGoogleカレンダーに追加する
            Calendar createdCalendar = mService.calendars().insert(calendar).execute();
            String calendarId = createdCalendar.getId();

            // カレンダー一覧から新規に作成したカレンダーのエントリを取得する
            CalendarListEntry calendarListEntry = mService.calendarList().get(calendarId).execute();

            // カレンダーのデフォルトの背景色を設定する
            calendarListEntry.setBackgroundColor("#ff0000");

            // カレンダーのデフォルトの背景色をGoogleカレンダーに反映させる
            CalendarListEntry updatedCalendarListEntry =
                    mService.calendarList()
                            .update(calendarListEntry.getId(), calendarListEntry)
                            .setColorRgbFormat(true)
                            .execute();

            // 新規に作成したカレンダーのIDを返却する
            return calendarId;
        }

        @Override
        protected void onPreExecute() {
            mOutputText.setText("");
            mProgress.show();
        }

        @Override
        protected void onPostExecute(String output) {
            mProgress.hide();
            if (output == null || output.isEmpty()) {
                mOutputText.setText("No results returned.");
            } else {
                mOutputText.setText("Calendar created using the Google Calendar API: " + 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(),
                            MainActivity.REQUEST_AUTHORIZATION);
                } else {
                    mOutputText.setText("The following error occurred:\n" + mLastError.getMessage());
                }
            } else {
                mOutputText.setText("Request cancelled.");
            }
        }
    }
}
```

# Step 6: アプリを実行する

1. メニューバーから [Run]->**[Run 'app']**を選択してください
2. [Select Deployment Target]ダイアログが表示されたら、USB接続されている端末を選択して[OK]を押してください
3. Android 6.0 (Marshmallow)以降の端末でアプリを実行すると、「連絡先」のパーミッションが要求されますので承諾してください
4. Googleアカウントの選択画面が表示されますので、新規にカレンダーを作成するアカウントを選択してください
5. Google Calendar API の呼び出し後、Googleカレンダーを起動してメニューから「更新」を実行してください
6. Googleカレンダーの指定したGoogleアカウントに以下のカレンダーが追加されていることを確認してください
    - 名前: CalendarTitle
    - 背景色: 赤色

# 参考情報

- [Android Quickstart  |  Google Calendar API  |  Google Developers](https://developers.google.com/google-apps/calendar/quickstart/android)
- [Calendars: insert  |  Google Calendar API  |  Google Developers](https://developers.google.com/google-apps/calendar/v3/reference/calendars/insert)
- [CalendarList: update  |  Google Calendar API  |  Google Developers](https://developers.google.com/google-apps/calendar/v3/reference/calendarList/update)
- [アプリケーションへの署名 | Android Developers](https://developer.android.com/guide/publishing/app-signing.html?hl=ja)