Skip to content

Commit 4748197

Browse files
Merge pull request #81 from qonversion/release/3.2.0
Release/3.2.0
2 parents 449bc7f + ae571c9 commit 4748197

File tree

7 files changed

+112
-59
lines changed

7 files changed

+112
-59
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 3.2.0
2+
* Add support for Android v2 embedding
3+
14
## 3.1.0
25
* Add support for promo purchases on iOS
36
* Add Identity support

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
group 'com.qonversion.flutter.sdk.qonversion_flutter_sdk'
2-
version '3.1.0'
2+
version '3.2.0'
33

44
buildscript {
55
ext.kotlin_version = '1.3.50'

android/src/main/kotlin/com/qonversion/flutter/sdk/qonversion_flutter_sdk/QonversionFlutterSdkPlugin.kt

Lines changed: 104 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -6,42 +6,65 @@ import androidx.annotation.NonNull
66
import androidx.preference.PreferenceManager
77
import com.google.gson.Gson
88
import com.qonversion.android.sdk.*
9-
import io.flutter.plugin.common.MethodCall
10-
import io.flutter.plugin.common.MethodChannel
11-
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
12-
import io.flutter.plugin.common.MethodChannel.Result
13-
import io.flutter.plugin.common.PluginRegistry.Registrar
14-
159
import com.qonversion.android.sdk.dto.QLaunchResult
1610
import com.qonversion.android.sdk.dto.QPermission
1711
import com.qonversion.android.sdk.dto.eligibility.QEligibility
1812
import com.qonversion.android.sdk.dto.offerings.QOfferings
1913
import com.qonversion.android.sdk.dto.products.QProduct
14+
import io.flutter.embedding.engine.plugins.FlutterPlugin
15+
import io.flutter.embedding.engine.plugins.activity.ActivityAware
16+
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
17+
import io.flutter.plugin.common.BinaryMessenger
18+
import io.flutter.plugin.common.MethodCall
19+
import io.flutter.plugin.common.MethodChannel
20+
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
21+
import io.flutter.plugin.common.MethodChannel.Result
22+
import io.flutter.plugin.common.PluginRegistry.Registrar
2023

2124
/** QonversionFlutterSdkPlugin */
22-
class QonversionFlutterSdkPlugin internal constructor(registrar: Registrar): MethodCallHandler {
23-
private val activity: Activity = registrar.activity()
24-
private val application: Application = activity.application
25+
class QonversionFlutterSdkPlugin : MethodCallHandler, FlutterPlugin, ActivityAware {
26+
private var activity: Activity? = null
27+
private var application: Application? = null
28+
private var channel: MethodChannel? = null
2529
private var deferredPurchasesStreamHandler: BaseEventStreamHandler? = null
2630

2731
companion object {
32+
const val METHOD_CHANNEL = "qonversion_flutter_sdk"
33+
const val EVENT_CHANNEL_PROMO_PURCHASES = "promo_purchases"
34+
const val EVENT_CHANNEL_DEFERRED_PURCHASES = "updated_purchases"
35+
2836
@JvmStatic
2937
fun registerWith(registrar: Registrar) {
30-
val channel = MethodChannel(registrar.messenger(), "qonversion_flutter_sdk")
31-
val instance = QonversionFlutterSdkPlugin(registrar)
32-
channel.setMethodCallHandler(instance)
33-
34-
// Register deferred purchases events
35-
val purchasesListener = BaseListenerWrapper(registrar.messenger(), "updated_purchases")
36-
purchasesListener.register()
37-
instance.deferredPurchasesStreamHandler = purchasesListener.eventStreamHandler
38-
39-
// Register promo purchases events. Android SDK does not generate any promo purchases yet
40-
val promoPurchasesListener = BaseListenerWrapper(registrar.messenger(), "promo_purchases")
41-
promoPurchasesListener.register()
38+
val instance = QonversionFlutterSdkPlugin()
39+
instance.setup(registrar.messenger(), registrar.activity().application)
40+
instance.activity = registrar.activity()
4241
}
4342
}
4443

44+
override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
45+
setup(binding.binaryMessenger, binding.applicationContext as Application)
46+
}
47+
48+
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
49+
activity = binding.activity
50+
}
51+
52+
override fun onDetachedFromActivityForConfigChanges() {
53+
onDetachedFromActivity()
54+
}
55+
56+
override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
57+
onAttachedToActivity(binding)
58+
}
59+
60+
override fun onDetachedFromActivity() {
61+
activity = null
62+
}
63+
64+
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
65+
tearDown()
66+
}
67+
4568
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
4669

4770
// Methods without args
@@ -96,25 +119,25 @@ class QonversionFlutterSdkPlugin internal constructor(registrar: Registrar): Met
96119
}
97120

