【はじめてのAndroidアプリ開発】プッシュ通知



【はじめてのAndroidアプリ開発】プッシュ通知

Androidのアプリ開発をはじめようと考えている方、もしくははじめたばかりの方向けにお届けしている 【はじめてのAndroidアプリ開発】 シリーズ。 今回は 『プッシュ通知』の実行方法をご紹介。

プッシュ通知の取扱いに合わせて、Firebaseファイアベースの使い方も合わせて学習できますよ。

★本稿はこんな方に役立ちます★

  • Android アプリ開発初心者
  • 参考書を開いて、フリーズした方
  • プッシュ通知を利用したい方
  • Firebaseを試したい方

★今回使用する環境等★

  • エミュレーター/ Android 9 (Pie) API 28
  • プログラミング言語/ Java
目次
  1. 【はじめてのAndroidアプリ開発】プッシュ通知
  2. 今回作成するプッシュ通知機能搭載のアプリについて
  3. Firebaseについて
  4. Firebaseのプッシュ通知について
  5. プッシュ通知のエミュレーター環境
  6. プッシュ通知機能搭載のアプリを作る様子
  7. FirebaseとAndroid Studioと公式ドキュメント
  8. 開発するアプリと Firebase を接続
  9. プッシュ通知の設定
  10. プッシュ通知のプログラム
  11. Firebaseからメッセージを送信
  12. アイコンを設定
  13. Firebaseのプロジェクト削除
  14. まとめ

【はじめてのAndroidアプリ開発】プッシュ通知

今回作成するプッシュ通知機能搭載のアプリについて

image

今回作成するプッシュ機能搭載のアプリは、 Firebase にてプッシュ通知を操作。そして送った通知は、アプリ利用中の方、もしくはメモリー下にアプリがおかれているデバイスを対象に通知。 そして通知する内容は、簡単なテキスト・スタイルのものとしました。

Firebaseについて

image

https://firebase.google.com/

まず今回利用する Firebase について簡単にご紹介。 Firebase は、 Google 社が運営するアプリ用開発プラットフォーム。 Firebase を利用すると、以下のような機能を無料でアプリに実装できます。

  • データベース
  • 統計(アナリティクス)
  • 通知機能
  • ログイン機能
  • 機械学習機能
  • 予測機能
  • アプリのクラッシュ状況確認
  • A/Bテスト etc

こんなにたくさんの機能を無料で利用できるって、さすが Google って感じですね。

また Firebaseは、 Web(クラウド)上で操作しますので、 Androidでも iOS でも Unityでも ハイブリッド型アプリでも利用可能。もはやアプリ開発のインフラ的な存在ともいえますので、使い方を知っておくと様々な場面で役立つと思います。

Firebaseのプッシュ通知について

image

アプリを作成する時に、Firebase対応のプッシュ通知機能を組み込んでおくことで、ブラウザ画面からいつでもプッシュ通知を設定することが可能。プッシュ通知の設定科目としては以下のようなものがあります。

  • テキスト内容
  • ターゲットの指定(Topic や Channel)
  • 通知の予約
  • 開封状況などのリアクション確認
  • 有効期限
  • 通知音の有無

そして Firebase を使って発信した通知は、端末の状況によって通知が表示される場合と表示されない場合が存在。例えばアプリを起動していればプッシュ通知は表示されますが、アプリを立ち上げていなければブッシュ通知は表示されません。

このあたりのことは、バックグラウンドで常時稼働するようにアプリを設定すればいいのですが、アプリ開発の初期段階でバックグラウンド処理はちょっと難しい内容。 そしてまた 2019年 1月 からは、 FCM(Firebase Cloud Messaging)はバックグラウンド下に置かれているアプリに対しては通知をしないと宣言*

そうしたことから今回は Firebaseに慣れ、プッシュ通知を体験するということを目的に、一番簡単に設定できる「起動中のアプリに対してテキストのプッシュ通知を発信」していくことにしました。

プッシュ通知のエミュレーター環境

