LoginSignup
4
6

More than 5 years have passed since last update.

KiiCloudを使ったPush通知について

Posted at

プッシュ通知

概要

本投稿は「Kiicloudのユーザー間のプッシュ通知(Android)」について書きます.
前回記事

github

volleyとkiicloudのライブラリを設定の上、以下のパラメータを設定するとログインユーザーがTARGET_IDに指定したユーザーに対し、プッシュ通知を送信できます。
サンプルプロジェクト

ApplicationValue.java
//以下のIDとKEYを設定するとTARGET_IDのuserへプッシュ通知が送れます。
// TODO:APP_IDとAPP_KEYはKiiCloudでアプリケーションを作成した際に発行された値に書き換えてください。
    public static final String APP_ID = "your App ID";
    public static final String APP_KEY = "your App Key";
    // TODO:Google Developers Console Project ID SENDER_IDはGCMの設定を有効にした際に発行された値に書き換えてください。
    public static final String SENDER_ID = "your Project ID";
    // TODO:送信したいtest用のuserのID。
    public static final String TARGET_ID = "TEST USER ID";

プッシュ通知の種類

KiiCloudのプッシュ通知は、GCM、APNS、JPush のアプリケーションサーバを想定した実装モデルを採用しているそうです。
Kii Cloud では、以下の3つのプッシュ通知を利用できます。
参考


プッシュ通知

サーバ上変更のプッシュ通知 (Push To App):
購読済みの Bucket 内の更新をプッシュ通知として受け取ります。

ユーザープッシュ通知 (Push to User):
購読済みのトピックへのメッセージをプッシュ通知として受け取ります。

運用者メッセージのプッシュ通知 (Direct Push):
開発者ポータルからアプリ開発者がプッシュ通知を送信します。

今回はグループに招待するためにプッシュ通知を利用したいので,ユーザープッシュ通知を使用します.
参考:ユーザープッシュ通知について

実装

プロジェクト,GCMの設定

以下参考は開発者ポータルからのプッシュ通知ですが,設定周りは大体同じなので,1-7を設定します.
参考:Android (GCM) プッシュ通知設定チュートリアル
Android (GCM) プッシュ通知設定チュートリアル
1. Android アプリの作成
2. Google プロジェクトの作成
3. Google Cloud Messaging の設定
4. Kii Cloud の設定
5. ビルド環境の設定
6. マニフェストの設定
7. プログラムの実装(受信側の設定)

送信の実装

参考:Kii Cloudを用いたチャットアプリケーションの開発 [その4] ―メッセージ送受信機能の実装

トピックの作成

トピックは、プッシュメッセージを送信するためのチャンネルの役割を果たします。あるトピックに興味のあるユーザーは、このトピックを購読することにより、以後このトピックに送信されたプッシュメッセージを受信できます。
参考:トピックとは

UserActivity.java
//ログイン時のアクティビティーに記述
//....省略
//push通知用のtopicを作成
    private void createPushTopic(final KiiUser user) {
        Log.d("pushTopic", user.getUsername());
        // GCMの設定
        try {
            installGCMRegistrationID();
            Log.d("GCM", "セッティング");
        } catch (Exception e) {
            e.printStackTrace();
        }
        final KiiTopic topic = KiiUser.topic(ApplicationValue.TOPIC_INVITE_NOTIFICATION);
        // Save the topic to Kii Cloud
        topic.save(new KiiTopicCallBack() {
            @Override
            public void onSaveCompleted(int taskId, KiiTopic target, Exception exception) {
        //////////////////////////                
        //トピックの ACL を変更する
        //////////////////////////                
            }
        });

    }

    //GCMの設定
    private void installGCMRegistrationID() throws Exception {
        String registrationId = GCMUtils.register(senderID);
        KiiUser.pushInstallation().install(registrationId);
    }

参考:トピックの作成

トピックのACLを変更する

トピックにプッシュメッセージを送信するための権限を付与します。

