Android勉強会 番外編 GoogleCalendarを取得する

この記事では Android Studio 2.1.2 を使用しています。
大学の研究室で開催している勉強会の資料共有とアーカイブのためにQiitaに投稿しています。

AndroidアプリからGoogleのAPIを用いて様々なGoogleのサービスを利用します。
今回は要望があったため急遽Calendarについても記事にしました
基本的な部分は[第4回](http://qiita.com/InoueDaiki/items/77e5798a4933a2531c13)とほとんど同じです

# APIとは
APIはざっくりと説明すると他の人が用意してくれた便利なライブラリのことです。
プログラミングはすべて自分で作るのには限界があるためAPIを組み合わせてアプリを作っていくことが多いと思われます。
今回はそんなAPIについて学んでいきたいと思います

# Google カレンダー とは
ウェブブラウザでも利用できるカレンダーのクラウドサービスです
所持する端末間でカレンダーを同期できるので便利ですね

# APIでできること
Googleカレンダーの予定を取得したり追加したりできます

# GoogleのAPIを利用するために
GoogleのAPIを利用するためには開発者としての登録とどの機能を使うか選択する必要があります。
さらに実際に利用する際には認証が必要になるためアプリ開発に用いるにはすこし難しいと感じています。

## 開発者として登録する
まずは[Google API Console](https://console.developers.google.com)にアクセスしプロジェクトを作成します。
大学や企業のアカウントなどでは以下のように利用できない場合があります。この表示が出た時は通常のGoogleアカウントにします。
![無題.jpg](https://qiita-image-store.s3.amazonaws.com/0/113969/2ba292cf-9b4b-dbc1-e3aa-e10440f071fd.jpeg)

## プロジェクトを作成する
勉強会で使用するプロジェクトを作成します。
![無題.jpg](https://qiita-image-store.s3.amazonaws.com/0/113969/a986fb24-0e61-01f0-5c01-7a128d28239e.jpeg)
画面右上周辺の「プロジェクトを選択」をクリックし「プロジェクトの作成」をクリックしてください。
![無題.jpg](https://qiita-image-store.s3.amazonaws.com/0/113969/ced33654-f31c-a032-ca85-23b101937647.jpeg)
プロジェクト名は好きなもので構いません。入力したら「作成」をクリックします。
プロジェクトの作成には1分ほどかかりますので待ちます。

## 利用するAPIを選択する
今回はCalendar APIを用いるためGoogle Apps APIの中にあるCalendar APIを選択します。
![無題.jpg](https://qiita-image-store.s3.amazonaws.com/0/113969/1dfe7deb-82d3-e5ab-42e1-eaa54665b030.jpeg)
「有効にする」をクリックします。
![無題.jpg](https://qiita-image-store.s3.amazonaws.com/0/113969/05a37cd1-c1f5-8a78-dcc2-4baec8bd2238.jpeg)
警告が出てきますので「認証情報に進む」をクリックします。
![無題.jpg](https://qiita-image-store.s3.amazonaws.com/0/113969/8c537fd4-a5ca-7088-8591-4d6f39f23580.jpeg)
今回はCalendar APIを選択し、呼び出す場所をAndroidとします。
![無題.jpg](https://qiita-image-store.s3.amazonaws.com/0/113969/39cd19b8-348a-9f78-48d8-e57b917a9d54.jpeg)
次にこのような画面になります
![無題.jpg](https://qiita-image-store.s3.amazonaws.com/0/113969/31e618c5-fef8-1d2e-66b7-e7ccc95ae20c.jpeg)
ここでAPIを使用するAndroidアプリの「パッケージ名」と「フィンガープリント」が必要になるため調べていきます

## パッケージ名を調べる
まずは空のAndroidアプリを作成します
EmptyActivityを選択しアプリを作成しました
はじめに生成されたbuild.gradle(Module: app)を開きます。

```rb:build.gradle
apply plugin: 'com.android.application'

android {
    ...
    defaultConfig {
        applicationId "パッケージ名"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    ...
}

...
```

android -> defaultConfig -> applicationId がパッケージ名になります

## フィンガープリントを調べる
これが少し面倒です

まずはJavaのインストールされたフォルダのbinフォルダを開きます
大抵の場合`C:\Program Files\Java\jre7\bin`となっていると思われますが適宜調べてください
そしてコマンドプロンプトを開きます(Shift+右クリックで簡単に開けます)

次にAndroidStudioが使用するkeystoreファイルを探します
こちらは基本的に`C:\Users\ユーザー名\.android`となります
このフォルダの中にdebug.keystoreというファイルがあるはずです
先ほど開いたコマンドプロンプトに
`keytool -list -v -keystore `
と入力しdebug.keystoreファイルをコマンドプロンプトにドラッグします
するとコマンドプロンプト上には
`C:\Program Files\Java\jre7\bin>keytool -list -v -keystore C:\Users\ユーザ名\.android\debug.keystore`
のように表示されますのでEnterキーを押して実行します

パスワードの入力を求められるので`android`と入力します
この時に入力しても何も表示されませんがそのままEnterキーを押します

すると様々な情報が表示されますがフィンガープリントはSHA1の部分になります
![無題.jpg](https://qiita-image-store.s3.amazonaws.com/0/113969/cb0642c8-af89-47b4-566c-348167e5b581.jpeg)
※一部隠してあります

## パッケージ名とフィンガープリントを登録する
再びGoogleの登録画面にもどり2つを登録します
![無題.jpg](https://qiita-image-store.s3.amazonaws.com/0/113969/77f5e44f-b87f-00c9-7661-c4c072014fb2.jpeg)
入力したら「APIキーを生成する」をクリックし「完了」をクリックします
![無題.jpg](https://qiita-image-store.s3.amazonaws.com/0/113969/dcb4d15c-25a7-d664-9aff-250f313c70e6.jpeg)
このような画面になります

ここまででAPIを利用する準備は整いました

# アプリ側の準備をする
APIを使用するために必要なライブラリを読み込みます
まずは(Module: app)と表記されているbuild.gradleを編集します

```rb:build.gradle
apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "パッケージ名"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'
    // ここから下を追加
    compile 'com.google.android.gms:play-services-auth:9.0.2'
    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-rev201-1.22.0') {
        exclude group: 'org.apache.httpcomponents'
    }
}
```

基本的には生成されたままですがdependenciesに幾つか追記しています
次に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.quickstart">


    <!--ネットワーク接続の許可を追加-->
    <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="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!--meta情報を追加-->
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
    </application>

</manifest>
```

2か所追加しました

## サンプルコードをコピーする
[公式のサンプルコード](https://developers.google.com/google-apps/calendar/quickstart/android#step_5_setup_the_sample)をそのまま一度写します
1行目はそれぞれ異なるはずので1行目以外をすべてコピペします

## サンプルコードを実行する
起動してCALL GOOGLE CALENDAR APIをタップすると今後の10個の予定が時系列順に表示されます

## どこで取得しているのか
サンプルコードの363行目付近のgetDataFromApiという関数がカレンダーのデータを読み取ってきています
詳しい使い方は[リファレンス](https://developers.google.com/google-apps/calendar/v3/reference/)

## 少しだけ改造
getDataFromApiを少し改造して24時間以内の予定をリストアップしてみます
コメントアウトのある部分のみ追加しています

```java
        private List<String> getDataFromApi() throws IOException {
            DateTime now = new DateTime(System.currentTimeMillis());
            DateTime end = new DateTime(System.currentTimeMillis() + 24 * 60 * 60 * 1000); // 24時間後を保持する変数
            List<String> eventStrings = new ArrayList<String>();
            Events events = mService.events().list("primary")
                    .setMaxResults(10)
                    .setTimeMin(now)
                    .setTimeMax(end) // 取得するデータの最大の時間を決める
                    .setOrderBy("startTime")
                    .setSingleEvents(true)
                    .execute();
            ...
        }
```