image

これから作成していく「プッシュ機能搭載のアプリ」をテストする環境は、実機をお勧めします。理由はエミュレーターのセットアップによっては、プッシュ通知が届かないためです。

通常新規でエミュレーターを起動すると Android のセットアップが起動し、アカウント情報なども入力する必要があります。しかし本当のスマホとは違うエミュレーターで、アカウント情報を入力されている方は少ないのではないでしょうか。セットアップができてない・・・・・、もしくは中途半端・・・・な状況ですと、正しくアプリが開発されて正しく Firebase のプッシュ通知が設定されていても、その通知が端末に届くことはありません。

以上のことより、プッシュ通知のテストは実機を用いてお試しすることを勧めます。

プッシュ通知機能搭載のアプリを作る様子

今回ご紹介するプッシュ通知機能対応のアプリを制作している様子です。Google で「firebase android notification」と検索すると、いくつかのチュートリアルが表示。20種類ほどプッシュ通知のチュートリアルを確認しましたが、どれも作り方は違いました。また実際に紹介されているコードを入力してもうまくいかないケースもありますし、 Firebaseの管理画面が古かったり、 Android Studio のバージョンが低かったりして、テストしていても常に不安。

そのため今回は、今後 Firebase の管理画面が変わったり、 Android Studio のバージョンが変わっても、プッシュ通知機能を利用できるように公式ドキュメントをテキストとして、プッシュ通知の実装方法をご紹介することとしました。

FirebaseとAndroid Studioと公式ドキュメント

image

「Firebase、どうやって使うんだ?」 と思って Google で情報収集しようとすると、ちょっと疲れるかもしれません。理由は、 Firebase の設定方法が一つではないからです。

【Firebaseの設定方法の例】

  • Android Studio から設定
  • Firebase の管理画面から設定
  • Firebase の公式ドキュメントに従って設定

Firebase の設定方法は、上記の 3例が代表的と思いますが、どれも手順は違いますし、実行した結果も異なります。例えば Android Studio から設定する方法は簡単ですが、 SDK が足りないとエラーが出たり、バージョンが古いと黄色いエラーが出たりなど。

【Tools → Firebase → Cloud Messaging から設定した直後の画面】

image

それぞれの設定方法の特徴をまとめると、以下のようになりました。

設定方法 特徴
Android Studioから 2回のクリックでFirebaseの設定が完了、と思いきや、いくつかのエラー解消が必要に。
Firebaseの仕組みを理解していれば大丈夫ですが、Firebase初心者には分かりにくいエラーです。
Firebaseに慣れてきてから使うことを勧めます。
Firebaseの管理画面から 設定に必要なコードをAndroi Studio側に貼り付けたりと、いくつか手作業が必要ですが、どんな設定が必要になるのか把握することができます。
他の Firebaseチュートリアルを見る時に、何が今のバージョンと合っていないか、など応用を利かすことが可能に。
Firebaseの利用初期にオススメの設定方法です。
公式ドキュメントから 注意点や関連情報なども詳しく書かれていていいのですが、ちょっと文章量が多く読みにくいです。
エラーが発生したときや機能を把握したい時におすすめですね。

以上のことから、今回は Firebase の管理画面から手順を把握し、プッシュ通知に必要な設定を行っていくことにしました。

開発するアプリと Firebase を接続

Firebaseを確認

image

Google検索で「firebase console」 検索後に「Firebase Console」を選択、 もしくは https://console.firebase.google.com/ に直接アクセス。

image

Firebaseのコンソール画面。早速 「Add Project」 をクリック。

image

新規プロジェクト作成に必要な情報が求められますので、 Project name を入力し、利用規約等にチェック。そして最後に Create project を選択。

この時入力するプロジェクト名は、 Firebase 管理画面で扱っていく名称であり、 Android Studio のプロジェクト名と違っても大丈夫です。

image

プロジェクトの作成が完了したら、 Continue をクリック。すると Firebase のプロジェクト管理画面が開きます。