UserActivity.java
//上記コードの  //トピックの ACL を変更する部分
//....省略
// Save the topic to Kii Cloud
        topic.save(new KiiTopicCallBack() {
            @Override
            public void onSaveCompleted(int taskId, KiiTopic target, Exception exception) {
                if (exception != null) {
                    // Error handling
                    Log.d("topic err", exception.toString());
                    return;
                }
                KiiACL acl = topic.acl();
                //権限付与
                acl.putACLEntry(new KiiACLEntry(KiiAnyAuthenticatedUser.create(), KiiACL.TopicAction.SEND_MESSAGE_TO_TOPIC, true));
                acl.save(new KiiACLCallBack() {
                    @Override
                    public void onSaveCompleted(int token, KiiACL acl, Exception exception) {
                        if (exception != null) {
                            // Error handling
                            Log.d("topic err acl", exception.toString());
                            return;
                        }
                        KiiPushSubscription subscription = user.pushSubscription();
                        subscription.subscribe(topic, new KiiPushCallBack() {
                            @Override
                            public void onSubscribeCompleted(int taskId, KiiSubscribable target, Exception exception) {
                                if (exception != null) {
                                    // Error handling
                                    Log.d("topic err subscription", exception.toString());
                                    return;
                                }
                            }
                        });
                    }
                });

            }
        });

参考:トピックの ACL を変更する

GCMの準備(Google Cloud Messaging)

参考:GCMの設定

MainActivity.java

//senderIDはGoogle Developers Consoleのproject ID
//ログイン後のKiiUserを取得後に記述
//SharedPreferences に GCM から取得した登録 ID を文字列として保存
    private void registerGCM(final KiiUser user) {
        new AsyncTask<Void, Void, String>() {
            @Override
            protected String doInBackground(Void... params) {
                try {
                    // call register
                    String regId = gcm.register(senderID);

                    // install user device
                    boolean development = false;
                    user.pushInstallation(development).install(regId);

                    // if all succeeded, save registration ID to preference.
                    GCMPreference.setRegistrationId(MainActivity.this.getApplicationContext(), regId);
                    Log.d("regId", regId);
                    return null;
                } catch (Exception e) {
                    // Error Handling
                    Log.d("registerGCM", e.toString());
                    return null;
                }
            }
        }.execute();
    }

GCMPreference.java

public class GCMPreference {
    private static final String PREFERENCE_NAME = "KiiTest";
    private static final String PROPERTY_REG_ID = "GCMregId";

    public static String getRegistrationId(Context context) {
        SharedPreferences prefs = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
        String registrationId = prefs.getString(PROPERTY_REG_ID, "");
        return registrationId;
    }

    public static void setRegistrationId(Context context, String regId) {
        SharedPreferences prefs = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putString(PROPERTY_REG_ID, regId);
        editor.commit();
    }
}

メッセージの送信

MainActivity.java

//受け取るときにApplicationValue.SEND_MESSAGE_INTENTを使います。
//受信すると"Hello push 受信したよ!!"のToastがでます。
//push通知 sendMessage
    private void sendMessage() {
        final KiiUser target = KiiUser.userWithID(targetID);
        //ユーザーの取得
        target.refresh(new KiiUserCallBack() {
            @Override
            public void onRefreshCompleted(int token, Exception exception) {
                if (exception != null) {
                    // Error handling
                    Log.d("Refresh err", exception.toString());
                    return;
                }

                KiiTopic topic = target.topicOfThisUser(TOPIC_INVITE_NOTIFICATION);
                Log.d("target topic", topic.getName());

                KiiPushMessage.Data data = new KiiPushMessage.Data();
                data.put(ApplicationValue.SEND_MESSAGE_INTENT, "Hello push 受信したよ!!");
                KiiPushMessage message = KiiPushMessage.buildWith(data).build();
                // Send the push message.
                topic.sendMessage(message, new KiiTopicCallBack() {
                    @Override
                    public void onSendMessageCompleted(int taskId, KiiTopic target, KiiPushMessage message, Exception exception) {
                        if (exception != null) {
                            // Error handling
                            Log.d("SendMessage", exception.toString());
                            return;
                        }
                        Log.d("送信完了", "success");
                    }
                });

                // check whether user is disabled.
                boolean disabled = target.disabled();
                if (target.isLinkedWithSocialProvider(KiiSocialNetworkConnector.Provider.FACEBOOK)) {
                    // User is linked to the Facebook account.
                }
                if (target.isLinkedWithSocialProvider(KiiSocialNetworkConnector.Provider.TWITTER)) {
                    // User is linked to the Twitter account.
                }

            }
        });
    }

受信の実装

onReceiveの実装

