Android GCMのバックエンドにPushwooshを利用する


## Pushwoosh

http://www.pushwoosh.com

Pushwooshはマルチプラットフォーム対応のプッシュ通知バックエンドサービスです。現在、19プラットフォーム（Android,iOS,Blackberry,Amazon,Windows Phoneなど）が利用できるようです。

コントロールパネルは日本語化されていませんが、通知メッセージは日本語も問題なく利用できます。

### 実質無制限？のフリープラン

フリープランでは５つまでのアプリケーション、デバイスは100万デバイスまで登録できるそうです。

フリープランの送信数に関して、upgradeページのinfoで以下のようなメッセージがポップアップします。

```
You can send messages to your users once a month, once a week or 10 times per day.
```

10回/1日までで週1,月1（？）と読めますが、連続して10回以上送信できますし、2日連続でも送信できます。

実質無制限？ということでしょうか。もしかすると、上記のポップアップのメッセージが古いのかもしれませんね。

## Pushwooshアプリ作成

サインアップの説明は割愛しますが、アプリの作成だけ簡単に紹介します。
ログインすると、コントロールパネルが表示されます。

![pushwoosh-dashboard.png](https://qiita-image-store.s3.amazonaws.com/0/24161/9747aba0-2f9c-b311-487a-e7a8fdf481bc.png "pushwoosh-dashboard.png")

コントロールパネルの右上の+Add newボタン(1)でアプリを作成します。

![pushwoosh-create-app.png](https://qiita-image-store.s3.amazonaws.com/0/24161/2953e7c5-d8f7-8c79-8de3-d84ce539f13a.png "pushwoosh-create-app.png")

(2)あたりをクリップするとプラットフォームごとの一覧が表示されます。

AndroidのConfigureボタンでプラットフォームごとに設定します。
[Google Develper Console](https://console.developers.google.com)で取得したGoogle APIのキーを設定します。

![pushwoosh-config.png](https://qiita-image-store.s3.amazonaws.com/0/24161/03f1723e-f628-dd24-ca4d-2d0f2df61651.png "pushwoosh-config.png")

PushwooshアプリのApplication Code（赤矩形で囲った部分）とGoogle APIキーは、AndroidManifest.xmlに設定します。

※Pushwooshのコントロールパネルには、ときどきパックマンがでてきます（謎）。

## Android SDK & Sample

Pushwooshが提供するAndroidのサンプルプログラムは二つあります。

* [Native Android SDK](http://docs.pushwoosh.com/docs/native-android-sdk)
* [Android SDK Fragments](http://pushwoosh.readme.io/docs/android-sdk-fragments)

ドキュメントでは、Fragmentsの方を推奨しているようですので、今回はFragmentsで試してみました。

### ソースコード

https://github.com/Pushwoosh/pushwoosh-native-samples/tree/master/Android-Fragment

## 修正ポイント

このサンプルはeclipseのプロジェクトファイルが含まれていますが、Android Studioから読み込みました。

API22(lollipop MR1)を利用しているせいか、Google Play Serviceライブラリのバージョンが上がったためか、このままでは動作しませんでした。

そういった修正点もふくめて記録しておきます。

### SDKの取得

SDKはapp/libs/Pushwoosh.jarとして、含まれていますが、最新(現時点3.1.0)を利用するようにbuild.gradleに追加しました。

```build.gradle
dependencies {
  compile 'com.android.support:support-v4:18.0.0'
  compile 'com.google.android.gms:play-services:+'
  compile 'com.pushwoosh:pushwoosh:+'
}
```

### AndroidManifest.xmlの修正

#### minSdkVersion

Google Play Serviceのバージョンにより、uses-sdk:minSdkVersionは9以上に設定する必要があります。

```XML:AndroidManifest.xml
<uses-sdk
  android:minSdkVersion="9"
  android:targetSdkVersion="22"
/>
```

build.gradleのデフォルト値も確認しておく方がよいでしょう。

```build.grade
defaultConfig {
  applicationId "jp.co.notice.android.gcm"
  minSdkVersion 9
  targetSdkVersion 22
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_7
    targetCompatibility JavaVersion.VERSION_1_7
  }
}
```

#### PushWooshアプリの設定

GCMを利用するためのパーミッション以外に、Pushwooshアプリの情報を設定する必要があります。

作成したアプリのIDをApplicationタグ内に指定します。
PW_PROJECT_IDは、[Google Develper Console](https://console.developers.google.com)で得られるプロジェクトIDの先頭にAを付加したものです。

```XML:AndroidManifest.xml
<Application>
  <meta-data
    android:name="PW_APPID"
    android:value="AXX99-B9999"
  />
  <meta-data
    android:name="PW_PROJECT_ID"
    android:value="A999999999999"
  />
</Application>
```

#### レシーバクラス

サンプルのレシーバクラスは古いものが指定されています。
このままではクラッシュしますので、WakefulBroadcastReceiverを継承しているGcmReceiverに変更しました。

```XML:AndroidManifest.xml
<receiver
　　android:name="com.google.android.gms.gcm.GcmReceiver"
　　android:exported="true"
   android:permission="com.google.android.c2dm.permission.SEND"
>
  <intent-filter>
    <action android:name="com.google.android.c2dm.intent.RECEIVE" />
    <category android:name="jp.co.notice.android.gcm" />
  </intent-filter>
</receiver>
```

## ソースコード

ソースコードはPushFragmentActivity.javaのみです。
パッケージ名を変更しないなら、ほとんど修正するところはありません。
ポイントのみ簡単に紹介します。

### インタフェース
FragmentActivityを継承し、PushEventListenerを実装する必要があります。

```java:PushEventListener
public class PushFragmentActivity extends FragmentActivity implements PushEventListener
```

### コンストラクタ

PushFragment.init()を実行します。

```java:onCreate
@Override
protected void onCreate(Bundle savedInstanceState)
{
  super.onCreate(savedInstanceState);
  PushFragment.init(this);
}
```

### onNewIntent

PushFragment.onNewIntent()を実行します。

```java:onNewIntent
@Override
public void onNewIntent(Intent intent)
{
　super.onNewIntent(intent);
  PushFragment.onNewIntent(this, intent);
}
```

### 各ハンドラ

必要ならば、以下のハンドラに対して処理を実行します。デバイスのGCM登録・解除に関するものです。

```java:handlers
public void doOnRegistered(String registrationId)
public void doOnRegisteredError(String errorId)
public void doOnUnregistered(final String message)
public void doOnUnregisteredError(String errorId)
```

### メッセージ受信ハンドラ

ここで通知メッセージを取得します。messageはJSON Stringです。

```
public void doOnMessageReceive(String message)
```

#### 受信メッセージ例

```javascript:message
{
  "onStart": true,
  "pw_msg": "1",
  "p": "<",
  "pri": "",
  "vib": "0",
  "title": "受信メッセージ",
  "collapse_key": "do_not_collapse",
  "foreground": false
}
```

## Woosh!

ビルドして試してみましょう。

Pushwooshのコントロールパネルからアプリ名(3)をクリックして送信画面へ遷移し、メッセージを作成します。

![pushwoosh-push.png](https://qiita-image-store.s3.amazonaws.com/0/24161/08b62dcb-4231-34a5-9efb-582ce72652ce.png "pushwoosh-push.png")

送信するにはWooshボタンをクリックします。
スクリーンショットではWooshボタンがありませんが、実際はスクリーンショットのもっと下の方にあります。

http://docs.pushwoosh.com/docs/send-push


フリープランで無制限とは嬉しいですね。アプリに簡単なお知らせ機能がほしいときには便利です。

コントロールパネルが英語なのが気にならないなら、おすすめです。

割と親切なドキュメントやサンプルコードも豊富なので、実装も簡単です。

もちろん、iOSへも同時に送信可能です。
iOSではXcode6.4+Swift1.2でiOS SDKを組み込んだ経験がありますが、動作しています。