image

画面上部に現在のプロジェクト名「PushDemo007」が表示されて、画面左がメニューバーになります。プッシュ通知は、左サイドバーの「Grow」内にある 「Cloud Messaging」 から操作。

まずはこの Firebase と Androidアプリを接続する必要がありますので、アンドロイドのマーク「ドロイド君」をクリック。

image

ドロイド君をクリックするとアプリの登録画面が表示。3項目中 一番上の項目「Android package name」 のみ必須であとは任意の設定。まずはこの「Android package name」を入力、ですがこれには Android Studio で新規プロジェクトを作成する必要があります。

image

Android Studio を起動して、新規プロジェクトを作成。

image

Empty Activity。

image

プロジェクト名を入力して、Javaを選択、 Finish。今回プロジェクト名は、「MyPushDemo001」としました。

image

それで Firebase に入力する「Android package name」 は、 manifests フォルダ下にある AndroidManifest.xml 内を確認する必要が。 AndroidManifest.xml を開くと上から 3行目に

package="com.example.mypushdemo001"

と書かれた項目があります。この com.example.mypushdemo001 が、 Android package name になります。コピーして、 Firebase に貼り付けましょう。

image

そして今回はオプション設定はスルーして、 「Register app」 をクリック。すると次の設定へ画面が進みます。

image

こちらは Firebase と Android アプリを接続するために必要な、 JSONファイルの設定。画面に表示されている「Download google-service.json」をクリックして、 JSONファイルをダウンロード。そしてダウンロードされた google-services.json をコピー。

image

コピーした google-services.json ファイルは、 Project 下の app 内に貼付け(上図参照)。JSONファイル貼付け後、 JSONファイル内のコードも確認できますので、どんなことが書かれているかざっと見ておくといいでしょう。

そして再び Firebase の画面に戻って、 Nextボタンをクリック。

image

すると今度は設定に必要なコードが表示。表示されている 3つのコードをコピーして、 Android Studio の Gradle ファイルに貼付け。

まずは一番上のコードをコピーして、 Projectレベルの build.gradle 内に貼付けます。ちなみにこれらのコードは、 プラグインや SDKの読み込みを意味するもの。

image

一番上のコード

classpath 'com.google.gms:google-services:4.0.1'

を Project レベルの build.gradle に貼り付けたところ、貼り付けコードは黄色エラーで、画面右上には 「Sync Now」 が表示。ここではまず、貼り付けたコードにマウスカーソルを合わせて、 Alt + Enterキーでエラーハンドリング。今回のケースは、バージョンを 4.2.0 に上げてくださいとのこと。

image

バージョンを変更すると

classpath 'com.google.gms:google-services:4.2.0' 

上の黄色エラーは消えるでしょう。 Sync Now は、今行っても OKですし、後でまとめてやっても OK。今回は今 Sync Now してみました。

image

Sync Now したところ、画面上のエラーが消えてキレイになりました。個人的には設定を変える度に Sync Now する方が、エラーを把握しやすいと思います。

次は再び Firebase の画面に戻って、今度は Appレベルの build.gradle コードをコピー。

image

Appレベルの build.gradle へコードを追加したところ、先ほどと同じようにエラーが。エラー表示部分で Alt + Enter キーでエラーを確認すると、前回同様バージョンに関するもの。 バージョンを更新して、 Sync Now したところ再び support に関する行でエラーが発生。

image

suppress:add//noinspection gradle

ということで、バージョン関係でこのようなエラーが表示されている様子。suppress:add//noinspection gradle をクリックして、エラーを抑えます。

そして Sync Now をクリックして、 Gradle を更新。再び Firebase の画面に戻って、 Nextボタンをクリック。

image

すると設定した Androidアプリ起動してくださいとのこと。 Firebase と アプリがつながるか、 Firebaseの設定が正しく行われたかチェックしてくれます。

Android Studio のエミュレーターを起動してみましょう。

image

