diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle
index b04a798..a2afb50 100644
--- a/example/android/app/build.gradle
+++ b/example/android/app/build.gradle
@@ -26,6 +26,15 @@ android {
compileSdk 34
namespace 'com.adobe.marketing.mobile.flutter.flutter_aepsdk_example'
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+
lintOptions {
disable 'InvalidPackage'
}
@@ -33,7 +42,7 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.adobe.marketing.mobile.flutter.flutter_aepsdk_example"
- minSdkVersion 21
+ minSdkVersion flutter.minSdkVersion
targetSdkVersion 34
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
diff --git a/example/android/app/src/main/java/com/adobe/marketing/mobile/flutter/flutter_aepsdk_example/MainActivity.java b/example/android/app/src/main/java/com/adobe/marketing/mobile/flutter/flutter_aepsdk_example/MainActivity.java
index 8020d3b..363362f 100644
--- a/example/android/app/src/main/java/com/adobe/marketing/mobile/flutter/flutter_aepsdk_example/MainActivity.java
+++ b/example/android/app/src/main/java/com/adobe/marketing/mobile/flutter/flutter_aepsdk_example/MainActivity.java
@@ -1,6 +1,6 @@
package com.adobe.marketing.mobile.flutter.flutter_aepsdk_example;
-import io.flutter.embedding.android.FlutterActivity;
+import io.flutter.embedding.android.FlutterFragmentActivity;
-public class MainActivity extends FlutterActivity {
+public class MainActivity extends FlutterFragmentActivity {
}
diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties
index 2a3a460..3eed553 100644
--- a/example/android/gradle/wrapper/gradle-wrapper.properties
+++ b/example/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
#Thu Apr 18 18:04:58 PDT 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/example/android/settings.gradle b/example/android/settings.gradle
index d72a278..b9ac8d8 100644
--- a/example/android/settings.gradle
+++ b/example/android/settings.gradle
@@ -17,8 +17,8 @@ pluginManagement {
}
plugins {
- id "com.android.application" version "8.2.2" apply false
- id "org.jetbrains.kotlin.android" version "1.8.22" apply false
+ id "com.android.application" version "8.7.3" apply false
+ id "org.jetbrains.kotlin.android" version "2.1.0" apply false
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
}
diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist
index 8c6e561..d57061d 100644
--- a/example/ios/Flutter/AppFrameworkInfo.plist
+++ b/example/ios/Flutter/AppFrameworkInfo.plist
@@ -21,6 +21,6 @@
CFBundleVersion
1.0
MinimumOSVersion
- 12.0
+ 13.0
diff --git a/example/ios/Podfile b/example/ios/Podfile
index 2c068c4..10f3c9b 100644
--- a/example/ios/Podfile
+++ b/example/ios/Podfile
@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
-platform :ios, '12.0'
+platform :ios, '13.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock
index 998c3d0..2c93aa8 100644
--- a/example/ios/Podfile.lock
+++ b/example/ios/Podfile.lock
@@ -1,33 +1,33 @@
PODS:
- - AEPAssurance (5.0.1):
+ - AEPAssurance (5.0.2):
- AEPCore (< 6.0.0, >= 5.0.0)
- AEPServices (< 6.0.0, >= 5.0.0)
- - AEPCore (5.4.0):
+ - AEPCore (5.7.0):
- AEPRulesEngine (< 6.0.0, >= 5.0.0)
- - AEPServices (< 6.0.0, >= 5.4.0)
+ - AEPServices (< 6.0.0, >= 5.7.0)
- AEPEdge (5.0.3):
- AEPCore (< 6.0.0, >= 5.3.1)
- AEPEdgeIdentity (< 6.0.0, >= 5.0.0)
- - AEPEdgeBridge (5.0.0):
+ - AEPEdgeBridge (5.1.0):
- AEPCore (< 6.0.0, >= 5.0.0)
- - AEPEdgeConsent (5.0.0):
+ - AEPEdgeConsent (5.0.1):
- AEPCore (< 6.0.0, >= 5.0.0)
- AEPEdge (< 6.0.0, >= 5.0.0)
- AEPEdgeIdentity (5.0.0):
- AEPCore (< 6.0.0, >= 5.0.0)
- - AEPIdentity (5.4.0):
- - AEPCore (< 6.0.0, >= 5.4.0)
- - AEPLifecycle (5.4.0):
- - AEPCore (< 6.0.0, >= 5.4.0)
- - AEPMessaging (5.6.0):
- - AEPCore (< 6.0.0, >= 5.3.0)
+ - AEPIdentity (5.7.0):
+ - AEPCore (< 6.0.0, >= 5.7.0)
+ - AEPLifecycle (5.7.0):
+ - AEPCore (< 6.0.0, >= 5.7.0)
+ - AEPMessaging (5.8.0):
+ - AEPCore (< 6.0.0, >= 5.6.0)
- AEPEdge (< 6.0.0, >= 5.0.2)
- AEPEdgeIdentity (< 6.0.0, >= 5.0.0)
- - AEPServices (< 6.0.0, >= 5.3.0)
+ - AEPServices (< 6.0.0, >= 5.6.0)
- AEPRulesEngine (5.0.0)
- - AEPServices (5.4.0)
- - AEPSignal (5.4.0):
- - AEPCore (< 6.0.0, >= 5.4.0)
+ - AEPServices (5.7.0)
+ - AEPSignal (5.7.0):
+ - AEPCore (< 6.0.0, >= 5.7.0)
- AEPUserProfile (5.0.0):
- AEPCore (< 6.0.0, >= 5.0.0)
- Flutter (1.0.0)
@@ -108,20 +108,20 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_aepuserprofile/ios"
SPEC CHECKSUMS:
- AEPAssurance: df04baeace42befb0cc213fd6cdfe51651d11ba6
- AEPCore: 8cdc5390163f2b761e7f3eed1cae92b8a11c0237
+ AEPAssurance: fedcd7ed72b431b5f310eb3a52921345c34c1051
+ AEPCore: d1b0905c5a9531a883d9e8c31212ff61ca900be0
AEPEdge: 105afc7958acd7c016d57f7ac1d6f632bf05e6ee
- AEPEdgeBridge: be78be4885ae420ef21bda91707d5eff9510ef70
- AEPEdgeConsent: d7db1d19eb4c1e2146360ed3c8df315f671b26d5
+ AEPEdgeBridge: 2302555a67bf4677a903c42dedf9b3ab0dd941b9
+ AEPEdgeConsent: 5f28a8ed6cd86812a73b1f5a4dbde9c81e486bf1
AEPEdgeIdentity: 3161ff33434586962946912d6b8e9e8fca1c4d23
- AEPIdentity: 44513e103592e8cc60508dde9f0b049c82897c07
- AEPLifecycle: 619ce7bf7b64a2caff7a172e9f12f0b6da636142
- AEPMessaging: 34d796c0a078c3e669b88150aae7dc468a308dcd
+ AEPIdentity: 1d491f04c11cbea9d94c6e2bc1b956b1264e3f42
+ AEPLifecycle: da35d7393f0d635472719d292b9e4142123cb13c
+ AEPMessaging: 8018287b9504b8ab7ee8dc96d87e524c2f8e5a9f
AEPRulesEngine: fe5800653a4bee07b1e41e61b4d5551f0dba557b
- AEPServices: ce27e3f2de75a9b24b3d27c7b5f1bb519724f8cb
- AEPSignal: 9b34890eea1b81714aa45b7d7f8deb82206b0ca2
+ AEPServices: e1f14e286a8680cecbe0bcdf6ea47f46573635c4
+ AEPSignal: 6e10c4d1dca8fb1ed8601cb4224ebd30fc241a59
AEPUserProfile: cf36305d683d993d528337a46b7a269029b63e5d
- Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
+ Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
flutter_aepassurance: eec6156fe1f6324f05546b7df34f3f0d18187f71
flutter_aepcore: 5de99ca989c8f31c5a715ae5c2bf864b01518936
flutter_aepedge: 060db412454a60e1a970b3bdf649543c94a25fc0
@@ -131,6 +131,6 @@ SPEC CHECKSUMS:
flutter_aepmessaging: a702f2691b29880d723aa0ff214a271fc6bdd381
flutter_aepuserprofile: c9c84653ece987b2ed5c9c8d49735c79aa362314
-PODFILE CHECKSUM: 4e8f8b2be68aeea4c0d5beb6ff1e79fface1d048
+PODFILE CHECKSUM: cc1f88378b4bfcf93a6ce00d2c587857c6008d3b
-COCOAPODS: 1.14.3
+COCOAPODS: 1.16.2
diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj
index 2617059..66abd9f 100644
--- a/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/example/ios/Runner.xcodeproj/project.pbxproj
@@ -171,7 +171,6 @@
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
- DevelopmentTeam = 66USX5VV9D;
LastSwiftMigration = 1130;
};
};
@@ -382,7 +381,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
@@ -398,14 +397,14 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
- DEVELOPMENT_TEAM = 66USX5VV9D;
+ DEVELOPMENT_TEAM = FKGEE875K4;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
- IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -469,7 +468,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -518,7 +517,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
@@ -534,14 +533,14 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
- DEVELOPMENT_TEAM = 66USX5VV9D;
+ DEVELOPMENT_TEAM = FKGEE875K4;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
- IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -566,14 +565,14 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
- DEVELOPMENT_TEAM = 66USX5VV9D;
+ DEVELOPMENT_TEAM = FKGEE875K4;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
- IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
diff --git a/example/pubspec.lock b/example/pubspec.lock
index 3614fc6..953803a 100644
--- a/example/pubspec.lock
+++ b/example/pubspec.lock
@@ -21,26 +21,26 @@ packages:
dependency: transitive
description:
name: characters
- sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
+ sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
url: "https://pub.dev"
source: hosted
- version: "1.3.0"
+ version: "1.4.0"
clock:
dependency: transitive
description:
name: clock
- sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
+ sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
url: "https://pub.dev"
source: hosted
- version: "1.1.1"
+ version: "1.1.2"
collection:
dependency: transitive
description:
name: collection
- sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
+ sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
url: "https://pub.dev"
source: hosted
- version: "1.18.0"
+ version: "1.19.1"
cupertino_icons:
dependency: "direct main"
description:
@@ -53,10 +53,10 @@ packages:
dependency: transitive
description:
name: fake_async
- sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
+ sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
url: "https://pub.dev"
source: hosted
- version: "1.3.1"
+ version: "1.3.3"
flutter:
dependency: "direct main"
description: flutter
@@ -110,7 +110,7 @@ packages:
path: "../plugins/flutter_aepmessaging"
relative: true
source: path
- version: "5.0.0"
+ version: "5.0.1"
flutter_aepuserprofile:
dependency: "direct main"
description:
@@ -127,34 +127,34 @@ packages:
dependency: transitive
description:
name: leak_tracker
- sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
+ sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
url: "https://pub.dev"
source: hosted
- version: "10.0.5"
+ version: "11.0.2"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
- sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
+ sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
url: "https://pub.dev"
source: hosted
- version: "3.0.5"
+ version: "3.0.10"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
- sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
+ sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
url: "https://pub.dev"
source: hosted
- version: "3.0.1"
+ version: "3.0.2"
matcher:
dependency: transitive
description:
name: matcher
- sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
+ sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
url: "https://pub.dev"
source: hosted
- version: "0.12.16+1"
+ version: "0.12.17"
material_color_utilities:
dependency: transitive
description:
@@ -167,23 +167,23 @@ packages:
dependency: transitive
description:
name: meta
- sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
+ sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
url: "https://pub.dev"
source: hosted
- version: "1.15.0"
+ version: "1.16.0"
path:
dependency: transitive
description:
name: path
- sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
+ sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
url: "https://pub.dev"
source: hosted
- version: "1.9.0"
+ version: "1.9.1"
sky_engine:
dependency: transitive
description: flutter
source: sdk
- version: "0.0.99"
+ version: "0.0.0"
source_span:
dependency: transitive
description:
@@ -196,18 +196,18 @@ packages:
dependency: transitive
description:
name: stack_trace
- sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
+ sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
url: "https://pub.dev"
source: hosted
- version: "1.11.1"
+ version: "1.12.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
- sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
+ sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
url: "https://pub.dev"
source: hosted
- version: "2.1.2"
+ version: "2.1.4"
string_scanner:
dependency: transitive
description:
@@ -228,18 +228,18 @@ packages:
dependency: transitive
description:
name: test_api
- sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
+ sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
url: "https://pub.dev"
source: hosted
- version: "0.7.2"
+ version: "0.7.6"
vector_math:
dependency: transitive
description:
name: vector_math
- sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
+ sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
url: "https://pub.dev"
source: hosted
- version: "2.1.4"
+ version: "2.2.0"
vm_service:
dependency: transitive
description:
@@ -249,5 +249,5 @@ packages:
source: hosted
version: "14.2.5"
sdks:
- dart: ">=3.3.0 <4.0.0"
+ dart: ">=3.8.0-0 <4.0.0"
flutter: ">=3.18.0-18.0.pre.54"
diff --git a/plugins/flutter_aepcore/CHANGELOG.md b/plugins/flutter_aepcore/CHANGELOG.md
index e44ec2c..c174567 100644
--- a/plugins/flutter_aepcore/CHANGELOG.md
+++ b/plugins/flutter_aepcore/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 5.0.1
+
+* Add `MobileCore.setApplication` call in Android FlutterPlugin's `onAttachedToEngine` to accurately register lifecycle callbacks for launcher activity.
+
## 5.0.0
* Add `MobileCore.initializeWithAppId` and `MobileCore.initialize` APIs to simplify AEP SDK initialization by enabling automatic extension registration and lifecycle tracking.
diff --git a/plugins/flutter_aepcore/android/src/main/java/com/adobe/marketing/mobile/flutter/flutter_aepcore/FlutterAEPCorePlugin.java b/plugins/flutter_aepcore/android/src/main/java/com/adobe/marketing/mobile/flutter/flutter_aepcore/FlutterAEPCorePlugin.java
index 3e9a265..52c5db5 100644
--- a/plugins/flutter_aepcore/android/src/main/java/com/adobe/marketing/mobile/flutter/flutter_aepcore/FlutterAEPCorePlugin.java
+++ b/plugins/flutter_aepcore/android/src/main/java/com/adobe/marketing/mobile/flutter/flutter_aepcore/FlutterAEPCorePlugin.java
@@ -44,6 +44,21 @@ public void onAttachedToEngine(@NonNull final FlutterPluginBinding binding) {
Context appContext = binding.getApplicationContext();
if (appContext instanceof Application) {
application = (Application) appContext;
+ // Set the application early to register Activity lifecycle callbacks
+ // This ensures the SDK can track the current Activity for in-app messages
+ // Without this, the following will happen:
+ //1. Application.onCreate()
+ // ✗ No Activity lifecycle callbacks registered
+ // 2. MainActivity.onCreate()
+ // ✗ SDK doesn't know about it
+ // 3. MainActivity.onResume()
+ // ✗ SDK doesn't know this is current Activity
+ // 4. Flutter engine initializes
+ // 5. MobileCore.initialize() called from Flutter
+ // ↓ Might set Application context, but...
+ // ✗ MainActivity already went through lifecycle
+ // ✗ SDK missed the lifecycle events
+ MobileCore.setApplication(application);
}
MobileCore.setWrapperType(WrapperType.FLUTTER);
flutterAEPIdentityPlugin.onAttachedToEngine(binding);
diff --git a/plugins/flutter_aepcore/pubspec.yaml b/plugins/flutter_aepcore/pubspec.yaml
index cfe9fab..ccd9b01 100644
--- a/plugins/flutter_aepcore/pubspec.yaml
+++ b/plugins/flutter_aepcore/pubspec.yaml
@@ -1,6 +1,6 @@
name: flutter_aepcore
description: Official Adobe Experience Platform support for Flutter apps. The Mobile Core represents the core Adobe Experience Platform SDK that is required for every app implementation.
-version: 5.0.0
+version: 5.0.1
homepage: https://developer.adobe.com/client-sdks
repository: https://github.com/adobe/aepsdk-flutter/tree/main/plugins/flutter_aepcore
diff --git a/plugins/flutter_aepmessaging/CHANGELOG.md b/plugins/flutter_aepmessaging/CHANGELOG.md
index c24d7ce..7abe100 100644
--- a/plugins/flutter_aepmessaging/CHANGELOG.md
+++ b/plugins/flutter_aepmessaging/CHANGELOG.md
@@ -1,3 +1,6 @@
+## 5.0.1
+* Add a timeout to the call made from native bridge to custom messaging delegate to allow showing the in-app message if no delegate is provided by the app developer.
+
## 5.0.0
* Update to use BOM [(Bill of Materials)](https://central.sonatype.com/artifact/com.adobe.marketing.mobile/sdk-bom) for Android SDK dependencies.
diff --git a/plugins/flutter_aepmessaging/android/build.gradle b/plugins/flutter_aepmessaging/android/build.gradle
index bc43e5d..2adc2ed 100644
--- a/plugins/flutter_aepmessaging/android/build.gradle
+++ b/plugins/flutter_aepmessaging/android/build.gradle
@@ -37,8 +37,8 @@ android {
kotlinOptions {
jvmTarget = '1.8'
- languageVersion = "1.4"
- apiVersion = "1.4"
+ languageVersion = "1.6"
+ apiVersion = "1.6"
}
sourceSets {
@@ -49,6 +49,7 @@ android {
minSdkVersion 21
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
+
lintOptions {
disable 'InvalidPackage'
}
diff --git a/plugins/flutter_aepmessaging/android/src/main/kotlin/com/adobe/marketing/mobile/flutter/flutter_aepmessaging/FlutterAEPMessagingDelegate.kt b/plugins/flutter_aepmessaging/android/src/main/kotlin/com/adobe/marketing/mobile/flutter/flutter_aepmessaging/FlutterAEPMessagingDelegate.kt
index 05d50fc..dc2bb68 100644
--- a/plugins/flutter_aepmessaging/android/src/main/kotlin/com/adobe/marketing/mobile/flutter/flutter_aepmessaging/FlutterAEPMessagingDelegate.kt
+++ b/plugins/flutter_aepmessaging/android/src/main/kotlin/com/adobe/marketing/mobile/flutter/flutter_aepmessaging/FlutterAEPMessagingDelegate.kt
@@ -1,17 +1,18 @@
package com.adobe.marketing.mobile.flutter.flutter_aepmessaging
+import android.os.Handler
+import android.os.Looper
import com.adobe.marketing.mobile.Message
import com.adobe.marketing.mobile.messaging.MessagingUtils
import com.adobe.marketing.mobile.services.ui.*
-import io.flutter.embedding.android.FlutterActivity
import io.flutter.plugin.common.MethodChannel
import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
class FlutterAEPMessagingDelegate(
private var cache: MutableMap,
private var channel: MethodChannel
-) : FlutterActivity(), PresentationDelegate {
- var shouldShowMessage = true
+): PresentationDelegate {
override fun onDismiss(presentable: Presentable<*>) {
if (presentable.getPresentation() !is InAppMessage) return
@@ -22,7 +23,9 @@ class FlutterAEPMessagingDelegate(
msg["id"] = message.id
msg["autoTrack"] = message.autoTrack
data["message"] = msg
- channel.invokeMethod("onDismiss", data)
+ Handler(Looper.getMainLooper()).post {
+ channel.invokeMethod("onDismiss", data)
+ }
}
}
@@ -35,7 +38,9 @@ class FlutterAEPMessagingDelegate(
msg["id"] = message.id
msg["autoTrack"] = message.autoTrack
data["message"] = msg
- channel.invokeMethod("onShow", data)
+ Handler(Looper.getMainLooper()).post {
+ channel.invokeMethod("onShow", data)
+ }
}
}
@@ -48,51 +53,91 @@ class FlutterAEPMessagingDelegate(
msg["id"] = message.id
msg["autoTrack"] = message.autoTrack
data["message"] = msg
- channel.invokeMethod("onHide", data)
+ Handler(Looper.getMainLooper()).post {
+ channel.invokeMethod("onHide", data)
+ }
}
}
override fun canShow(presentable: Presentable<*>): Boolean {
if (presentable.getPresentation() !is InAppMessage) return false
val message = MessagingUtils.getMessageForPresentable(presentable as Presentable)
- val latch = CountDownLatch(2)
if (message != null) {
+ var shouldSave = true // Default to true for fallback
+ var shouldShow = true // Default to true for fallback
+ val latch1 = CountDownLatch(1)
+ val latch2 = CountDownLatch(1)
+
val data = HashMap()
val msg = HashMap()
msg["id"] = message.id
msg["autoTrack"] = message.autoTrack
data["message"] = msg
- runOnUiThread {
+ Handler(Looper.getMainLooper()).post {
channel.invokeMethod("shouldSaveMessage", data, object : MethodChannel.Result {
override fun success(result: Any?) {
- if (result as Boolean) {
- cache[message.id] = message
- latch.countDown()
+ if (result is Boolean) {
+ shouldSave = result
}
+ // If no Flutter handler is registered, result will be notImplemented
+ // In that case, we keep the default shouldSave = true
+ latch1.countDown()
}
- override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {}
+ override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {
+ latch1.countDown()
+ }
- override fun notImplemented() {}
+ override fun notImplemented() {
+ // Flutter handler not registered, use fallback
+ latch1.countDown()
+ }
})
+ }
+ // Wait with timeout - if Flutter handler isn't available, don't wait forever
+ if (!latch1.await(500, TimeUnit.MILLISECONDS)) {
+ // Timeout occurred - Flutter handler likely not registered, use fallback
+ shouldSave = true
+ }
+
+ // Cache the message if shouldSave is true (either from Flutter or fallback)
+ if (shouldSave) {
+ cache[message.id] = message
+ }
+
+ Handler(Looper.getMainLooper()).post {
channel.invokeMethod("shouldShowMessage", data, object : MethodChannel.Result {
override fun success(result: Any?) {
- shouldShowMessage = result as Boolean
- latch.countDown()
+ if (result is Boolean) {
+ shouldShow = result
+ }
+ // If no Flutter handler is registered, keep the default shouldShow = true
+ latch2.countDown()
}
- override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {}
+ override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {
+ latch2.countDown()
+ }
- override fun notImplemented() {}
+ override fun notImplemented() {
+ // Flutter handler not registered, use fallback
+ latch2.countDown()
+ }
})
}
- }
- latch.await()
- return shouldShowMessage
+ // Wait with timeout for shouldShowMessage
+ if (!latch2.await(500, TimeUnit.MILLISECONDS)) {
+ // Timeout occurred - Flutter handler likely not registered, use fallback
+ shouldShow = true
+ }
+
+ return shouldShow
+ }
+ return true
}
override fun onContentLoaded(presentable: Presentable<*>, presentationContent: PresentationListener.PresentationContent?) {
@@ -102,7 +147,9 @@ class FlutterAEPMessagingDelegate(
val data = HashMap()
data["id"] = message.id
data["autoTrack"] = message.autoTrack
- channel.invokeMethod("onContentLoaded", data)
+ Handler(Looper.getMainLooper()).post {
+ channel.invokeMethod("onContentLoaded", data)
+ }
}
}
}
\ No newline at end of file
diff --git a/plugins/flutter_aepmessaging/ios/Classes/SwiftFlutterAEPMessagingPlugin.swift b/plugins/flutter_aepmessaging/ios/Classes/SwiftFlutterAEPMessagingPlugin.swift
index 544fa5c..fd45fb0 100644
--- a/plugins/flutter_aepmessaging/ios/Classes/SwiftFlutterAEPMessagingPlugin.swift
+++ b/plugins/flutter_aepmessaging/ios/Classes/SwiftFlutterAEPMessagingPlugin.swift
@@ -185,14 +185,16 @@ public class SwiftFlutterAEPMessagingPlugin: NSObject, FlutterPlugin, MessagingD
if let fullscreenMessage = message as? FullscreenMessage,
let parentMessage = fullscreenMessage.parent
{
- channel.invokeMethod(
- "onDismiss",
- arguments: [
- "message": dataBridge.transformToFlutterMessage(
- message: parentMessage
- )
- ]
- )
+ DispatchQueue.main.async {
+ self.channel.invokeMethod(
+ "onDismiss",
+ arguments: [
+ "message": self.dataBridge.transformToFlutterMessage(
+ message: parentMessage
+ )
+ ]
+ )
+ }
}
}
@@ -200,14 +202,16 @@ public class SwiftFlutterAEPMessagingPlugin: NSObject, FlutterPlugin, MessagingD
if let fullscreenMessage = message as? FullscreenMessage,
let parentMessage = fullscreenMessage.parent
{
- channel.invokeMethod(
- "onShow",
- arguments: [
- "message": dataBridge.transformToFlutterMessage(
- message: parentMessage
- )
- ]
- )
+ DispatchQueue.main.async {
+ self.channel.invokeMethod(
+ "onShow",
+ arguments: [
+ "message": self.dataBridge.transformToFlutterMessage(
+ message: parentMessage
+ )
+ ]
+ )
+ }
}
}
@@ -215,43 +219,66 @@ public class SwiftFlutterAEPMessagingPlugin: NSObject, FlutterPlugin, MessagingD
if let fullscreenMessage = message as? FullscreenMessage,
let incomingMessage = fullscreenMessage.parent
{
- var shouldShow = true
+ var shouldSave = true // Default to true for fallback
+ var shouldShow = true // Default to true for fallback
let semaphore = DispatchSemaphore(value: 0)
- channel.invokeMethod(
- "shouldSaveMessage",
- arguments: [
- "message": dataBridge.transformToFlutterMessage(
- message: incomingMessage
- )
- ],
- result: { (result: Any?) -> Void in
- if let shouldSaveMessage = result as? Bool {
- if shouldSaveMessage {
- self.messageCache[incomingMessage.id] = incomingMessage
+ let timeout = DispatchTime.now() + .milliseconds(500) // 500ms timeout
+
+ DispatchQueue.main.async {
+ self.channel.invokeMethod(
+ "shouldSaveMessage",
+ arguments: [
+ "message": self.dataBridge.transformToFlutterMessage(
+ message: incomingMessage
+ )
+ ],
+ result: { (result: Any?) -> Void in
+ if let shouldSaveMessage = result as? Bool {
+ shouldSave = shouldSaveMessage
}
+ // If no Flutter handler is registered, result will be FlutterMethodNotImplemented
+ // In that case, we keep the default shouldSave = true
+ semaphore.signal()
}
- semaphore.signal()
- }
- )
+ )
+ }
- semaphore.wait()
+ // Wait with timeout - if Flutter handler isn't available, don't wait forever
+ if semaphore.wait(timeout: timeout) == .timedOut {
+ // Timeout occurred - Flutter handler likely not registered, use fallback
+ shouldSave = true
+ }
+
+ // Cache the message if shouldSave is true (either from Flutter or fallback)
+ if shouldSave {
+ self.messageCache[incomingMessage.id] = incomingMessage
+ }
- channel.invokeMethod(
- "shouldShowMessage",
- arguments: [
- "message": dataBridge.transformToFlutterMessage(
- message: incomingMessage
- )
- ],
- result: { (result: Any?) -> Void in
- if let shouldShowMessage = result as? Bool {
- shouldShow = shouldShowMessage
+ let semaphore2 = DispatchSemaphore(value: 0)
+ DispatchQueue.main.async {
+ self.channel.invokeMethod(
+ "shouldShowMessage",
+ arguments: [
+ "message": self.dataBridge.transformToFlutterMessage(
+ message: incomingMessage
+ )
+ ],
+ result: { (result: Any?) -> Void in
+ if let shouldShowMessage = result as? Bool {
+ shouldShow = shouldShowMessage
+ }
+ // If no Flutter handler is registered, keep the default shouldShow = true
+ semaphore2.signal()
}
- semaphore.signal()
- }
- )
+ )
+ }
- semaphore.wait()
+ // Wait with timeout for shouldShowMessage
+ if semaphore2.wait(timeout: timeout) == .timedOut {
+ // Timeout occurred - Flutter handler likely not registered, use fallback
+ shouldShow = true
+ }
+
return shouldShow
}
return true
@@ -261,15 +288,17 @@ public class SwiftFlutterAEPMessagingPlugin: NSObject, FlutterPlugin, MessagingD
if let fullscreenMessage = message as? FullscreenMessage,
let parentMessage = fullscreenMessage.parent
{
- channel.invokeMethod(
- "urlLoaded",
- arguments: [
- "url": url.absoluteString,
- "message": dataBridge.transformToFlutterMessage(
- message: parentMessage
- ),
- ]
- )
+ DispatchQueue.main.async {
+ self.channel.invokeMethod(
+ "urlLoaded",
+ arguments: [
+ "url": url.absoluteString,
+ "message": self.dataBridge.transformToFlutterMessage(
+ message: parentMessage
+ ),
+ ]
+ )
+ }
}
}
}
diff --git a/plugins/flutter_aepmessaging/pubspec.yaml b/plugins/flutter_aepmessaging/pubspec.yaml
index 0688a0a..c16a5b3 100644
--- a/plugins/flutter_aepmessaging/pubspec.yaml
+++ b/plugins/flutter_aepmessaging/pubspec.yaml
@@ -1,7 +1,7 @@
name: flutter_aepmessaging
description: Official Adobe Experience Platform support for Flutter apps. The Experience Platform Messaging extension enables handling of user push an in-app messages from a mobile app when using the Adobe Experience Platform SDK.
-version: 5.0.0
+version: 5.0.1
homepage: https://aep-sdks.gitbook.io/docs/
repository: https://github.com/adobe/aepsdk_flutter/tree/main/plugins/flutter_aepmessaging