From a8d8bb8122d69475a6b94d4842c6357d12c90467 Mon Sep 17 00:00:00 2001 From: Shiva Eravathri Date: Mon, 11 Aug 2025 12:46:47 +0530 Subject: [PATCH] add support for FlutterActivity --- README.md | 24 ++++- .../HyperSdkFlutterPlugin.kt | 94 ++++++++++++++----- android/src/main/res/values/styles.xml | 3 + 3 files changed, 93 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index bbf8504..7175edf 100644 --- a/README.md +++ b/README.md @@ -43,21 +43,37 @@ buildscript { Optionally, you can also provide an override for base SDK version present in plugin (the newer version among both would be considered). -### Note +### Activity Setup -**Your application's `MainActivity` should extend `FlutterFragmentActivity` instead of `FlutterActivity`.** +#### 1. Using `FlutterFragmentActivity` (Recommended) -_`HyperSDK` only supports `FragmentActivity`._ +Your application's `MainActivity` should extend `FlutterFragmentActivity` instead of `FlutterActivity` for a more seamless experience. ```kotlin import io.flutter.embedding.android.FlutterFragmentActivity +class MainActivity : FlutterFragmentActivity() { -class MainActivity: FlutterFragmentActivity() { +} +``` + +#### 2. Using `FlutterActivity` + +Alternatively, your application's `MainActivity` can extend `FlutterActivity`. + +```kotlin +import io.flutter.embedding.android.FlutterActivity + +class MainActivity : FlutterActivity() { } ``` +> **Note:** +> If you use `FlutterActivity`, always call `createHyperServices` or `createHyperServicesWithTenantId` before calling `initiate`. +> Use `FlutterFragmentActivity` if possible. + + ## iOS Setup Add the following post_install script in the Podfile (`ios/Podfile`) diff --git a/android/src/main/kotlin/in/juspay/hyper_sdk_flutter/HyperSdkFlutterPlugin.kt b/android/src/main/kotlin/in/juspay/hyper_sdk_flutter/HyperSdkFlutterPlugin.kt index c407014..208523b 100644 --- a/android/src/main/kotlin/in/juspay/hyper_sdk_flutter/HyperSdkFlutterPlugin.kt +++ b/android/src/main/kotlin/in/juspay/hyper_sdk_flutter/HyperSdkFlutterPlugin.kt @@ -41,6 +41,7 @@ class HyperSdkFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware, private var hyperServices: HyperServices? = null private var isHyperCheckOutLiteInteg: Boolean = false private var flutterPluginBinding: FlutterPluginBinding? = null + private var initiatedWithApplicationContext: Boolean = false override fun onAttachedToEngine(flutterPluginBinding: FlutterPluginBinding) { channel = MethodChannel(flutterPluginBinding.binaryMessenger, "hyperSDK") @@ -119,16 +120,24 @@ class HyperSdkFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware, } private fun createHyperServicesWithTenantId(tenantId: String?, clientId: String?, result: Result) { - val fragmentActivity = binding?.activity as? FragmentActivity - if (fragmentActivity !is FragmentActivity) { - result.error("INIT_ERROR", "FragmentActivity is null, cannot proceed", "") + val activity = binding?.activity + if (activity == null) { + result.error("INIT_ERROR", "Activity is null, cannot proceed", "") return } if (tenantId == null || clientId == null) { result.error("INIT_ERROR", "tenantId or clientId cannot be null", "") return } - hyperServices = HyperServices(fragmentActivity, tenantId, clientId) + + if (activity is FragmentActivity) { + hyperServices = HyperServices(activity, tenantId, clientId) + initiatedWithApplicationContext = false + } else { + hyperServices = HyperServices(activity.applicationContext, tenantId, clientId) + initiatedWithApplicationContext = true + } + result.success(true) } private fun onBackPress(result: Result) { @@ -164,16 +173,24 @@ class HyperSdkFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware, } private fun createHyperServices(clientId: String?, result: Result) { - val fragmentActivity = binding?.activity as? FragmentActivity - if (fragmentActivity !is FragmentActivity) { - result.error("INIT_ERROR", "FragmentActivity is null, cannot proceed", "") + val activity = binding?.activity + if (activity == null) { + result.error("INIT_ERROR", "Activity is null, cannot proceed", "") return } if (clientId == null) { result.error("INIT_ERROR", "clientId cannot be null", "") return } - hyperServices = HyperServices(fragmentActivity, clientId) + + if (activity is FragmentActivity) { + hyperServices = HyperServices(activity, clientId) + initiatedWithApplicationContext = false + } else { + hyperServices = HyperServices(activity.applicationContext, clientId) + initiatedWithApplicationContext = true + } + result.success(true) } private fun updateHyperPaymentsCallback(hyperPaymentsCallback: HyperPaymentsCallback): HyperPaymentsCallback { @@ -206,19 +223,16 @@ class HyperSdkFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware, private fun initiate(params: Map, result: Result) { try { - if (binding == null) { - Log.e( - "JUSPAY", - "Kotlin MainActivity should extend FlutterFragmentActivity instead of FlutterActivity! JUSPAY Plugin only supports FragmentActivity. Please refer to this doc for more information: https://juspaydev.vercel.app/sections/base-sdk-integration/initiating-sdk?platform=Flutter&product=Payment+Page" - ) - throw Exception("Kotlin MainActivity should extend FlutterFragmentActivity instead of FlutterActivity!") + if (binding?.activity == null) { + result.error("INIT_ERROR", "Activity binding is not available", null) + return } val fragmentActivity = binding?.activity as? FragmentActivity - if (fragmentActivity !is FragmentActivity) { - result.error("INIT_ERROR", "FragmentActivity is null, cannot proceed", "") + if (hyperServices == null && fragmentActivity == null) { + result.error("INIT_ERROR", "HyperServices has not been initialized. Please call createHyperServices first.", null) return } - if (hyperServices == null) { + if (hyperServices == null && fragmentActivity is FragmentActivity) { hyperServices = HyperServices(fragmentActivity) } @@ -253,11 +267,20 @@ class HyperSdkFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware, } } } - hyperServices?.initiate( - fragmentActivity, - JSONObject(params), - updateHyperPaymentsCallback(callback) - ) + + val activity = binding?.activity + if (!initiatedWithApplicationContext && activity is FragmentActivity) { + hyperServices?.initiate( + activity, + JSONObject(params), + updateHyperPaymentsCallback(callback) + ) + } else { + hyperServices?.initiate( + JSONObject(params), + updateHyperPaymentsCallback(callback) + ) + } result.success(true) } catch (e: Exception) { result.error("INIT_ERROR", e.localizedMessage, e) @@ -271,8 +294,31 @@ class HyperSdkFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware, return } webViewConfigurationCallback?.let { hyperServices.setWebViewConfigurationCallback(it) } - hyperServices.process(JSONObject(params)) - result.success(true) + + val activity = binding?.activity + if (activity == null) { + result.error("PROCESS_ERROR", "Activity is null.", null) + return + } + + if (initiatedWithApplicationContext) { + HyperProcessActivity.setActivityCallback(object : ActivityCallback { + override fun onCreated(fragmentActivity: FragmentActivity) { + hyperServices.process(fragmentActivity, JSONObject(params)) + } + + override fun onBackPressed(): Boolean { + return hyperServices.onBackPressed() + } + }) + + val intent = Intent(activity, HyperProcessActivity::class.java) + activity.startActivity(intent) + result.success(true) + } else { + hyperServices.process(JSONObject(params)) + result.success(true) + } } private fun processWithView(id: Int?, params: Map, result: Result) { diff --git a/android/src/main/res/values/styles.xml b/android/src/main/res/values/styles.xml index 5188299..00316ea 100644 --- a/android/src/main/res/values/styles.xml +++ b/android/src/main/res/values/styles.xml @@ -1,6 +1,9 @@