エミュレーターを起動し、10〜20秒ほど待つと、 Firebase の画面に 設定完了の旨が表示。これで Androidアプリに Firebase の基本的な設定ができました。ただ、これだけでは プッシュ通知やアナリティクスの機能は使えません。利用したい機能のプログラムをアプリ側に設定する必要があります。

一旦 「Continue to console」 ボタンで管理画面に戻ってみましょう。

image

プロジェクト PushDemo007 に対して、 Android アプリ com.example.mypushdemo001 がセットされたことが確認できます。他の Android アプリや iOS アプリ、 Unity など他の環境下のアプリも同時に 管理したい場合は、 「Add App」で追加可能。

今回は 1つのアプリを対象にプッシュ通知テストを行います。左サイドバーの Grow → Cloud Messaging をクリック。

プッシュ通知の設定

image

Firebase のプロジェクト管理画面から Grow → Cloud Messaging をクリックすると、 Cloud Messaging の管理画面に。今回はまだメッセージ機能の設定ができていませんので 「How do I get Started?どうやって使うの?」 をクリック。

image

画面移動後、英語表示であれば、ページ最下部で言語変更可能。とりあえず左サイドバーで 「Android」 を選択し、「Androidクライアントを設定する」を選択。

すると最初にメッセージ機能を使うために必要な SDK の設定コードが紹介されてきます。書かれている通りにコピーして、アプリレベルの build.gradle に追加しましょう。

image

指定コード

implementation 'com.google.firebase:firebase-messaging:17.3.4'

をアプリレベルの build.gradle に追加すると、貼り付けたコードに対して黄色エラー。 Alt + Enter キーでバージョンを更新し、 Sync Now で Gradle を整えましょう。

image

メッセージ機能の SDK のバージョンが 17.3.4 から 17.6.0 に更新されましたね。

image

次はマニフェストの設定。一見するとコードだけ書かれていて、どこに貼り付ければいいか分かりません。そんな時は コード右下のファイル名をクリック。すると GitHubのサンプルコードのページに飛びます。 AndroidManifest.xml 全般のコードが書かれていて、今回使うコードにピンポイントで移動してくれますので、自分のアプリのマニフェストファイルのどこにコードを貼り付ければいいか簡単に理解することが可能。

image

早速、参考コード

<service android:name=".java.MyFirebaseMessagingService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

を AndroidManifest.xml に貼り付けるものの、上図のように赤色エラー。これは赤色の .java.MyFirebaseMessagingService クラスがないね、というエラー。

あとで .java.MyFirebaseMessagingService を作成しましょう。

image

設定ページを進めますと、次はオプション設定。設定しなくても大丈夫な項目なので、今回は飛ばします。また以下の内容はトークンに関するもの。テストメッセージなどでは必要な設定ですが、今回はパス。

次は「メッセージを受信する」の項目に移動。

image

プッシュ通知のプログラム

image

アプリが Firebase から発信される通知を受け取り、表示するためにはアプリ内に適切な設定を行う必要があります。公式ドキュメント を参考に作業開始。

まず設定の概要は、目次にあるとおり

  • マニフェストの設定
  • onMessageReceivedクラスの設定
  • on DeletedMessagesクラスの設定
  • バックグラウンド下のアプリについて

今回は onMessageReceived クラスの設定まで行います。

まずはマニフェストに必要なコードを追加。 また?と思うかもしれませんが、内容を確認。

image

指定コード

<service android:name=".java.MyFirebaseMessagingService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

はい、これは Firebase とアプリの接続設定で追加したコードと同じですね。重複した内容です。 Firebase のドキュメントではこのようによく重複した内容が登場します。

コードが重複するとエラーも重複し、ややこしくなるので注意しましょう。

【重複したコード】

image


image

次はメッセージの受信を制御するプログラムの設定。上記のようなコードを入力する必要があるのですが、ファイル名は MyFirebaseMessagingService.java 。現在のアプリにこのようなファイルはありませんので、新規クラスの作成を行う必要が。

