Amazon SNSを使ってGCM経由でプッシュ通知

Amazon SNSのモバイルプッシュを使ってGCM経由でプッシュ通知する方法のめも
#GCMの設定
SNSからGCMを経由してプッシュ通知するため、まずはGCMの設定を行います。
Google Developer ConsoleでGCMを有効に設定します。

1. [Google Developer Console](https://console.developers.google.com)でプロジェクトを選択（または作成）
2. APIからCloud Messaging for Androidを選択
![API_ライブラリ_-_Default_Demo_App.png](https://qiita-image-store.s3.amazonaws.com/0/23385/e5654d6f-3eed-efb3-473d-60b53087e753.png "API_ライブラリ_-_Default_Demo_App.png")

3. APIを有効にする
![Google_Cloud_Messaging_for_Android_-_Default_Demo_App.png](https://qiita-image-store.s3.amazonaws.com/0/23385/8d4b1619-d87c-5592-13e3-4fd9ca371b3a.png "Google_Cloud_Messaging_for_Android_-_Default_Demo_App.png")
4. "認証情報"からAPIキーを作成 
![認証情報_-_Default_Demo_App.png](https://qiita-image-store.s3.amazonaws.com/0/23385/cea4ab16-c5a2-d90c-1d35-ada25f2af369.png "認証情報_-_Default_Demo_App.png")

5. サーバーキー選択
![認証情報_-_Default_Demo_App2.png](https://qiita-image-store.s3.amazonaws.com/0/23385/bbf267d6-d8bd-920d-a41c-2c24150ca2f2.png "認証情報_-_Default_Demo_App2.png")

6. IPアドレスを指定して作成（IPアドレスを指定しないとどのアドレスからでもリクエストを受け付ける）
![認証情報_-_Default_Demo_App3.png](https://qiita-image-store.s3.amazonaws.com/0/23385/a19fbd81-24c6-0d47-d099-9907726a7e3c.png "認証情報_-_Default_Demo_App3.png")
7. APIキーが作成されます
![認証情報_-_Default_Demo_App4.png](https://qiita-image-store.s3.amazonaws.com/0/23385/6170b34b-b0d1-cbe3-7f87-3538f3e56cf1.png "認証情報_-_Default_Demo_App4.png")

# GCMの設定ファイル取得
1.以下のサイトにアクセスします
[設定ファイル取得](https://developers.google.com/mobile/add?platform=android&cntapi=gcm&cntapp=Default%20Demo%20App&cntpkg=gcm.play.android.samples.com.gcmquickstart&cnturl=https:%2F%2Fdevelopers.google.com%2Fcloud-messaging%2Fandroid%2Fstart%3Fconfigured%3Dtrue&cntlbl=Continue%20Try%20Cloud%20Messaging)
2. パッケージにAndroidアプリのルートパッケージを設定し（ここでは"gcm.play.android.samples.com.gcmquickstart"を設定）、"Choose and configure services"をクリックします
![Add_Google_Services_ ___ _Google_Developers.png](https://qiita-image-store.s3.amazonaws.com/0/23385/417497c1-836b-c85c-b8c0-a0bd1ff4088d.png "Add_Google_Services_ ___ _Google_Developers.png")


3."ENABLE GOOGLE CLOUD MESSAGING"をクリックします
![Add_Google_Services_ ___ _Google_Developers2.png](https://qiita-image-store.s3.amazonaws.com/0/23385/bf6c02a8-44c0-6af9-f362-d3c52c16d332.png "Add_Google_Services_ ___ _Google_Developers2.png")


4."Server API Key"と"Sender ID"は後ほど利用するので保存しておきます。"Generate configuration files"をクリックします

 - Sender ID:クライアントアプリにメッセージを送信するアプリケーションサーバの認証に使用する
 - API Key:


![Add_Google_Services_ ___ _Google_Developers3.png](https://qiita-image-store.s3.amazonaws.com/0/23385/47cbb0ee-acea-bb26-35a4-9e7d26f39eb1.png "Add_Google_Services_ ___ _Google_Developers3.png")

5."Download google-services.json"をクリックして設定ファイルをダウンロードします
![Add_Google_Services_ ___ _Google_Developers4.png](https://qiita-image-store.s3.amazonaws.com/0/23385/8504ce41-1d5f-1f52-f1b3-33f71f43cb6e.png "Add_Google_Services_ ___ _Google_Developers4.png")

# GCMのregist token取得

参照：[Try Cloud Messaging for Android](https://developers.google.com/cloud-messaging/android/start)
注：最新の[Android Studio](https://developer.android.com/intl/ja/sdk/index.html)と[Google Play Services](https://developer.android.com/intl/ja/sdk/installing/adding-packages.html)が必要です。

1. google-servicesリポジトリをチェックアウトします
``` 
$ git clone https://github.com/googlesamples/google-services.git
```
2. AndroidStudioでプロジェクトを開きます（google-services/android/gcm）
3. 以下のソースを編集します
 - gcm.play.android.samples.com.gcmsender.GcmSender.java 30行目```public static final String API_KEY = "[Server API Key]";```
 - res/values/strings.xml 9行目```<string name="gcm_defaultSenderId">[Sender ID]</string>```
 - Server API Key、Sender IDは前節のGoogle Developer Consoleで取得した値を設定します
4. appを実行します
![device-2015-08-12-104216.png](https://qiita-image-store.s3.amazonaws.com/0/23385/dbfc3ff5-b125-85f1-3109-1f99f0dd23da.png "device-2015-08-12-104216.png")

5. 以下のコマンドを実行します```./gradlew run -Pargs="こんにちは"```
6. Android端末にプッシュ通知が来ます
![device-2015-08-07-121455.png](https://qiita-image-store.s3.amazonaws.com/0/23385/f4dc372d-4635-52ee-1923-ffd2c03611c7.png "device-2015-08-07-121455.png")

ちなみに、サンプルアプリは起動時に"/topics/global"を購読しています。gradlewコマンドではプッシュ通知するメッセージのみを渡すと"/topics/global"というTopicにパブリッシュするので、サンプルアプリを起動した端末でプッシュ通知を受け取ることができます。
Topicではなく、特定の端末にプッシュ通知するには第二引数に[regist token]を渡します。

```
./gradlew run -Pargs="こんにちは,[regist token]"
```
このコマンドを実行すると、[regist token]の端末にのみメッセージをパブリッシュできます。
Topicについての詳細は[Implementing Topic Messaging](https://developers.google.com/cloud-messaging/topic-messaging)を参照してください。



##registration tokenの取得
「GCMのサンプルアプリケーションの実行」で以下のようなログが出力されます。このRegistration TokenがGCMからのregistration tokenとなります。

```
08-07 12:01:37.960  13513-13567/gcm.play.android.samples.com.gcmquickstart I/RegIntentService﹕ GCM Registration Token: xxxxx
```

registration token取得のソースコードは以下になります。[InstanceID](https://developers.google.com/android/reference/com/google/android/gms/iid/InstanceID)を利用してトークンを取得します。```getInstance```の引数には```Context```を渡します。```R.string.gcm_defaultSenderId```の値はstring.xmlに設定した[Sender ID]です。

```java:RegistrationIntentService.java(53行目)
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
        GoogleCloudMessaging.INSTANCE_ID_SCOPE, null)
```
##メッセージ受信

PUSH通知されたメッセージを受信するには```GcmListenerService```を拡張します。
```onMessageReceived```メソッドをオーバーライドしてプッシュ通知受信後の処理を記述します。

```java
@Override
public void onMessageReceived(String from, Bundle data) {
    String message = data.getString("message");
    Log.d(TAG, "From: " + from);
    Log.d(TAG, "Message: " + message);

    /**
     * Production applications would usually process the message here.
     * Eg: - Syncing with server.
     *     - Store message in local database.
     *     - Update UI.
     */

    /**
     * In some cases it may be useful to show a notification indicating to the user
     * that a message was received.
     */
    sendNotification(message);
}
```

- ```./gradlew run -Pargs="こんにちは"```を実行すると、以下のようなログが出力されます

```
08-12 11:02:24.612   2954-17735/gcm.play.android.samples.com.gcmquickstart D/MyGcmListenerService﹕ From: /topics/global
08-12 11:02:24.612   2954-17735/gcm.play.android.samples.com.gcmquickstart D/MyGcmListenerService﹕ Message: こんにちは
```

- ```./gradlew run -Pargs="こんにちは,[regist token]"```を実行すると、以下のようなログが出力されます

```
08-12 11:28:04.964   30196-2379/gcm.play.android.samples.com.gcmquickstart D/MyGcmListenerService﹕ From: [Sender ID]
08-12 11:28:04.964   30196-2379/gcm.play.android.samples.com.gcmquickstart D/MyGcmListenerService﹕ Message: こんにちは
```



##GCMクライアントの詳細
GCMクライアント（Android）の詳細については以下のURLを参考にしてください。
[Implementing GCM Client on Android](https://developers.google.com/cloud-messaging/android/client)



#プッシュ通知
##手動で通知
管理コンソールから手動でプッシュ通知を送ってみます。

1. Amazon SNSのコンソールから[Applications]を選択し、[Create Platform Application]ボタンをクリックします
![AWS_SNS.png](https://qiita-image-store.s3.amazonaws.com/0/23385/f5ca7da2-6b25-7640-75b8-716e2868d0bd.png "AWS_SNS.png")
2. 以下を設定します
 - Application Name:任意の値（今回はSampleGCMを設定）
 - Push Notification Platform:Google Cloud Messaging(GCM)
 - API Key:GCMの設定で取得したServer API Key
![AWS_SNS2.png](https://qiita-image-store.s3.amazonaws.com/0/23385/a82ba38d-aa1c-f6ff-b42e-ad5590ff66fd.png "AWS_SNS2.png")
3. Applicationが作成されました
![AWS_SNS3.png](https://qiita-image-store.s3.amazonaws.com/0/23385/9e256e34-439f-53be-140f-0b369b762ce8.png "AWS_SNS3.png")
4. 作成したApplicationを選択して[Create Platform Endpoint]をクリック
![AWS_SNS4.png](https://qiita-image-store.s3.amazonaws.com/0/23385/09b2a1b6-39aa-115c-70a3-4266cea11c8b.png "AWS_SNS4.png")
5. Device tokenに「GCMのregist token取得」で取得したregist tokenを設定し、[Add endpoint]をクリックします。（User dataはエンドポイントに関連付ける任意の値でAmazon　SNSはこの値を使用しません）
![AWS_SNS5.png](https://qiita-image-store.s3.amazonaws.com/0/23385/be66ad4d-da97-df01-232e-ca5937bd8d19.png "AWS_SNS5.png")
6. デバイスを登録したら、SampleGCMのARNのリンクをクリックして「Application Details」を表示します
7. 登録したTokenを選択して[Publish to Endpoint]をクリックします
![AWS_SNS6.png](https://qiita-image-store.s3.amazonaws.com/0/23385/750a120c-eefa-a217-57fd-fcf66fdc4f38.png "AWS_SNS6.png")
8. [JSON message generator]をクリックします
![AWS_SNS7.png](https://qiita-image-store.s3.amazonaws.com/0/23385/42778b1a-9e7c-de11-58bd-85d6f2655f29.png "AWS_SNS7.png")
9. [Message]を入力して[Generate JSON]をクリック
![AWS_SNS8.png](https://qiita-image-store.s3.amazonaws.com/0/23385/67855e7e-ac0f-093e-eef3-5ec30b3edc92.png "AWS_SNS8.png")
10. GCM用のJSONが生成されるので、[Publish message]をクリックしてメッセージを送信します
![AWS_SNS9.png](https://qiita-image-store.s3.amazonaws.com/0/23385/81622979-6a03-b09a-e29f-64e08dd1013f.png "AWS_SNS9.png")
11. 端末にプッシュ通知がきます

![device-2015-08-12-120541.png](https://qiita-image-store.s3.amazonaws.com/0/23385/544498a3-367e-c92e-bd41-84797df9fd2a.png "device-2015-08-12-120541.png")

##Javaで通知
[AWS SDK for Java](https://aws.amazon.com/jp/sdk-for-java/)を利用して端末にプッシュ通知を行います。

1. [サンプルアプリケーション](https://s3.amazonaws.com/codesamples/sns/latest/snsmobilepush.zip)をダウンロードします
2. 1を解凍し、snsmobilepush/SNSSamplesをIDEで開きます
3. 以下を編集します
 - API Key:GCMのAPI Key
 - アプリケーション名:GCMを利用可能に設定したプロジェクト名

```java:SNSMobilePush.java(96行目)
String serverAPIKey = "[API Key]";
String applicationName = "[プロジェクト名]";
String registrationId = "[regist token]";
```

4.AwsCredentials.propertiesを編集します

```AwsCredentials.properties
accessKey=[Amazon SNSを利用可能なAWSのアクセスキー]
secretKey=[Amazon SNSを利用可能なAWSのシークレットキー]
```

5.SNSMobilePush.java(66行目)のコメントを外します

```java:SNSMobilePush.java
sample.demoAndroidAppNotification();
```
6.com.amazonaws.sns.samples.mobilepush.SNSMobilePushを実行すると端末にプッシュ通知がきます
![device-2015-08-13-111102.png](https://qiita-image-store.s3.amazonaws.com/0/23385/f71121b4-04fd-7f44-55ad-95b24d57b33d.png "device-2015-08-13-111102.png")