10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ElixirAdvent Calendar 2024

Day 25

ElixirDesktop: WebViewからAndroid/iOSの通知を送信する方法

Posted at

リポジトリ

以下のリポジトリで、記事中に含まれるコードを確認できる。

記事を読むことできるようになること

  • ElixirDesktopでAndroid/iOSの通知を送信できる

省略する内容

  • ElixirDesktopの初期化手順
  • webviewからAndroid/iOSの関数を呼び出す方法

本題

ElixirDesktopでWebViewからAndroid/iOSの通知を送信実装をまとめる。

Android

Androidでは以下の5ステップで通知の送信を実装する。

  1. 権限を追加する
  2. 起動時に権限を要求する
  3. 通知のチャネルを作成する
  4. 通知の送信処理を実装する
  5. 呼び出しを実装する

権限を追加する

Androidで通知を送信するためには、通知の権限を追加する必要がある。
AndroidManifest.xmlに以下を記述して、権限を追加する。

AndroidManifest.xml
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

権限の要求

通知の権限を追加したあと、ユーザーに権限の要求を行う必要がある。
下記の関数を定義し、onCreate()内で実行することで、アプリの実行時に権限の要求ができる。

MainActivity.kt
import android.Manifest
    
    // 省略

    private fun requestNotificationPermission() {
        // Android 13以上で権限必要
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            val notificationPermission = Manifest.permission.POST_NOTIFICATIONS

            if (ContextCompat.checkSelfPermission(this, notificationPermission) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(
                    this,
                    arrayOf(notificationPermission),
                    REQUEST_NOTIFICATION_PERMISSION
                )
            } else {
                println("通知権限は許可されている")
            }
        } else {
            println("通知権限の要求は不要")
        }
    }

チャネルの作成

通知を送信する前に、チャネルを作成する必要がある。
下記の関数を定義し、init()内に追加することで通知を送信する準備ができる。

Bridge.kt
    fun createNotificationChannel() {
        val channel = NotificationChannel("tutorial_call_channel", "チュートリアル通知", NotificationManager.IMPORTANCE_DEFAULT).apply {
            description = "通知送信チュートリアルの通知チャネル"
        }
        val notificationManager =
            applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(channel)
    }

通知の送信処理

通知を送信する処理を以下のように実装する
WebViewから呼び出せるように@JavascriptInterfaceを付与する。

Bridge.kt
    @JavascriptInterface
    fun sendNotification() {
        val intent = Intent(applicationContext, MainActivity::class.java)

        val pendingIntent: PendingIntent = PendingIntent.getActivity(applicationContext, 0, intent,  PendingIntent.FLAG_IMMUTABLE)

        val notification = NotificationCompat.Builder(applicationContext, "tutorial_call_channel")
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setContentTitle("tutorial_notificationの通知")
            .setContentText("テキスト")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setDefaults(NotificationCompat.DEFAULT_ALL)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true) 
            .build()

        val notificationManager =
            applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        notificationManager.notify(1, notification)
    }

WebViewから呼び出せるようにinit()に下記を追加する

Bridge.kt
webview.addJavascriptInterface(this, "Android")

呼び出しを実装する

WebView側のJavaScriptで以下のように呼び出す

window.Android.sendNotification()

IOS

  1. 通知の権限をリクエストする
  2. 通知のデリゲートを設定する
  3. 通知の送信処理を実装する
  4. 呼び出しを実装する

通知の権限をリクエストする

Androidと同様に通知を送信するためには、通知の権限を追加する必要がある。
アプリ名.swiftに以下のようにAppDelegateクラスを追加して権限の要求をできる

アプリ名.swift
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions
                     launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
        
        let center = UNUserNotificationCenter.current()
        center.delegate = self
        requestNotificationAuthorization()
        return true
        
    }
    
    private func requestNotificationAuthorization() {
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
            if granted {
                print("通知の権限が許可された")
            } else {
                print("通知の権限が拒否された")
            }
        }
    }
}

通知のデリゲートを設定する

通知のデリゲートとは、通知を受信した時の処理という意味であり、これを実装することで通知をどのように表示するかを設定する。

以下のように記述することで、フォアグラウンドで画面にアラート表示しつつ、通知音を鳴らし、通知タスクに通知を表示できる。

アプリ名.swift
extension AppDelegate {
    // フォアグランド
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.alert, .sound, .list])
    }

    // バックグランド
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        completionHandler()
    }
}

通知の送信処理を実装する

通知を送信する処理は次のように実装できる。

WebView.swift
    func sendNotification() {
        let content = UNMutableNotificationContent()
        content.title = "tutorial_notificationの通知"
        content.body = "テキスト"
        content.sound = .default
        content.badge = 1
        let identifier = "通知送信チュートリアルの通知チャネル"

        let request = UNNotificationRequest(identifier: identifier, content: content, trigger: nil)

        UNUserNotificationCenter.current().add(request) { (error: Error?) in
            if error != nil {
                print("通知の送信に失敗した")
            } else {
                print("通知の送信に成功した")
            }
        }
    }

WebViewから呼び出せるようにoverride init()に下記を追加する

WebView.swift
configuration.userContentController.add(self, name: "sendNotification")

そしてuserContentControllerに以下を追加

WebView.swift
case "sendNotification":
    sendNotification()

呼び出しを実装する

WebView側のJavaScriptで以下のように呼び出す

window.webkit.messageHandlers.sendNotification.postMessage("sendNotification");

まとめ

Android/iOSともに以下の手順で通知を実装できる。

  1. 権限を追加する
  2. 権限を要求する
  3. 通知を送信する処理を実装する

ただし、iOSではAppDelegateを記述して通知の表示方法を設定しなければ通知が正しく表示されない点に注意が必要である。

一方で、AndroidにはiOSのAppDelegateに相当する仕組みは存在しない。そのため、通知をアラート表示させたい場合は、端末の設定に依存することになる。

10
2
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
10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?