BroadcastReceiverのonReceive() を実装します。
以下ではswich文でプッシュ通知の種類を分岐してありますが、本投稿ではユーザー間のプッシュ通知なので「PUSH_TO_USER」の部分しか動作しません。
参考:メッセージを受信する

KiiPushBroadcastReceiver.java
public class KiiPushBroadcastReceiver extends BroadcastReceiver {
        public KiiPushBroadcastReceiver(){
    }

    @Override
    public void onReceive(final Context context, final Intent intent) {
        Log.d("onReceive", "received push message");
        if (KiiUser.getCurrentUser() == null) {
            // ログイン中でない場合は何もしない
            Log.d("onReceive", "user null return");
            return;
        }
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
        String messageType = gcm.getMessageType(intent);
        if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
            final Bundle extras = intent.getExtras();
            final ReceivedMessage message = PushMessageBundleHelper.parse(extras);
            PushMessageBundleHelper.MessageType type = message.pushMessageType();
            switch (type) {
                case DIRECT_PUSH:
                    Toast.makeText(context, "DIRECT_PUSH", Toast.LENGTH_LONG).show();
                    Log.d("onReceive", "DIRECT_PUSH");
                    return;
                case PUSH_TO_APP:
                    Log.d("onReceive", "PUSH_TO_APP");
                    Toast.makeText(context, "PUSH_TO_APP", Toast.LENGTH_LONG).show();
                    try {
                        Log.d("onReceive", "PUSH_TO_USER");
                    } catch (Exception e) {
                    }
                    break;
                case PUSH_TO_USER:
                    // ユーザー間のプッシュ通知
                    Log.d("onReceive", "received PUSH_TO_USER");
                    String getMessage = extras.getString(ApplicationValue.SEND_MESSAGE_INTENT);
                    sendBroadcast(context, ApplicationValue.ACTION_RECEIVED_INTENT, getMessage);
                    Toast.makeText(context, "PUSH_TO_USER: " + getMessage, Toast.LENGTH_LONG).show();
                    break;
            }
        }
    }

    /**
     * プッシュ通知を受信したことをBroadcast Intentを使ってActivityに通知します。
     *
     */
    private void sendBroadcast(Context context, String action, String message) {
        Intent intent = new Intent(action);
        intent.putExtra(ApplicationValue.GET_MESSAGE_INTENT, message);
        context.sendBroadcast(intent);
    }

}


Activityで取得

受け取れた場合、「push通知:hogehoge」みたいなToastが出ます。

MainActivity.java
//KiiPushBroadcastReceiverから受信したメッセージをActivityで取得
    private final BroadcastReceiver handleNewReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String message = intent.getStringExtra(ApplicationValue.GET_MESSAGE_INTENT);
            Toast.makeText(context, "push通知:"+ message, Toast.LENGTH_LONG).show();
            Log.d("push通知",  message);
        }
    };

    @Override
    public void onResume() {
        super.onResume();
        registerReceiver(this.handleNewReceiver, new IntentFilter(ApplicationValue.ACTION_RECEIVED_INTENT));
    }

    @Override
    public void onPause() {
        super.onPause();
        unregisterReceiver(this.handleNewReceiver);
    }


Manifestの設定

receiverが必要です。

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.luky_ponies.pushtest" >

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <permission android:name="com.luky_ponies.pushtest.permission.C2D_MESSAGE" android:protectionLevel="signature" />
    <uses-permission android:name="com.luky_ponies.pushtest.permission.C2D_MESSAGE" />

    <application
        android:name=".VolleyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

        <activity
            android:name=".UserActivity"
            android:label="UserActivity"></activity>

        <!-- *** add following lines *** -->
        <receiver android:name="com.luky_ponies.pushtest.KiiPushBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
                <category android:name="com.luky_ponies" />
            </intent-filter>
        </receiver>

    </application>

</manifest>


送信の検証

注意

メッセージの送信を検証するためには,実機を2台使うのが理想的です.genymotionを用いた実験では実機→エミュレータでは送信と受信は可能ですが,エミュレータ→実機では送信ができないことが注意です.
エミュレータではregisterGCMのメソッド部分でエラーが出て登録ができていないようです.

メッセージの送信機能でグループに追加

このプッシュ通知にuserIDなどをのせて通知を行えば、グループのメンバーの追加ができるかと思います。
前回記事

4
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6