リポジトリ
以下のリポジトリで、記事中に含まれるコードを確認できる。
記事を読むことできるようになること
- ElixirDesktopでAndroid/iOSの通知を送信できる
省略する内容
- ElixirDesktopの初期化手順
- webviewからAndroid/iOSの関数を呼び出す方法
本題
ElixirDesktopでWebViewからAndroid/iOSの通知を送信実装をまとめる。
Android
Androidでは以下の5ステップで通知の送信を実装する。
- 権限を追加する
- 起動時に権限を要求する
- 通知のチャネルを作成する
- 通知の送信処理を実装する
- 呼び出しを実装する
権限を追加する
Androidで通知を送信するためには、通知の権限を追加する必要がある。
AndroidManifest.xml
に以下を記述して、権限を追加する。
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
権限の要求
通知の権限を追加したあと、ユーザーに権限の要求を行う必要がある。
下記の関数を定義し、onCreate()
内で実行することで、アプリの実行時に権限の要求ができる。
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()
内に追加することで通知を送信する準備ができる。
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
を付与する。
@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()
に下記を追加する
webview.addJavascriptInterface(this, "Android")
呼び出しを実装する
WebView側のJavaScriptで以下のように呼び出す
window.Android.sendNotification()
IOS
- 通知の権限をリクエストする
- 通知のデリゲートを設定する
- 通知の送信処理を実装する
- 呼び出しを実装する
通知の権限をリクエストする
Androidと同様に通知を送信するためには、通知の権限を追加する必要がある。
アプリ名.swift
に以下のようにAppDelegate
クラスを追加して権限の要求をできる
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("通知の権限が拒否された")
}
}
}
}
通知のデリゲートを設定する
通知のデリゲート
とは、通知を受信した時の処理
という意味であり、これを実装することで通知をどのように表示するかを設定する。
以下のように記述することで、フォアグラウンドで画面にアラート表示しつつ、通知音を鳴らし、通知タスクに通知を表示できる。
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()
}
}
通知の送信処理を実装する
通知を送信する処理は次のように実装できる。
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()
に下記を追加する
configuration.userContentController.add(self, name: "sendNotification")
そしてuserContentController
に以下を追加
case "sendNotification":
sendNotification()
呼び出しを実装する
WebView側のJavaScriptで以下のように呼び出す
window.webkit.messageHandlers.sendNotification.postMessage("sendNotification");
まとめ
Android/iOSともに以下の手順で通知を実装できる。
- 権限を追加する
- 権限を要求する
- 通知を送信する処理を実装する
ただし、iOSではAppDelegate
を記述して通知の表示方法を設定しなければ通知が正しく表示されない点に注意が必要である。
一方で、AndroidにはiOSのAppDelegate
に相当する仕組みは存在しない。そのため、通知をアラート表示させたい場合は、端末の設定に依存することになる。