image

上図のように新規クラス MyFirebaseMessagingService を作成し、指定コードを貼り付けるものの、エラーだらけ。まずは RemoteMessage や Log などは必要な class がないというエラーなので、マウスカーソルを合わせて Alt + Enter キーでクラスをインポート。

image

そして一旦ここで GitHub のサンプルコードと照らしあわせてみると、 FirebaseMessagingService クラスが継承されていなかったり、 TAGプロパティがセットされていなかったりといくつかのミスポイントが確認できます。

GitHub のサンプルを元にコードを更新。

image

MyFirebaseMessagingServiceクラスで FirebaseMessagingService クラスを継承したところ、クラス名にエラー発生。これは前に設定した AndroidManifest.xml 内の name のこと? というエラー。 AndroidManifest 側の name を

.MyFirebaseMessagingService

にセットし直しましょう。

image

schedulejob() と handleNow() というメソッドの定義がない、とエラー。 GitHub のコードを参考にしてもいいのですが、これはなくてもいいので消しちゃいます。

image

MyFirebaseMessagingServiceクラスのコード

import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "【Firebaseテスト中】";

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        // TODO(developer): Handle FCM messages here.
        Log.d(TAG, "From: " + remoteMessage.getFrom());

        if (remoteMessage.getNotification() != null) {
            Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
        }

    }
}

image

エミュレーターを起動するとエラーなくアプリが起動。ただし私の場合、エミュレーター上では Android のセットアップが完了していません。この状態では Firebase からのメッセージを受け取れませんでした。そのため実機を接続し、作成したアプリを実機で起動。

image

実機の場合は、 Android のセットアップが完了していますので、 Firebase からのメッセージを受け取れそうです。

Firebaseからメッセージを送信

image

再び Firebase の管理画面に戻って、メッセージを送信してみましょう。とりあえず 「Send your first message」 をクリック。

image

Title 部分と Text 部分に文字を適当に入力して、 Nextボタン。

image

次は、送信先に関する設定。

大分類として 「User segment」 「Topic」 があり、User segment は送信先アプリを個別に指定でき、 Topic は特定のキーワードがセットされたアプリに対して送信。

今回は簡単な User segment を利用し、対象アプリは com.example.mypushdemo001 を設定。

あとはメッセージの送信するタイミングやコンバーション(反応)、通知音などの設定なのでこれはデフォルトのままでいきます。

image

ページ最下部の Review をクリックし、Publish をクリック。すると管理画面に送信履歴が表示されます。

image


image Firebase からメッセージ送信後、 Android Studio の Logcat を確認すると、設定したメッセージが書かれています。これで Firebase から Androidアプリにメッセージが送れていることが確認できますね。

あとはプッシュ通知ぽく、メッセージを表示すれば OK。プッシュ通知の表示には、 NotificationCompat.Builderクラスと NotificationManagerCompatクラスが便利でしょう。

下記のように MyFirebaseMessagingServiceクラスを書き換えると、 Firebaseからのメッセージがプッシュ通知として端末に表示されます。

import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class MyFirebaseMessagingService extends FirebaseMessagingService {

   private static final String TAG = "【Firebaseテスト中】";

   @Override
   public void onMessageReceived(RemoteMessage remoteMessage) {

       Log.d(TAG, "From: " + remoteMessage.getFrom());


       // Check if message contains a notification payload.
       if (remoteMessage.getNotification() != null) {
           //Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
           String title = remoteMessage.getNotification().getTitle();
           String message = remoteMessage.getNotification().getBody();

           Log.d(TAG, "Title:  " + title);
           Log.d(TAG,"Body:  " + message);
       }

       super.onMessageReceived(remoteMessage);
       showNotification(remoteMessage.getNotification().getTitle(),remoteMessage.getNotification().getBody());
   }

   public void showNotification(String title,String message){
       NotificationCompat.Builder builder = new NotificationCompat.Builder(this,"MyNotification")
               .setContentTitle(title)
               .setAutoCancel(true)
               .setContentText(message);

       NotificationManagerCompat manager = NotificationManagerCompat.from(this);
       manager.notify(999,builder.build());
   }
}

