icerockdev / moko-permissions

Runtime permissions controls for mobile (android & ios) Kotlin Multiplatform development
https://moko.icerock.dev/
Apache License 2.0
311 stars 34 forks source link

permission not working on android but works on ios compose multiplatform #85

Open prabinshrestha opened 1 year ago

prabinshrestha commented 1 year ago

I am using voyager library for compose multiplatform, here is the dependencies on shared

implementation("cafe.adriel.voyager:voyager-navigator:$voyagerVersion") api("dev.icerock.moko:permissions-compose:0.16.0")

gradle properties kotlin.version=1.8.20 agp.version=7.4.2 compose.version=1.4.1

The issue is the Log inside coroutine scope is called and after that no code run, there is no exception everything is blank or prints nothing on logger on android studio.I beleive something is wrong with controller.isPermissionGranted but in IOS It works properly

Android Log : 2023-07-07 16:06:22.577 744-744 test com.myapplication.MyApplication V on login button clicked. 2023-07-07 16:06:22.578 744-744 test com.myapplication.MyApplication V inside coroutine scope

IOS Log: 07-07 16:16:44.251 💜 VERBOSE test - on login button clicked. 07-07 16:16:44.251 💜 VERBOSE test - inside coroutine scope 07-07 16:16:44.262 💜 VERBOSE test - isGranted true

Android Manifest: <uses-feature android:name="android.hardware.camera" android:required="true" />

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />

import cafe.adriel.voyager.core.model.rememberScreenModel import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.Navigator import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import dev.icerock.moko.permissions.DeniedAlwaysException import dev.icerock.moko.permissions.DeniedException import dev.icerock.moko.permissions.Permission import dev.icerock.moko.permissions.PermissionsController import dev.icerock.moko.permissions.compose.PermissionsControllerFactory import dev.icerock.moko.permissions.compose.rememberPermissionsControllerFactory

val factory: PermissionsControllerFactory = rememberPermissionsControllerFactory()
    val controller: PermissionsController =
        remember(factory) { factory.createPermissionsController() }
    val coroutineScope: CoroutineScope = rememberCoroutineScope()

  Button(
            onClick = {
                //  onValid()
                AppLogger.log("on login button clicked.")
                coroutineScope.launch {
                    AppLogger.log("inside coroutine scope")
                    try {
                        val isGranted = controller.isPermissionGranted(Permission.CAMERA)
                        AppLogger.log("isGranted $isGranted")
                        if (!isGranted) {
                            // need to add permission on android manifest and info.plist on ios xcode
                            // https://iosdevcenters.blogspot.com/2016/09/infoplist-privacy-settings-in-ios-10.html
                            val permissionState =
                                controller.getPermissionState(Permission.CAMERA)
                            AppLogger.log(permissionState.name)
                            controller.providePermission(Permission.CAMERA)
                        }
                    } catch (deniedAlways: DeniedAlwaysException) {
                        AppLogger.log(deniedAlways.message.toString())
                        // Permission is always denied.
                        controller.openAppSettings()
                    } catch (denied: DeniedException) {
                        // Permission was denied.
                        AppLogger.log(denied.message.toString())
                        controller.openAppSettings()
                    }

                    //   controller.openAppSettings()
                    //   controller.providePermission(Permission.CAMERA)
                }
            },
            modifier = Modifier
                .fillMaxWidth()
                .padding(top = 16.dp)
        ) {
            Text(
                stringResource(MR.strings.sign_in),
                fontWeight = FontWeight.Bold,
                fontSize = MaterialTheme.typography.h6.fontSize
            )
        }
Alex009 commented 1 year ago

hi!

please compare your setup with this template - https://github.com/icerockdev/moko-compose-multiplatform-ios-android-template

prabinshrestha commented 1 year ago
Its working now, BindEffect is required
val factory: PermissionsControllerFactory = rememberPermissionsControllerFactory()
val controller: PermissionsController =
        remember(factory) { factory.createPermissionsController() }
BindEffect(controller) // missing this api otherwise doesnot work, i am not using mokomvvm
val coroutineScope: CoroutineScope = rememberCoroutineScope()

Thank you @Alex009

RaedGhazal commented 7 months ago

Thanks @prabinshrestha for sharing your solution, was debugging for quite a while trying to understand why my viewmodel isn't logging anything, then after checking I saw that the isPermissionGranted is not returning anything. the solution you wrote fixed it, ~I'll open a PR to update the readme file, hope they approve it cuz it can be confusing~ apparently its added to the documentation

ibaton commented 3 weeks ago

Thanks @Alex009 this helped me as well