[Jetpack Compose] ローカル通知を表示する

実装

AndroidManifest.xml

以下を追加

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

MainActivity.kt

class MainActivity : ComponentActivity() {
	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		setContent {
			MyNotificationTheme {
				Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
					MyNotificationView(
						context = this,
						modifier = Modifier.padding(innerPadding)
					)
				}
			}
		}
	}
}

@Composable
private fun MyNotificationView(context: Context, modifier: Modifier = Modifier) {
	val requestPermissionLauncher = rememberLauncherForActivityResult(
		ActivityResultContracts.RequestPermission()
	) { isGranted: Boolean ->
		if (!isGranted) {
			Toast.makeText(context, "通知を送信するには権限が必要です。", Toast.LENGTH_SHORT).show()
		}
	}

	// コンポーザブルが最初に表示されたときに権限リクエストを実行
	SideEffect {
		// Android 13 (Tiramisu) 以降でのみ権限リクエストが必要
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
			if (ContextCompat.checkSelfPermission(
					context,
					Manifest.permission.POST_NOTIFICATIONS
				) != PackageManager.PERMISSION_GRANTED
			) {
				// 権限が付与されていない場合、権限リクエストを開始
				requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
			}
		}
	}

	Column(
		modifier = Modifier.fillMaxSize(),
		verticalArrangement = Arrangement.Center,
		horizontalAlignment = Alignment.CenterHorizontally
	) {
		Button(
			onClick = {
				sendNotification(context)
			}
		) {
			Text(text = "Send Notification")
		}
	}
}

private fun sendNotification(context: Context) {
	// 5秒遅延させて通知を送信
	Handler(Looper.getMainLooper()).postDelayed({
		val channelId = "my_channel_id"
		val notificationId = 1

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

		// Android 8.0 (Oreo) 以降でのみ通知チャンネルを作成
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
			val channel = NotificationChannel(
				channelId,
				"My Channel",
				NotificationManager.IMPORTANCE_HIGH
			)
			notificationManager.createNotificationChannel(channel)
		}

		val builder = NotificationCompat.Builder(context, channelId)
			.setSmallIcon(android.R.drawable.ic_dialog_info) // 通知アイコン
			.setContentTitle("My Notification") // 通知のタイトル
			.setContentText("This is a notification from my app!") // 通知の本文
			.setPriority(NotificationCompat.PRIORITY_HIGH) // 高い優先度を設定

		// 通知を送信
		notificationManager.notify(notificationId, builder.build())
	}, 5000) // 5000 milliseconds = 5 seconds
}