実機でプログラムを再起動し、 Firebase からメッセージを送ってみます。

image

すると、アプリが落ちました....

Logcat を確認すると...

image

java.lang.IllegalArgumentException: Invalid notification (no valid small icon)

どうもアイコンがないことでエラーとのこと。確かに現状では AndroidManifest.xml に

android:roundIcon="@mipmap/ic_launcher_round"

と書かれていますが、ダメな様子。このあたりは公式ドキュメントに従ってセットしたはずなのですが。。。

アイコンを設定

image 通知のアイコン設定は、 res → drawable の drawable フォルダで右クリックし、 New → Image Asset を選択。あとは上図のように icon Type を Notification に変えて、ロゴや文字を変更。今回は Aa という文字にロゴをセットしました。

image

アイコンが作成できたら、上図のように MyFirebaseMessagingService クラス内にアイコンコードを追加。そして再びアプリを起動し、 Firebase からメッセージを送信してみます。

最終的なMyFirebaseMessagingServiceクラスのコード


import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class MyFirebaseMessagingService extends FirebaseMessagingService {

   private static final String TAG = "【Firebaseテスト中】";

   @Override
   public void onMessageReceived(RemoteMessage remoteMessage) {

       Log.d(TAG, "From: " + remoteMessage.getFrom());


       // Check if message contains a notification payload.
       if (remoteMessage.getNotification() != null) {
           //Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
           String title = remoteMessage.getNotification().getTitle();
           String message = remoteMessage.getNotification().getBody();

           Log.d(TAG, "Title:  " + title);
           Log.d(TAG,"Body:  " + message);
       }

       super.onMessageReceived(remoteMessage);
       showNotification(remoteMessage.getNotification().getTitle(),remoteMessage.getNotification().getBody());
   }

   public void showNotification(String title,String message){
       NotificationCompat.Builder builder = new NotificationCompat.Builder(this,"MyNotification")
               .setContentTitle(title)
               .setSmallIcon(R.drawable.ic_stat_name)
               .setAutoCancel(true)
               .setContentText(message);

       NotificationManagerCompat manager = NotificationManagerCompat.from(this);
       manager.notify(999,builder.build());
   }
}

image

ちょっと小さくて見難いですが、実機のスマホ上に設定したアイコン Aa が表示されています。 そして通知を確認すると...

image

きちんと Firebase で設定したテキストが表示されていますね。

尚、今回作成したプログラムは、バックグラウンドで動くアプリには対応していません。起動中もしくはメモリー下におかれたアプリにのみメッセージが送られます。

Firebaseのプロジェクト削除

Firebaseで作成したプロジェクト、ちょっと困ったことに Firebase管理画面からは削除できません。削除は、 Google Cloud Platform から削除する必要があります。

まとめ

一昔前に比べると落ち着いたように思えるプッシュ通知。しかし、ユーザーに対してアクションを起こせるプッシュ通知の機能は、アプリ特有のもの。使い方を知っておいて損はないと思います。

「書かれているコードと同じようにやってもアプリが動かない」「Android Studio 難しすぎっ」という方、学習はお一人で進めているのでしょうか?

費用はかかりますが、プロの方やプログラミング・スクールに頼ってみるというのはどうでしょう?悩んだり検索している時間、もったいないかもしれませんよ。

CodeCamp では、『オンライン × マンツーマン × 現役エンジニア講師』でプログラミング学習を支援中。ユーザー満足度 94.6% のプログラミング学習、試してみませんか? CodeCampでは無料体験や無料相談を受付中。詳しくは公式ページ https://codecamp.jp より確認して見て下さい。

オシママサラ
この記事を書いた人
オシママサラ
\ 無料体験開催中!/自分のペースで確実に習得!
オンライン・プログラミングレッスンNo.1のCodeCamp