98121
private fun launch(args: Map<String, Any>, result: Result) {
99-
val apiKey = args["key"] as? String ?: return result.noApiKeyError()
100-
val isObserveMode = args["isObserveMode"] as? Boolean ?: return result.noArgsError()
101-
102-
Qonversion.launch(
103-
application,
104-
apiKey,
105-
isObserveMode,
106-
callback = object: QonversionLaunchCallback {
107-
override fun onSuccess(launchResult: QLaunchResult) {
108-
result.success(launchResult.toMap())
109-
}
110-
111-
override fun onError(error: QonversionError) {
112-
result.qonversionError(error.description, error.additionalMessage)
122+
application?.let { application ->
123+
val apiKey = args["key"] as? String ?: return result.noApiKeyError()
124+
val isObserveMode = args["isObserveMode"] as? Boolean ?: return result.noArgsError()
125+
Qonversion.launch(
126+
application,
127+
apiKey,
128+
isObserveMode,
129+
callback = object : QonversionLaunchCallback {
130+
override fun onSuccess(launchResult: QLaunchResult) {
131+
result.success(launchResult.toMap())
132+
}
133+
134+
override fun onError(error: QonversionError) {
135+
result.qonversionError(error.description, error.additionalMessage)
136+
}
113137
}
114-
}
115-
)
116-
117-
startListeningPendingPurchasesEvents()
138+
)
139+
startListeningPendingPurchasesEvents()
140+
} ?: result.error(QonversionErrorCode.UnknownError.name, "Couldn't launch Qonversion. There is no Application context", null)
118141
}
119142

120143
private fun identify(userId: String?, result: Result) {
@@ -143,31 +166,35 @@ class QonversionFlutterSdkPlugin internal constructor(registrar: Registrar): Met
143166
return
144167
}
145168

146-
Qonversion.purchase(activity, productId, callback = object: QonversionPermissionsCallback {
147-
override fun onSuccess(permissions: Map<String, QPermission>) {
148-
result.success(PurchaseResult(permissions).toMap())
149-
}
169+
activity?.let { activity ->
170+
Qonversion.purchase(activity, productId, callback = object : QonversionPermissionsCallback {
171+
override fun onSuccess(permissions: Map<String, QPermission>) {
172+
result.success(PurchaseResult(permissions).toMap())
173+
}
150174

151-
override fun onError(error: QonversionError) {
152-
result.success(PurchaseResult(error = error).toMap())
153-
}
154-
})
175+
override fun onError(error: QonversionError) {
176+
result.success(PurchaseResult(error = error).toMap())
177+
}
178+
})
179+
} ?: result.error(QonversionErrorCode.PurchaseInvalid.name, "Couldn't make purchase. There is no Activity context", null)
155180
}
156181

157182
private fun updatePurchase(args: Map<String, Any>, result: Result) {
158183
val newProductId = args["newProductId"] as? String ?: return result.noNewProductIdError()
159184
val oldProductId = args["oldProductId"] as? String ?: return result.noOldProductIdError()
160185
val prorationMode = args["proration_mode"] as? Int
161186

162-
Qonversion.updatePurchase(activity, newProductId, oldProductId, prorationMode, callback = object: QonversionPermissionsCallback {
163-
override fun onSuccess(permissions: Map<String, QPermission>) {
164-
result.success(permissions.mapValues { it.value.toMap() })
165-
}
187+
activity?.let { activity ->
188+
Qonversion.updatePurchase(activity, newProductId, oldProductId, prorationMode, callback = object : QonversionPermissionsCallback {
189+
override fun onSuccess(permissions: Map<String, QPermission>) {
190+
result.success(permissions.mapValues { it.value.toMap() })
191+
}
166192

167-
override fun onError(error: QonversionError) {
168-
result.qonversionError(error.description, error.additionalMessage)
169-
}
170-
})
193+
override fun onError(error: QonversionError) {
194+
result.qonversionError(error.description, error.additionalMessage)
195+
}
196+
})
197+
} ?: result.error(QonversionErrorCode.PurchaseInvalid.name, "Couldn't update purchase. There is no Activity context", null)
171198
}
172199

173200
private fun checkPermissions(result: Result) {
@@ -304,4 +331,26 @@ class QonversionFlutterSdkPlugin internal constructor(registrar: Registrar): Met
304331

305332
result.success(null)
306333
}
334+
335+
private fun setup(messenger: BinaryMessenger, application: Application) {
336+
this.application = application
337+
channel = MethodChannel(messenger, METHOD_CHANNEL)
338+
channel?.setMethodCallHandler(this)
339+
340+
// Register deferred purchases events
341+
val purchasesListener = BaseListenerWrapper(messenger, EVENT_CHANNEL_DEFERRED_PURCHASES)
342+
purchasesListener.register()
343+
this.deferredPurchasesStreamHandler = purchasesListener.eventStreamHandler
344+
345+
// Register promo purchases events. Android SDK does not generate any promo purchases yet
346+
val promoPurchasesListener = BaseListenerWrapper(messenger, EVENT_CHANNEL_PROMO_PURCHASES)
347+
promoPurchasesListener.register()
348+
}
349+
350+
private fun tearDown() {
351+
channel?.setMethodCallHandler(null)
352+
channel = null
353+
this.deferredPurchasesStreamHandler = null
354+
this.application = null
355+
}
307356
}

example/android/app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
android:label="com.qonversion.sample"
1515
android:icon="@mipmap/ic_launcher">
1616
<activity
17-
android:name=".MainActivity"
17+
android:name="io.flutter.embedding.android.FlutterActivity"
1818
android:launchMode="singleTop"
1919
android:theme="@style/LaunchTheme"
2020
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"

example/pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ version: 1.0.0
77

88
environment:
99
sdk: ">=2.3.0 <3.0.0"
10+
flutter: ">=1.12.13+hotfix.6"
1011

1112
dependencies:
1213
flutter:

lib/src/qonversion.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import 'models/purchase_exception.dart';
1616
import 'qa_provider.dart';
1717

1818
class Qonversion {
19-
static const String _sdkVersion = "3.1.0";
19+
static const String _sdkVersion = "3.2.0";
2020

2121
static const MethodChannel _channel = MethodChannel('qonversion_flutter_sdk');
2222

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: qonversion_flutter
22
description: In-App Subscription Infrastructure to grow your subscription business
3-
version: 3.1.0
3+
version: 3.2.0
44
homepage: 'https://qonversion.io'
55
repository: 'https://github.com/qonversion/flutter-sdk'
66

0 commit comments

Comments
 (0)