flutterflutter-plugin

How to implement `AppCompatActivity` in a Flutter plugin?


I'm trying to create a Flutter plugin that asks for user notification permission. Most of the suggestion on this thread Ask permission for push notification suggest to do something like:

private val pushNotificationPermissionLauncher = registerForActivityResult(RequestPermission()) { granted ->
            viewModel.inputs.onTurnOnNotificationsClicked(granted)
        }

But to use registerForActivityResult function, the class must be a subclass of AppCompatActivity as far as I understood, and my plugin implementation is a subclass of FlutterPlugin. The question is, how to use registerForActivityResult in a Flutter Android plugin? Should I create a separate Activity to subclass AppCompatActivity? And if so, how to create that and integrate with the Flutter plugin?


Solution

  • After studying more about Android environment I ended up with a simple solution. To invoke UI elements in a Flutter Android plugin, we just need to invoke an AppCompatActivity using an Intent. Using the push notification example above (but you can change to whenever permission you want to present), we need to create an AppCompatActivity subclass and write the proper code to ask for the permission:

    class PushPermissionActivity: AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            val requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { 
            isGranted: Boolean -> 
            if (isGranted) {
                sendBroadcast(Intent(ACTION_PERMISSIONS_GRANTED))
            } else {
                sendBroadcast(Intent(ACTION_PERMISSIONS_DENIED))
            }
            finish()
        }
    
            return requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
        }
    }
    

    After that, register this new activity in the AndroidManifest:

    <activity android:name="PushPermissionActivity" android:theme="@style/Theme.Transparent" />
    

    After that, you can invoke the activity using an Intent in the plugin implementation file:

    private fun requestPermission(result: Result) {
        val permissionReceiver = object : BroadcastReceiver() {
          init {
            val intentFilter = IntentFilter()
            intentFilter.addAction(ACTION_PERMISSIONS_GRANTED)
            intentFilter.addAction(ACTION_PERMISSIONS_DENIED)
            context.registerReceiver(this, intentFilter)
          }
    
                override fun onReceive(context: Context, intent: Intent) {
                    when {
                    intent.action == ACTION_PERMISSIONS_GRANTED -> {
                        result.success(2)
                        context.unregisterReceiver(this)
                    }
                    intent.action == ACTION_PERMISSIONS_DENIED -> {
                        result.success(1)
                        context.unregisterReceiver(this)
                    }
                    
                }
            }
        }
          val intent = Intent(context, PushPermissionActivity::class.java)
          intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
          this.context.startActivity(intent)
      }