I'm trying to create a notification channel with some help from this tutorial (on creating notifications) and this tutorial (on creating alarms). I have this code:
private fun createNotificationChannel() {
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(Notification.CATEGORY_REMINDER, "Reminder to Edit Trip", importance).apply {
description = "Send half-hourly reminders to edit the details of a trip."
}
val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager //TODO
notificationManager.createNotificationChannel(channel)
}
I don't know how to write the TODO line since I get the error "Required: Context, Found: String". The first tutorial wrote it as:
NotificationManager notificationManager = getSystemService(NotificationManager.class)
which doesn't work because I get an error on NotificationManager
saying "Classifier NotificationManager does not have a companion object, and thus must be initialised here", and the second tutorial wrote the line as:
private val alarmManager = context.getSystemService(AlarmManager::class.java)
which also doesn't work because of an error on context
saying "None of the following functions can be called with the arguments supplied".
I found this SO question on the same issue, but the answer no longer works since context
no longer has getSystemService()
. I tried both
val notificationManager = Context.getSystemService(Context.NOTIFICATION_SERVICE)
which gives the error "Unresolved reference: getSystemService()"
and
val notificationManager = ContextCompat.getSystemService(Context.NOTIFICATION_SERVICE);
which gives the error "Required: Context, Found: String".
So how can I write this now? I'm targeting API 30.
I figured it out (though don't really know the theory on why it works): we get the context via LocalContext.current
, which then requires the function to be a composable. This would then require my calling function, onCreate()
to be a composable, but that would clash with @SuppressLint
and @OptIn
, so I had to call the function from setContent()
. Here's the entire code:
class MainActivity : ComponentActivity() {
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@OptIn(ExperimentalMaterial3Api::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
WayToGoTheme ( content = {
Scaffold {
val context = LocalContext.current
val application = context.applicationContext as WayToGoApplication
val routeRepository = application.routeRepository
val waypointRepository = application.waypointRepository
val routeViewModel: RouteViewModel = remember { RouteViewModel(routeRepository) }
val waypointViewModel: WaypointViewModel = remember { WaypointViewModel(waypointRepository) }
val navController = rememberNavController()
CreateNotificationChannel()
NavGraph(navController = navController, waypointViewModel = waypointViewModel, routeViewModel = routeViewModel)
}
})
}
}
}
@Composable
private fun CreateNotificationChannel() {
val ctx = LocalContext.current
// Use LaunchedEffect to ensure the side effect happens only once
LaunchedEffect(Unit) {
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(Notification.CATEGORY_REMINDER, "Reminder to Edit Trip", importance).apply {
description = "Send half-hourly reminders to edit the details of a trip."
}
val notificationManager = ctx.getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(channel)
}
}