Search code examples
react-nativeexpoandroid-permissionsexpo-module

Handling android permission callback in module created by create-expo-module


I am implementing my custom expo module using create-expo-module. I need to request user for some permissions (notifications, bluetooth, location). There is a documentation about how to write custom expo module, but I could not find how to implement handling android permission callbacks. While implementing my module I followed great tutorial on youtube but he does not care about permission callbacks. Expo module expo-permission is deprecated.

For example, when user accept or reject notification permission dialog then I could not handle system callback onActivityResult in the app. Is there any hacks how to achieve this?

class MyExpoModule : Module() {

  override fun definition(): ModuleDefinitionData {

    return ModuleDefinition {
      Name("MyExpoModule")

      Function("requestPermissions") {
        MyPermissionManager.requestPermissions(appContext.activityProvider?.currentActivity)
      }

    }
  }
}
public class MyPermissionManager {

    public static void requestPermissions(Activity activity) {
        if (Build.VERSION.SDK_INT >= 33) {
            if (ContextCompat.checkSelfPermission(activity, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
                PermissionAwareActivity permissionAwareActivity = (PermissionAwareActivity) activity;
                if (permissionAwareActivity != null) {
                    permissionAwareActivity.requestPermissions(new String[]{Manifest.permission.POST_NOTIFICATIONS}, 101, new PermissionListener() {
                        @Override
                        public boolean onRequestPermissionsResult(int i, String[] strings, int[] ints) {
                            // POSSIBLE TO HANDLE - OK
                            return false;
                        }
                    });
                }
            }
            else {
                // granted
            }
        }  else if (Build.VERSION.SDK_INT >= 30) {
            if (((NotificationManager) activity.getSystemService(Context.NOTIFICATION_SERVICE))
                    .isNotificationPolicyAccessGranted()) {
                Intent intent = new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
                activity.startActivityForResult(intent, 1000);

                // HOW TO HANDLE RESULT HERE ???

            } else {
                // granted
            }
        }
    }

}

Thanks for advices.


Solution

  • Okay, I've found a a correct way by adding OnActivityResult. Here is the full code:

    class MyExpoModule : Module() {
    
      override fun definition(): ModuleDefinitionData {
    
        return ModuleDefinition {
          Name("MyExpoModule")
    
          Function("requestPermissions") {
            MyPermissionManager.requestPermissions(appContext.activityProvider?.currentActivity)
          }
    
          OnActivityResult { activity, onActivityResultPayload ->
            // handle results here
          }
    
        }
      }
    }
    
    

    But still, I had to use PermissionAwareActivity class from react-native to implement anonymous class with onRequestPermissionsResult callback in requestPermissions call. That means I had to add react-native dependency into app/build.gradle in my custom module.

    There is no possibility to watch onRequestPermissionsResult in expo module.