15
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AndroidのPush通知の導入方法

Last updated at Posted at 2022-07-07

image00.png
Firebase Cloud Messaging(FCM)を使って AndroidでPush通知を実装します。

Firebase Cloud Messagingとは

Firebase Cloud Messaging(FCM)は、メッセージを無料で確実に配信するためのクロスプラットフォーム メッセージング ソリューションです。以前は Google Cloud Messaging API が使われていたようですが、現在はFCMに移行しています。
image.png

Push通知実装の流れ

  1. Firebaseプロジェクトの作成 - Firebaseコンソール
  2. Androidアプリでサービスを実装 - Android Studio
  3. テスト通知 - Firebaseコンソール
  4. アプリがフォアグラウンド時の通知表示実装 - Android Studio

それでは実装していきましょう。

Firebaseプロジェクトの作成

1 .Firebaseのコンソールから新規にプロジェクトを作成

image.png

2 .プロジェクトに名前を付ける

お好きな名前で大丈夫です。
image.png

3 .Google アナリティクス

Google アナリティクスは今回はオフにします。
image.png

4 .android iconをクリック

android iconをクリック。
スクリーンショット 2022-07-07 083549.png

5 .Android パッケージ名を入力

Android パッケージ名は、androidアプリのAndroiManifest.xmlで確認できます。
その他の項目は空欄のままで大丈夫です。
スクリーンショット 2022-07-07 083922.png

image.png

6 .google-services.jsonの導入

google-services.jsonとは、今作成したプロジェクトの情報が記述せれているjsonファイルです。
ダウンロードした google-services.json ファイルを Android アプリのappディレクトリー直下に配置します。
image.png
image.png

7 .Firebase SDK の追加

ここは後で追加するので、次へをクリック。
image.png

8 .Firebaseの設定完了

image.png

Androidアプリの設定

1 .プロジェクトレベルのbuild.gradleを修正

// 追記 ここから
buildscript {
    dependencies {
        classpath 'com.google.gms:google-services:4.3.13'
    }
    repositories {
        google()
    }
}
// ここまで

plugins {
    id 'com.android.application' version '7.1.2' apply false
    id 'com.android.library' version '7.1.2' apply false
    id 'org.jetbrains.kotlin.android' version '1.6.20' apply false
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

}

2 .アプリレベルのbuild.gradleを修正

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'

    // 追記
    id 'com.google.gms.google-services'
}

android {
    compileSdk 32

    defaultConfig {
        applicationId "com.example.pushnotificationtest"
        minSdk 29
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
}

dependencies {
    implementation 'androidx.core:core-ktx:1.8.0'
    implementation 'androidx.appcompat:appcompat:1.4.2'
    implementation 'com.google.android.material:material:1.6.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    implementation 'com.google.firebase:firebase-bom:30.2.0'
    implementation 'com.google.firebase:firebase-messaging-ktx:23.0.6'

    // 2行追記
    implementation 'com.google.firebase:firebase-bom:30.2.0'
    implementation 'com.google.firebase:firebase-messaging-ktx:23.0.6'
}

修正したら「Sync now」をクリックします。

3 .FirebaseMessagingServiceを継承したMyFirebaseMessagingServiceクラスを作成

Firebaseのガイド(https://firebase.google.com/docs/cloud-messaging/android/receive) を参考にサービスクラスを作成します。
今回はMainActivityと同じ階層に作成します。

class MyFirebaseMessagingService: FirebaseMessagingService() {
    private val TAG = "push notification"

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)
        Log.d(TAG, "onMessageReceived: " + remoteMessage.data["message"])
    }
}

4 .AndroidManifest.xmlにサービスを登録

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.PushNotificationTest">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!-- 追加 ここから -->
        <service
            android:name=".MyFirebaseMessagingService"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>
        <!-- 追加 ここまで -->
    </application>
</manifest>

5 .MainActivityの修正

FCM token(アプリのアドレス)を取得する為のコードを記述します。
このコードを記述することで、MainActivityが作成されたタイミングでFCM tokenが表示され、自動的にクリップボードにコピーされます。
このtokenは、google keepやメールなどを使いパソコンで利用出来るようにしておいてください。

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        // 追加
        updateFCMToken()
    }
    
    // 追加
    private fun updateFCMToken() {
        FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
            if (!task.isSuccessful) {
                Log.w("FIREBASE", "getInstanceId failed", task.exception)
                return@OnCompleteListener
            }
            val token = task.result

            // 以下通知テスト用にFCMトークンを表示、コピーする為の記述
            Toast.makeText(baseContext,token,Toast.LENGTH_LONG).show()
            val clipboardManager = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
            val clipData = ClipData.newPlainText("text", token)
            clipboardManager.setPrimaryClip(clipData)
        })
    }
}

Screenshot_20220707_090750.png

6 .Androidアプリの設定完了

Androidアプリを実行するとPush通知が受け取れるようになります。
※ただしアプリがフォアグラウンドの時はまだ通知を受信できません。これについては、また後で説明します。

テストメッセージを送信

Firebaseコンソール(https://console.firebase.google.com/) でテスト用の通知メッセージを作成します。

1 .Cloud messageing、send your first messageを順にクリックしてメッセージ作成画面を表示します。

image.png
image.png

2 .メッセージの送信

通知のタイトル、通知テキストを記述してテストメッセージを送信をクリック。
image.png

FCM登録トークンを追加箇所に、先程取得したFCM tokenを貼り付け。
image.png
メッセージを送信するとAndroidアプリにPush通知が表示されます。
Screenshot_20220707_092333.png
メッセージは、アプリが起動していない場合、もしくはアプリがバックグラウンドの場合のみに受信します。

アプリがフォアグラウンド時の通知表示実装

androidのpush通知には、2種類あります。
1つはアプリがforeground時の通知、もう1つはアプリがbackground時の通知です。
background時の通知は、OSが自動で受け取ったデータから通知を生成してくれますが、
foreground時の通知は、自分で受けっとた時の処理を書く必要があります。
より詳しく知らたい人は以下のサイトを御覧ください。
https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages
https://note.com/kirimin_chan/n/n04fbabbf17bb

それでは、forground時に通知を受け取れるように実装していきましょう。

1 .MyFirebaseMessagingService classのonMessageReceived関数の編集

以下のコードは受信したデータからtitle, bodyを取得してMainActivityに遷移する通知を作成しています。

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)
        Log.d(TAG, "onMessageReceived: " + remoteMessage.data["message"])

        // 追加 ここから
        val intent = Intent(this, MainActivity::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)
        val channelId = "Default"
        val builder: NotificationCompat.Builder = NotificationCompat.Builder(this, channelId)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(remoteMessage.notification!!.title)
            .setContentText(remoteMessage.notification!!.body).setAutoCancel(true)
            .setContentIntent(pendingIntent)
        val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        val channel = NotificationChannel(
            channelId,
            "Default channel",
            NotificationManager.IMPORTANCE_DEFAULT
        )
        manager.createNotificationChannel(channel)
        manager.notify(0, builder.build())
       // ここまで
    }

この記述を追加することで、アプリがforground時でも通知を表示されるようになりました。
またonMessageReceived関数の内容によっては、アプリがforground時にメッセージを受け取った場合にdialogを表示するActivityを起動することでdialogを表示することも可能です。

15
9
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
15
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?