Search code examples
androidandroid-jetpack-composeandroid-notificationsandroid-permissionsjetpack-compose-accompanist

Android Compose: how to get notification permission


I need to get permission to turn do not disturb mode on or off. Normally, without composing I would use the following code and check the result of the launched activity:

val mNotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    if (!mNotificationManager.isNotificationPolicyAccessGranted) {
        val intentNotifica = Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS)
        startActivity(intentNotifica)
    }

But with jetpack compose I would not know how to check if the user has obtained the permissions or not. For example, with the following code, I cannot know, after the user has pressed the button, if the permissions have been obtained or not:

fun DoNotDisturbPermission() {

val context = LocalContext.current
val hasPermission = context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager

if (!hasPermission.isNotificationPolicyAccessGranted) {
    Button(onClick = {
        val intentNotifica = Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS)
        context.startActivity(intentNotifica)
    }) {
        Text("get permission")
    }
} else {
    Text("Already granted")
}}

Also, I tried to use the Accompanist library with rememberPermissionState(Manifest.permission.ACCESS_NOTIFICATION_POLICY), but it doesn't work properly.


Solution

  • This is how I do it. I have the files below in a Permissions package in my Utils package.

    Permission Checker:

       @Composable
        fun checkNotificationPolicyAccess(
            notificationManager: NotificationManager,
            context: Context
        ): Boolean {
            if (notificationManager.isNotificationPolicyAccessGranted) {
                return true
            } else {
                PermissionDialog(context)
            }
            return false
        }
    

    Permission Dialog:

    @OptIn(ExperimentalComposeUiApi::class)
    @Composable
    fun PermissionDialog(context: Context) {
        val openDialog = remember { mutableStateOf(true) }
    
        if (openDialog.value) {
            AlertDialog(
                properties = DialogProperties(
                    usePlatformDefaultWidth = true
                ),
                title = { Text("Permission Needed") },
                text = {
                    Text("Allow ******* to access Do Not Disturb Settings? Pressing 'No' will close the app as it cannot work without access. Thanks.")
                },
                onDismissRequest = { openDialog.value = true },
    
                dismissButton = {
                    Button(
                        onClick = {
                            exitProcess(0)
                        },
                        colors = ButtonDefaults.buttonColors(Color(0xffFF9800))
                    ) {
                        Text(text = "No")
                    }
                },
                confirmButton = {
                    Button(
                        onClick = {
                            openDialog.value = false
                            val intent = Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS)
                            startActivity(context, intent, null)
    
                        },
                        colors = ButtonDefaults.buttonColors(Color(0xffFF9800))
                    ) {
                        Text(text = "Yes")
                    }
                }
            )
        }
    }
    

    Then my main activity looks like this:

    class MainActivity : ComponentActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            val notificationManager: NotificationManager =
                getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    
            setContent {
                MyTheme {
                    // A surface container using the 'background' color from the theme
                    Surface(
                        modifier = Modifier.fillMaxSize(),
                        color = MaterialTheme.colors.background
                    ) {   
                        checkNotificationPolicyAccess(notificationManager, this)
                        HomePage()
                    }
                }
            }
        }
    }