AndroidでpushwooshでPush通知を実装する

プッシュ通知を送れるサービス[PushWoosh](https://cp.pushwoosh.com/)。

これを使って、AndroidのPush通知を実装してみました


# Google Play Developer Console での作業

Google Play Developer Console にログイン。
対象のアプリを選択し（一通りの情報は登録済みの前提です）、「サービスとAPI」を選択。
「送信者IDを作成」ボタンをクリック。

すると、以下のページに飛びます。
[Enable Google Services for Your App](https://developers.google.com/mobile/add)

求められるままに、自分のアプリの情報を入力します。

サービスを選択する部分では、「Cloud Messaging」を選択。
![スクリーンショット 2016-02-29 10.42.42.png](https://qiita-image-store.s3.amazonaws.com/0/98954/a663af54-ae12-f30b-ab1b-7090e475b596.png)

「ENABLE GOOGLE CLOUD MESSAGING」をクリックすると

![スクリーンショット 2016-02-29 10.42.52.png](https://qiita-image-store.s3.amazonaws.com/0/98954/506ec9a3-d648-0423-9ae4-120906366d64.png)

このように、APIキー(Server API Key)と送信者ID(Sender ID)が作成されます。（APIキーは英数字記号混じりの文字列。送信者IDは12桁の数字です）
送信者IDは、「プロジェクト番号」（Project Number）とも呼びます。「プロジェクトID」というものもありますがそれとは別物です。（テストに出るよ！）
これをメモっておきます。


ちなみにこの節の作業は、
[Google Developers Console](https://console.developers.google.com/)からも行うことができます。（Google *Play* Developers Console ではなく、 Google Developers Console）



# PushWoosh管理画面での作業

[PushWoosh](https://cp.pushwoosh.com/)に行き、アカウントを作成、アプリの情報を登録します。（これは難しいことはないので省略）

アプリ一覧画面から、ドロイド君の絵の部分をクリック。（実際はアプリ名のリンク以外の部分ならどこをクリックしてもいいです）
![スクリーンショット 2016-02-29 12.03.23_z.png](https://qiita-image-store.s3.amazonaws.com/0/98954/d2eb99ea-76be-28aa-13e8-6588c6ca7c52.png)

すると以下の画面になります。（この絵は、設定完了後のものなので、実際に出る絵は少し違います）
上部に表示されている「Application Code」を記録しておきましょう。（pushwoosh内でのアプリの識別子）
Androidの「Edit」ボタンをクリック。
![スクリーンショット 2016-02-29 12.03.32_z.png](https://qiita-image-store.s3.amazonaws.com/0/98954/202e9827-a548-485d-c0d5-fdfbb5ee82ba.png)

以下の画面になるので、先ほどのAPIキーを入力。
また、アプリで使用しているFrameworkを選択します。（Unityとか。何も使ってなければNative）
![名称未設定 2.png](https://qiita-image-store.s3.amazonaws.com/0/98954/92ac4df7-c5a5-e934-8f4e-9c75d4948949.png)

これで、管理画面での作業は終わりです。


# SDK 実装

[このページ](https://github.com/Pushwoosh/pushwoosh-android-sdk)から、Android用のSDKをダウンロードします。（Download ZIPボタンをクリック）

この中にある「Pushwoosh.jar」ファイルを、自分のAndroidプロジェクトの app/libs/ディレクトリに配置。

## AndroidManifest.xml

以下を記述。
PW_APPIDは、pushwooshのApplicationCode。
PW_PROJECT_IDは、Google Developer Console の送信者ID（12桁の数字）に、先頭にAをつけたもの。つまり「A123456789012」みたいになります。
また、PACAGE_NAME は自身のアプリのパッケージ名に置き換えます。

```xml:AndroidManifest.xml
    <application>
        <meta-data android:name="PW_APPID" android:value="XXXXX-XXXXX" />
        <meta-data android:name="PW_PROJECT_ID" android:value="AXXXXXXXXXXXX" />
        <activity android:name="com.pushwoosh.richpages.RichPageActivity" />
        <activity android:name="com.pushwoosh.MessageActivity" />
        <activity android:name="com.pushwoosh.PushHandlerActivity" />
        <receiver android:name="com.pushwoosh.local.AlarmReceiver" />
        <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="PACKAGE_NAME" />
            </intent-filter>
        </receiver>
        <service android:name="com.pushwoosh.GCMListenerService" android:exported="false">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
            </intent-filter>
        </service>
        <service android:name="com.pushwoosh.GCMInstanceIDListenerService" android:exported="false">
            <intent-filter>
                <action android:name="com.google.android.gms.iid.InstanceID"/>
            </intent-filter>
        </service>
        <service android:name="com.pushwoosh.GCMRegistrationService" android:exported="false">
        </service>
    </application>

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.VIBRATE" />
    <permission      android:name="PACKAGE_NAME.permission.C2D_MESSAGE"  android:protectionLevel="signature"/>
    <uses-permission android:name="PACKAGE_NAME.permission.C2D_MESSAGE"/>
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
 
```

マニフェストが正しく書けたか心配な人は…
pushwooshの管理画面へ行くと、先ほどのEditボタンのそばに「Validate Manifest」というボタンが出来ているはずです。
そこをクリックし、今書いたAndroidManifest.xmlを選択すると、pushwoosh周りの記述抜けやワーニングなどを表示してくれるのでとても便利です。


## MainActivity.java

MainActivity.javaには、以下のように記述します。



```java:MainActivity.java

import com.pushwoosh.*;


@Override
public void onResume()
{
    super.onResume();
     
    //Re-register receivers on resume
    registerReceivers();
}
 
@Override
public void onPause()
{
    super.onPause();
 
    //Unregister receivers on pause
    unregisterReceivers();
}

@Override
protected void onNewIntent(Intent intent)
{
    super.onNewIntent(intent);
    setIntent(intent);
 
    checkMessage(intent);
}


//Registration receiver
BroadcastReceiver mBroadcastReceiver = new BaseRegistrationReceiver()
{
    @Override
    public void onRegisterActionReceive(Context context, Intent intent)
    {
        checkMessage(intent);
    }
};
 
//Push message receiver
private BroadcastReceiver mReceiver = new BasePushMessageReceiver()
{
    @Override
    protected void onMessageReceive(Intent intent)
    {
        //JSON_DATA_KEY contains JSON payload of push notification.
        showMessage("push message is " + intent.getExtras().getString(JSON_DATA_KEY));
    }
};
 
//Registration of the receivers
public void registerReceivers()
{
    IntentFilter intentFilter = new IntentFilter(getPackageName() + ".action.PUSH_MESSAGE_RECEIVE");
 
    registerReceiver(mReceiver, intentFilter, getPackageName() +".permission.C2D_MESSAGE", null);
     
    registerReceiver(mBroadcastReceiver, new IntentFilter(getPackageName() + "." + PushManager.REGISTER_BROAD_CAST_ACTION));        
}
 
public void unregisterReceivers()
{
    //Unregister receivers on pause
    try
    {
        unregisterReceiver(mReceiver);
    }
    catch (Exception e)
    {
        // pass.
    }
     
    try
    {
        unregisterReceiver(mBroadcastReceiver);
    }
    catch (Exception e)
    {
        //pass through
    }
}

private void checkMessage(Intent intent)
{
    if (null != intent)
    {
        if (intent.hasExtra(PushManager.PUSH_RECEIVE_EVENT))
        {
            showMessage("push message is " + intent.getExtras().getString(PushManager.PUSH_RECEIVE_EVENT));
        }
        else if (intent.hasExtra(PushManager.REGISTER_EVENT))
        {
            showMessage("register");
        }
        else if (intent.hasExtra(PushManager.UNREGISTER_EVENT))
        {
            showMessage("unregister");
        }
        else if (intent.hasExtra(PushManager.REGISTER_ERROR_EVENT))
        {
            showMessage("register error");
        }
        else if (intent.hasExtra(PushManager.UNREGISTER_ERROR_EVENT))
        {
            showMessage("unregister error");
        }
 
        resetIntentValues();
    }
}
 
/**
 * Will check main Activity intent and if it contains any PushWoosh data, will clear it
 */
private void resetIntentValues()
{
    Intent mainAppIntent = getIntent();
 
    if (mainAppIntent.hasExtra(PushManager.PUSH_RECEIVE_EVENT))
    {
        mainAppIntent.removeExtra(PushManager.PUSH_RECEIVE_EVENT);
    }
    else if (mainAppIntent.hasExtra(PushManager.REGISTER_EVENT))
    {
        mainAppIntent.removeExtra(PushManager.REGISTER_EVENT);
    }
    else if (mainAppIntent.hasExtra(PushManager.UNREGISTER_EVENT))
    {
        mainAppIntent.removeExtra(PushManager.UNREGISTER_EVENT);
    }
    else if (mainAppIntent.hasExtra(PushManager.REGISTER_ERROR_EVENT))
    {
        mainAppIntent.removeExtra(PushManager.REGISTER_ERROR_EVENT);
    }
    else if (mainAppIntent.hasExtra(PushManager.UNREGISTER_ERROR_EVENT))
    {
        mainAppIntent.removeExtra(PushManager.UNREGISTER_ERROR_EVENT);
    }
 
    setIntent(mainAppIntent);
}
 
private void showMessage(String message)
{
    Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
```

これでOKです。
なお、showMessageはテスト表示しているだけなので、本番アプリでは呼び出さないようにしましょう。

# テスト

アプリを一度起動してみましょう。起動するだけで登録されるはずです。
pushwoosh管理画面へ行き、Androidのところに人間が一人と表記されていれば成功です。
![スクリーンショット 2016-02-29 12.37.53.png](https://qiita-image-store.s3.amazonaws.com/0/98954/3b929965-6e36-758b-bca3-52c63c946ec7.png)

左のタブから「Send Push」を選択すると、以下の画面になります
![スクリーンショット 2016-02-29 12.39.49.png](https://qiita-image-store.s3.amazonaws.com/0/98954/27452502-a161-89dd-49f2-59c7983145b0.png)

真ん中のスペースに、送信したい文字列を登録。
フリーだとEnglishしか選べませんが、日本語を入れればちゃんと送れますのでご心配なく。
どのプラットフォームに送るかも選択できます。（このスクショの下部に映っている、「iOS」やドロイド君の上部のON/OFFスイッチ）

ここには映っていませんが、さらに下の画面に行けば
バッジ数の指定もできます。
また、通知を受け取ったユーザーの画面イメージもリアルタイムで表示されます。

問題なければ、右下にある「Woosh！」ボタンをクリック。

2、3秒ですぐ通知が端末に来ます。（アプリを閉じておく必要あり）

# うまくいかない時は

左タブの「Push History」タブを見ると、送った通知の結果が確認できます。
登録されていないのか、証明書が間違っているのか（iOSの場合よくある）、確認しましょう。

Successなのに来ていない時は、自分の端末の通知設定がOFFになっていることも考えられます。

公式のドキュメントは[こちら](http://docs.pushwoosh.com/docs/)