I've added a native view which requires me to ask the user for some permissions and I want to do this in the onCreate
method. After reading over expos documentation I came across some boilerplate code to do this. So I added:
class MyLibPackage : Package {
override fun createReactActivityLifecycleListeners(activityContext: Context): List<ReactActivityLifecycleListener> {
return listOf(MyLibReactActivityLifecycleListener())
}
}
and created the following class:
class MyLibReactActivityLifecycleListener : ReactActivityLifecycleListener {
private var requestPermissionLauncher: ActivityResultLauncher<String>? = null
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
override fun onCreate(activity: Activity, savedInstanceState: Bundle?) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
handleNotificationPermission(activity)
}
}
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
private fun handleNotificationPermission(activity: Activity) {
if (activity is androidx.activity.ComponentActivity) {
requestPermissionLauncher = activity.registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
if (isGranted) {
// Permission granted
} else {
// Permission denied
// Provide user feedback
}
}
}
handleNotificationPermission(activity)
when {
ContextCompat.checkSelfPermission(
activity,
Manifest.permission.POST_NOTIFICATIONS
) == PackageManager.PERMISSION_GRANTED -> {
// Permission already granted
}
ActivityCompat.shouldShowRequestPermissionRationale(
activity, Manifest.permission.POST_NOTIFICATIONS) -> {
// Provide rationale to the user
// For example, show a dialog explaining why the permission is needed
}
else -> {
// Request permission
requestPermissionLauncher?.launch(Manifest.permission.POST_NOTIFICATIONS)
}
}
}
}
In this code the MyLibPackage
never actually runs and I'm not sure how to integrate it with the view.
My full Module file looks like this with NativeAudioViewModule
being the view i'm creating.
package expo.modules.nativeaudioview
import expo.modules.kotlin.modules.Module
import expo.modules.kotlin.modules.ModuleDefinition
import expo.modules.core.interfaces.Package
import expo.modules.core.interfaces.ReactActivityLifecycleListener
import android.content.Context
class MyLibPackage : Package {
override fun createReactActivityLifecycleListeners(activityContext: Context): List<ReactActivityLifecycleListener> {
return listOf(MyLibReactActivityLifecycleListener())
}
}
class NativeAudioViewModule : Module() {
override fun definition() = ModuleDefinition {
Name("NativeAudioView")
View(NativeAudioView::class) {
Events("onStatusChange")
Prop("url") { view: NativeAudioView, url: String? ->
if (url != null) {
view.url = url
}
}
Prop("title") { view: NativeAudioView, title: String? ->
if (title != null) {
view.title = title
}
}
}
}
}
I just spent an hour and a half figuring out the same problem.
In theory, your package class is picked up automatically by the expo-modules-autolinking
package and referenced in a Java file that is generated. Note that this is dependent on the filename ending in Package.kt
or Package.java
. The generated file is in node_modules/expo/android/build/generated/expo/src/main/java/expo/modules/ExpoModulesPackageList.java
.
However there is a caching issue and gradle doesn't know it needs to regenerate that file once you've added the Package class. I couldn't find a clean way to trigger the gradle task specifically, so I simply deleted the android build cache: rm -rf node_modules/expo/android/build/
. With the next rebuild the file is regenerated and correctly references the Package class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With