JPushで中国国内のAndroid端末にプッシュ通知するための初期調査

# はじめに

## 免責
**本記事は中国語サイトを自動翻訳しながら記述したものであり、内容が不正確であることをあらかじめご了承ください。本記事で記述されている、ネットワークサービスやライブラリの信頼性、セキュリティに関しても自己責任でご利用をお願いします。*「斜め」*の文字は、Googleで機械的に翻訳した日本語訳です。**


## JPushについて
通常日本でAndroidにプッシュ通知するにはGoogleのFCMを使用するかと思いますが、中国のインターネットはグレートファイアウォールで囲まれており、FCMからはネットワークアクセスできません。代わりに、JIGUANG（极光）のJPushが使えるということなので、このサービスでテスト端末にPush送信してみました。テストは日本国内で行なっていますが、普通のドコモのAndorid端末でpushを受け取れました。

# アカウント作成

## QQアカウントの作成
事前の準備としてJIGUANGのアカウント作成しますが、その際にQQの番号が必要となります。そのため先にQQアカウントを作成します。QQは、中国のメッセンジャーアプリです。

登録方法はいろいろありますが、英語のサイトがあったので今回はここからやります。
https://ssl.zc.qq.com/v3/index-en.html?from=pt


![qq.jpg](https://qiita-image-store.s3.amazonaws.com/0/88743/8a398afd-8e2c-b798-eb71-bb21052f28d1.jpeg)

NicknameとPasswordは、任意の値を入れてください。Telには、日本の国際番号81と携帯番号を入れます。携帯番号を1つしか持っていないので再確認できないのですが、上の3項目だけ入れれば、10桁くらいの数値のQQの番号がもらえたと思います。

この後の作業では特に不要ですが、発行されたQQの番号とパスワードは、Androidアプリの「QQ日本版」で使えます。



## JIGUANG（极光） アカウントの作成
https://www.jiguang.cn/accounts/register/form

**最初の画面**

![スクリーンショット 2017-08-18 18.37.16.png](https://qiita-image-store.s3.amazonaws.com/0/88743/6f371c01-e450-82ea-8a7a-02d53e87db4b.png)

上から、アカウント、メアド、パスワードが2回です。


**2つ目の画面**

![スクリーンショット 2017-08-18 19.44.52.png](https://qiita-image-store.s3.amazonaws.com/0/88743/aed6f7ec-ef16-4c41-11ca-da3b185f11a9.png)

最初の4項目を入力すると、自動的に2つ目の項目が出ます。
上から、名前、会社名、電話番号、QQの番号(数値)、CAPTCHA


[^1]: グレートファイアウォールは通称で、正式には、「金盾工程」(Golden Shield Project)と呼ばれます。


# JPushサービスを登録する

![スクリーンショット 2017-08-19 10.55.51.png](https://qiita-image-store.s3.amazonaws.com/0/88743/98a3263d-878a-1ca3-3dd1-58d8d69153b8.png)
JIGUANG（极光） https://www.jiguang.cn/ のサイトに行き、右上の「登录」でログインします。

ログイン後のメニューで、「开发者服务」>[「极光推送」](https://www.jiguang.cn/push)を選んで、次の画面で、「立即使用」を選択すると[サービスの管理画面](https://www.jiguang.cn/dev/#/app/list)が開きます。

![jpush.jpg](https://qiita-image-store.s3.amazonaws.com/0/88743/a0a4dd70-ba0a-4e5d-7da5-eedbcf3ea51b.jpeg)

「创建应用」(アプリケーションの作成)を押します。

![スクリーンショット 2017-08-19 11.27.07.png](https://qiita-image-store.s3.amazonaws.com/0/88743/1bf6374c-92fa-8546-b351-f6eba9b09769.png)

「应用名称」（アプケーション名）を入力します。「应用图标」（アプリケーションアイコン）はそのままで大丈夫です。今回はJPushTestAppで作成してみます。

![jpush2.jpg](https://qiita-image-store.s3.amazonaws.com/0/88743/5b204ee7-f964-8119-529c-1aa1b4a770f7.jpeg)

「AppKye」と「Master Secret」に表示されている数値は後で使用します。
2つ目のブロックの「推送设置」を押します。

![スクリーンショット 2017-08-19 11.37.35.png](https://qiita-image-store.s3.amazonaws.com/0/88743/2e119a4b-d043-dfee-40c1-12f63eb7ccc9.png)

次の画面で、应用包名にパッケージを設定後に、「提交」を押すと「下载Demo」からデモアプリがダウンロードできるようになります。今回はパッケージ名を「com.grachro.chinapush」にしました。

ダウンロードしたファイルの名前は JPushExample(6桁くらいの数値).zip で、解凍するとGradle/Eclipse構成のAndroidプロジェクトでした。プロジェクトをAndroid Studio（Version 2.3.3）の「Import project(Eclipse ADT, Gradle, etc)」で開くと、、、なにやらプロジェクト構成系のエラーが出て先に進めませんでした。

# Androidデモアプリ

## Androidデモアプリを作る

ダウンロードしたプロジェクトをAndroid Studioで開けなかったので、新規のプロジェクトで動かしてみます。

Android Studioで、New Projectを作成します。プロジェクト名とパッケージは、JPushのサービスで登録したのと同じ、「JPushTestApp」と「com.grachro.chinapush」にします。ここは未検証ですが、別にしてもいいのかもしれません。その他はディフォルトのままにしました。

![スクリーンショット 2017-08-19 15.10.14.png](https://qiita-image-store.s3.amazonaws.com/0/88743/fe485710-e530-d801-ca08-9441220c4219.png)

プロジェクトのスケルトンが作成できたら、先ほど解凍したJPushExample(xxxxxx)プロジェクトのファイルをコピペして移植してください。対象は5箇所です。

- AndroidManifest.xml（元のファイルは削除）
- src/main/java/以下すべて（元のファイルは削除）
- src/main/res以下すべて（元のファイルは削除）
- libのjarをlibへ
- libのjar以外の全てをsrc/main/jniLibsへ（jniLibsディレクトリは手動で作成）

移植が終わったら、Gradleリフレッシュをするとコンパイルが通ると思います。パッケージの辻褄が合わない等でコンパイルエラーになった場合は、手動で修正してください。AndroidManifest.xmlにJPUSH_APPKEYという項目がありますが、ここの値がサービス登録時に画面に表示されたAppKyeの値と一致しているハズです。




この状態で実機で動かすとアプリが立ち上がると思います。

## Androidデモアプリの実行
![android.png](https://qiita-image-store.s3.amazonaws.com/0/88743/ac618b71-a62a-9ff9-2bde-e074b0899f6d.png)

起動したデモアプリで、「get_Registration_Id」をタップするとRegIdが割り振られます。

# AndroidデモアプリへPush送信
## JIGUANGのWebコンソールからデモアプリへPush送信

公式サイトからAndroidデモアプリへpush送信してみます。

![push.png](https://qiita-image-store.s3.amazonaws.com/0/88743/bf6e920f-ac43-2039-b234-7f6944cc5d04.png)
ふたたび[JIGUANG（极光）](https://www.jiguang.cn/dev/#/app/list)のサイトへ行き、登録したアプリのページで「发送通知」をクリックします。
![push.png](https://qiita-image-store.s3.amazonaws.com/0/88743/676b2e5d-c89a-f1ee-d61e-2ea5fa5a7e7a.png)

「推送内容」「目标平台」「Registration ID」を入力します。「Registration ID」には、Android実機で割り振られたコードを入れてください。

「立即发送」>「发送吧!」の順にボタンを押すと、「推送成功，是否去查看推送记录？」のメッセージが表示されます。しばらくして、Android実機にpushメッセージが届くと成功です。

## JavaアプリからAndroidデモアプリへPush送信
公式サイトhttp://docs.jiguang.cn/jpush/server/3rd/java_sdk/ を頼りにJavaクライアントを作ってみます。意外と言ってはなんですが、SDKはMavenのセントラルリポジトリに登録されています。[GitHub](https://github.com/jpush/jpush-api-java-client)で公開もされていました。

```groovy:build.gradle
apply plugin: 'java'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile 'cn.jpush.api:jpush-client:3.3.0'
}
```

```java:SendApp.java
package sample;

import cn.jiguang.common.resp.APIConnectionException;
import cn.jiguang.common.resp.APIRequestException;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.audience.AudienceTarget;
import cn.jpush.api.push.model.notification.Notification;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SendApp {

    private static Logger logger = LoggerFactory.getLogger(SendApp.class);

    public static void main(String[] args) {
        //<<masterSecret>>と<<appKey>>は、公式サイトの管理画面で確認できます。
        JPushClient jpushClient = new JPushClient("<<masterSecret>>", "<<appKey>>");

        //<<registrationId>>は、Android実機のデモアプリに払い出されたID
        AudienceTarget target = AudienceTarget.registrationId("<<registrationId>>");
        Audience audience = Audience.newBuilder().addAudienceTarget(target).build();

        PushPayload payload = PushPayload.newBuilder()
                .setPlatform(Platform.android())
                .setAudience( audience)
                .setNotification(Notification.android("from日本", "Hello🐼中国！！", nul)
                .build();

        try {
            PushResult result = jpushClient.sendPush(payload);
            logger.info("Got result - " + result);

        } catch (APIConnectionException e) {
            logger.error("Connection error, should retry later", e);

        } catch (APIRequestException e) {
            logger.error("Should review the error, and fix the request", e);
            logger.info("HTTP Status: " + e.getStatus());
            logger.info("Error Code: " + e.getErrorCode());
            logger.info("Error Message: " + e.getErrorMessage());
        }
    }

}
```

実行するとデモアプリにpushメッセージが届きます。
![push.jpg](https://qiita-image-store.s3.amazonaws.com/0/88743/7b6141d9-e507-8126-79f2-46019a0ba41d.jpeg)

# JCenterのライブラリを使用して最小限の構成でアプリを作る
公式サイトのドキュメントを探すとAndroid SDKについてのマニュアルが見つかります。
https://docs.jiguang.cn/jpush/client/Android/android_sdk/

- [Android SDK 概述](https://docs.jiguang.cn/jpush/client/Android/android_sdk/) *SDKの概要*
- [3 分钟 Demo](https://docs.jiguang.cn/jpush/client/Android/android_3m/) *3分デモ*
- [Android SDK 集成指南](https://docs.jiguang.cn/jpush/client/Android/android_guide/) *Android SDKの統合ガイド*
- [Android SDK 调试指南](https://docs.jiguang.cn/jpush/client/Android/android_debug_guide/) *Android SDKのデバッグガイド*
- [Android SDK 进阶教程](https://docs.jiguang.cn/jpush/client/Android/android_senior/) *Android SDKの高度なチュートリアル*
- [Android SDK API](https://docs.jiguang.cn/jpush/client/Android/android_api/) *Android SDKのAPI*
- [Android SDK FAQ](https://docs.jiguang.cn/jpush/client/Android/android_faq/) *Android SDKのFAQ*

このマニュアルを眺めていると、「Android SDK 集成指南」ページに、「[jcenter 自动集成步骤](https://docs.jiguang.cn/jpush/client/Android/android_guide/#jcenter)」(*jcenter自動積分ステップ*)と、「[手动集成步骤](https://docs.jiguang.cn/jpush/client/Android/android_guide/#_5)」(*手動統合手順*)という項目が見つかります。先ほどのデモアプリでjarファイルやAndroidManifest.xmlを移植しましたがこれは、手動に該当するようです。JCenterの自動の方が簡単そうなので試してみます。

## 1.デモアプリの時と同じように、Android Studioで、New Projectを作成

ディフォルトのままで特に設定変更不要です。

## 2.build.gradleにJPushの依存を追加

```groovy:app/build.gradle
apply plugin: 'com.android.application'

android {
    //中略
    defaultConfig {
        applicationId "com.grachro.chinapush.jpushminimum" //＜＜JPushサービス登録したパッケージに合わせる
        //中略


        //ndkを追加
        ndk {
            //选择要添加的对应cpu类型的.so库。
            abiFilters 'armeabi', 'armeabi-v7a', 'armeabi-v8a'
            // 还可以添加 'x86', 'x86_64', 'mips', 'mips64'
        }

        //manifestPlaceholdersブロックを追加
        manifestPlaceholders = [
                JPUSH_PKGNAME : applicationId,
                JPUSH_APPKEY : "ここにAppKey", //JPush上注册的包名对应的appkey.
                JPUSH_CHANNEL : "developer-default", //暂时填写默认值即可.
        ]
    }
    buildTypes {
        //中略
    }
}

dependencies {
    //中略
    compile 'cn.jiguang.sdk:jpush:3.0.3'  // 此处以JPush 3.0.3 版本为例。 ＜＜ここを追加
    compile 'cn.jiguang.sdk:jcore:1.1.1'  // 此处以JCore 1.1.1 版本为例。 ＜＜ここを追加
}
```

- applicationIdを変更。
- ndkを追加。
- manifestPlaceholdersを追加。JPUSH_APPKEYを変更。
- dependenciesに2ライブラリ追加


## 3.アプリ起動時にJPushInterfaceを初期化


```java:MainActivity.java
package com.grachro.chinapush.jpushminimum;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import cn.jpush.android.api.JPushInterface;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //3行追加
        JPushInterface.setDebugMode(true);
        JPushInterface.init(this);
        Log.i("MainActivity",JPushInterface.getRegistrationID(this));
    }
}
```

MainActivityで、JPushInterfaceを初期化して、RegistrationIDを取得します。RegistrationIDは、本来であればサーバーサイドで管理する必要がありますが、今回はデバッグログに出して終わりです。


## 4.サーバーサイドでPush送信
アプリを実機で起動して、先ほどと同じように、WebコンソールかJavaアプリからPush送信すると、アプリでPushが受け取れます。

Manifestファイルも一切変更しないでPushを受信できましたが、これでいいのでしょうか。。

# 最後に
送信対象をタグ付けしたり、AndroidでPushを受け取った場合の制御をしたりできると思われますが、今回はここで終了します。また調査が進んだら追記するか、別ページを作るかもしれません。