diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..ae343b4 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +insert_final_newline = false +max_line_length = 120 +trim_trailing_whitespace = true + +[*.{dart,yml}] +indent_size = 2 + +[*.{kt,kts,swift}] +indent_size = 4 diff --git a/README.md b/README.md index 40594eb..6080bbe 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ $ flutter pub get ### Extra step for iOS 14+ only -4. Follow the instructions available [here](https://wiki.appodeal.com/en/ios/2-8-1-ios-sdk-integration/ios-14+-support) to learn how to implement the permission request to track users, but ignore the part to include some code in the `AppDelegate` file. This code is already included in this plugin and it will be executed when you call the function `Appodeal.requestIOSTrackingAuthorization()`, before the initialization of Appodeal (see below). +4. Follow the instructions available [here](https://wiki.appodeal.com/en/ios/ios-14-network-support) to learn how to implement the permission request to track users, but ignore the part to include some code in the `AppDelegate` file. This code is already included in this plugin and it will be executed when you call the function `Appodeal.requestIOSTrackingAuthorization()`, before the initialization of Appodeal (see below). ## 📱 Usage diff --git a/android/src/main/kotlin/io/vinicius/appodeal_flutter/AppodealBannerFactory.kt b/android/src/main/kotlin/io/vinicius/appodeal_flutter/AppodealBannerFactory.kt index 4f5a5e9..bbc6930 100644 --- a/android/src/main/kotlin/io/vinicius/appodeal_flutter/AppodealBannerFactory.kt +++ b/android/src/main/kotlin/io/vinicius/appodeal_flutter/AppodealBannerFactory.kt @@ -11,15 +11,13 @@ import io.flutter.plugin.common.StandardMessageCodec import io.flutter.plugin.platform.PlatformView import io.flutter.plugin.platform.PlatformViewFactory -class AppodealBannerFactory(private val activity: Activity, private val messenger: BinaryMessenger) - : PlatformViewFactory(StandardMessageCodec.INSTANCE) -{ +class AppodealBannerFactory(private val activity: Activity, private val messenger: BinaryMessenger) : + PlatformViewFactory(StandardMessageCodec.INSTANCE) { override fun create(context: Context?, viewId: Int, args: Any?): PlatformView = - AppodealBannerView(activity, messenger, viewId) + AppodealBannerView(activity, messenger, viewId) - class AppodealBannerView(activity: Activity, messenger: BinaryMessenger, id: Int) - : PlatformView, MethodChannel.MethodCallHandler - { + class AppodealBannerView(activity: Activity, messenger: BinaryMessenger, id: Int) : + PlatformView, MethodChannel.MethodCallHandler { private val bannerView = Appodeal.getBannerView(activity) private val channel = MethodChannel(messenger, "plugins.io.vinicius.appodeal/banner_$id") diff --git a/android/src/main/kotlin/io/vinicius/appodeal_flutter/AppodealFlutterPlugin.kt b/android/src/main/kotlin/io/vinicius/appodeal_flutter/AppodealFlutterPlugin.kt index eac4fd5..305b2e7 100644 --- a/android/src/main/kotlin/io/vinicius/appodeal_flutter/AppodealFlutterPlugin.kt +++ b/android/src/main/kotlin/io/vinicius/appodeal_flutter/AppodealFlutterPlugin.kt @@ -3,10 +3,6 @@ package io.vinicius.appodeal_flutter import android.app.Activity import androidx.annotation.NonNull import com.appodeal.ads.Appodeal -import com.appodeal.ads.BannerCallbacks -import com.appodeal.ads.InterstitialCallbacks -import com.appodeal.ads.NonSkippableVideoCallbacks -import com.appodeal.ads.RewardedVideoCallbacks import com.explorestack.consent.Consent import com.explorestack.consent.Consent.ShouldShow import com.explorestack.consent.ConsentForm @@ -48,7 +44,8 @@ class AppodealFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { // Permissions "disableAndroidLocationPermissionCheck" -> disableAndroidLocationPermissionCheck(result) - "disableAndroidWriteExternalStoragePermissionCheck" -> disableAndroidWriteExternalStoragePermissionCheck(result) + "disableAndroidWriteExternalStoragePermissionCheck" -> + disableAndroidWriteExternalStoragePermissionCheck(result) else -> result.notImplemented() } @@ -62,8 +59,8 @@ class AppodealFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { activity = binding.activity pluginBinding.platformViewRegistry.registerViewFactory( - "plugins.io.vinicius.appodeal/banner", - AppodealBannerFactory(activity, pluginBinding.binaryMessenger) + "plugins.io.vinicius.appodeal/banner", + AppodealBannerFactory(activity, pluginBinding.binaryMessenger) ) } @@ -123,125 +120,10 @@ class AppodealFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { // region - Callbacks private fun setCallbacks() { - Appodeal.setBannerCallbacks(object : BannerCallbacks { - override fun onBannerLoaded(p0: Int, p1: Boolean) { - channel.invokeMethod("onBannerLoaded", null) - } - - override fun onBannerFailedToLoad() { - channel.invokeMethod("onBannerFailedToLoad", null) - } - - override fun onBannerShown() { - channel.invokeMethod("onBannerShown", null) - } - - override fun onBannerShowFailed() { - // Not implemented for the sake of consistency with iOS - } - - override fun onBannerClicked() { - channel.invokeMethod("onBannerClicked", null) - } - - override fun onBannerExpired() { - channel.invokeMethod("onBannerExpired", null) - } - }) - - Appodeal.setInterstitialCallbacks(object : InterstitialCallbacks { - override fun onInterstitialLoaded(isPrecache: Boolean) { - channel.invokeMethod("onInterstitialLoaded", null) - } - - override fun onInterstitialFailedToLoad() { - channel.invokeMethod("onInterstitialFailedToLoad", null) - } - - override fun onInterstitialShown() { - channel.invokeMethod("onInterstitialShown", null) - } - - override fun onInterstitialShowFailed() { - channel.invokeMethod("onInterstitialShowFailed", null) - } - - override fun onInterstitialClicked() { - channel.invokeMethod("onInterstitialClicked", null) - } - - override fun onInterstitialClosed() { - channel.invokeMethod("onInterstitialClosed", null) - } - - override fun onInterstitialExpired() { - channel.invokeMethod("onInterstitialExpired", null) - } - }) - - Appodeal.setRewardedVideoCallbacks(object : RewardedVideoCallbacks { - override fun onRewardedVideoLoaded(isPrecache: Boolean) { - channel.invokeMethod("onRewardedVideoLoaded", null) - } - - override fun onRewardedVideoFailedToLoad() { - channel.invokeMethod("onRewardedVideoFailedToLoad", null) - } - - override fun onRewardedVideoShown() { - channel.invokeMethod("onRewardedVideoShown", null) - } - - override fun onRewardedVideoShowFailed() { - channel.invokeMethod("onRewardedVideoShowFailed", null) - } - - override fun onRewardedVideoFinished(p0: Double, p1: String?) { - channel.invokeMethod("onRewardedVideoFinished", null) - } - - override fun onRewardedVideoClosed(p0: Boolean) { - channel.invokeMethod("onRewardedVideoClosed", null) - } - - override fun onRewardedVideoExpired() { - channel.invokeMethod("onRewardedVideoExpired", null) - } - - override fun onRewardedVideoClicked() { - channel.invokeMethod("onRewardedVideoClicked", null) - } - }) - - Appodeal.setNonSkippableVideoCallbacks(object : NonSkippableVideoCallbacks { - override fun onNonSkippableVideoLoaded(p0: Boolean) { - channel.invokeMethod("onNonSkippableVideoLoaded", null) - } - - override fun onNonSkippableVideoFailedToLoad() { - channel.invokeMethod("onNonSkippableVideoFailedToLoad", null) - } - - override fun onNonSkippableVideoShown() { - channel.invokeMethod("onNonSkippableVideoShown", null) - } - - override fun onNonSkippableVideoShowFailed() { - channel.invokeMethod("onNonSkippableVideoShowFailed", null) - } - - override fun onNonSkippableVideoFinished() { - channel.invokeMethod("onNonSkippableVideoFinished", null) - } - - override fun onNonSkippableVideoClosed(p0: Boolean) { - channel.invokeMethod("onNonSkippableVideoClosed", null) - } - - override fun onNonSkippableVideoExpired() { - channel.invokeMethod("onNonSkippableVideoExpired", null) - } - }) + Appodeal.setBannerCallbacks(bannerCallback(channel)) + Appodeal.setInterstitialCallbacks(interstitialCallback(channel)) + Appodeal.setRewardedVideoCallbacks(rewardedCallback(channel)) + Appodeal.setNonSkippableVideoCallbacks(nonSkippableCallback(channel)) } // endregion @@ -251,24 +133,31 @@ class AppodealFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { val appKey = args["androidAppKey"] as String val consentManager = ConsentManager.getInstance(activity) - consentManager.requestConsentInfoUpdate(appKey, object : ConsentInfoUpdateListener { - override fun onConsentInfoUpdated(consent: Consent?) { - if (consent == null) { - result.success(null) - } else { - result.success(mapOf( - "acceptedVendors" to consent.acceptedVendors?.map { it.name }, - "status" to consent.status.ordinal, - "zone" to consent.zone.ordinal - )) + consentManager.requestConsentInfoUpdate( + appKey, + object : ConsentInfoUpdateListener { + override fun onConsentInfoUpdated(consent: Consent?) { + if (consent == null) { + result.success(null) + } else { + result.success( + mapOf( + "acceptedVendors" to consent.acceptedVendors?.map { it.name }, + "status" to consent.status.ordinal, + "zone" to consent.zone.ordinal + ) + ) + } } - } - override fun onFailedToUpdateConsentInfo(exception: ConsentManagerException?) { - result.error("CONSENT_INFO_ERROR", "Failed to fetch the consent info", - exception?.reason) + override fun onFailedToUpdateConsentInfo(exception: ConsentManagerException?) { + result.error( + "CONSENT_INFO_ERROR", "Failed to fetch the consent info", + exception?.reason + ) + } } - }) + ) } private fun shouldShowConsent(result: Result) { @@ -282,21 +171,23 @@ class AppodealFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { var consentForm: ConsentForm? = null consentForm = ConsentForm.Builder(activity) - .withListener(object : ConsentFormListener { - override fun onConsentFormLoaded() { - consentForm?.showAsDialog() - result.success(null) - } + .withListener(object : ConsentFormListener { + override fun onConsentFormLoaded() { + consentForm?.showAsDialog() + result.success(null) + } - override fun onConsentFormError(exception: ConsentManagerException?) { - result.error("CONSENT_WINDOW_ERROR", - "Error showing the consent window", exception?.reason) - } + override fun onConsentFormError(exception: ConsentManagerException?) { + result.error( + "CONSENT_WINDOW_ERROR", + "Error showing the consent window", exception?.reason + ) + } - override fun onConsentFormOpened() {} - override fun onConsentFormClosed(consent: Consent?) {} - }) - .build() + override fun onConsentFormOpened() {} + override fun onConsentFormClosed(consent: Consent?) {} + }) + .build() consentForm?.load() } diff --git a/android/src/main/kotlin/io/vinicius/appodeal_flutter/BannerCallback.kt b/android/src/main/kotlin/io/vinicius/appodeal_flutter/BannerCallback.kt new file mode 100644 index 0000000..96268e9 --- /dev/null +++ b/android/src/main/kotlin/io/vinicius/appodeal_flutter/BannerCallback.kt @@ -0,0 +1,32 @@ +package io.vinicius.appodeal_flutter + +import com.appodeal.ads.BannerCallbacks +import io.flutter.plugin.common.MethodChannel + +fun bannerCallback(channel: MethodChannel): BannerCallbacks { + return object : BannerCallbacks { + override fun onBannerLoaded(p0: Int, p1: Boolean) { + channel.invokeMethod("onBannerLoaded", null) + } + + override fun onBannerFailedToLoad() { + channel.invokeMethod("onBannerFailedToLoad", null) + } + + override fun onBannerShown() { + channel.invokeMethod("onBannerShown", null) + } + + override fun onBannerShowFailed() { + // Not implemented for the sake of consistency with iOS + } + + override fun onBannerClicked() { + channel.invokeMethod("onBannerClicked", null) + } + + override fun onBannerExpired() { + channel.invokeMethod("onBannerExpired", null) + } + } +} \ No newline at end of file diff --git a/android/src/main/kotlin/io/vinicius/appodeal_flutter/InterstitialCallback.kt b/android/src/main/kotlin/io/vinicius/appodeal_flutter/InterstitialCallback.kt new file mode 100644 index 0000000..3b5af88 --- /dev/null +++ b/android/src/main/kotlin/io/vinicius/appodeal_flutter/InterstitialCallback.kt @@ -0,0 +1,36 @@ +package io.vinicius.appodeal_flutter + +import com.appodeal.ads.InterstitialCallbacks +import io.flutter.plugin.common.MethodChannel + +fun interstitialCallback(channel: MethodChannel): InterstitialCallbacks { + return object : InterstitialCallbacks { + override fun onInterstitialLoaded(isPrecache: Boolean) { + channel.invokeMethod("onInterstitialLoaded", null) + } + + override fun onInterstitialFailedToLoad() { + channel.invokeMethod("onInterstitialFailedToLoad", null) + } + + override fun onInterstitialShown() { + channel.invokeMethod("onInterstitialShown", null) + } + + override fun onInterstitialShowFailed() { + channel.invokeMethod("onInterstitialShowFailed", null) + } + + override fun onInterstitialClicked() { + channel.invokeMethod("onInterstitialClicked", null) + } + + override fun onInterstitialClosed() { + channel.invokeMethod("onInterstitialClosed", null) + } + + override fun onInterstitialExpired() { + channel.invokeMethod("onInterstitialExpired", null) + } + } +} \ No newline at end of file diff --git a/android/src/main/kotlin/io/vinicius/appodeal_flutter/NonSkippableCallback.kt b/android/src/main/kotlin/io/vinicius/appodeal_flutter/NonSkippableCallback.kt new file mode 100644 index 0000000..1e0678c --- /dev/null +++ b/android/src/main/kotlin/io/vinicius/appodeal_flutter/NonSkippableCallback.kt @@ -0,0 +1,36 @@ +package io.vinicius.appodeal_flutter + +import com.appodeal.ads.NonSkippableVideoCallbacks +import io.flutter.plugin.common.MethodChannel + +fun nonSkippableCallback(channel: MethodChannel): NonSkippableVideoCallbacks { + return object : NonSkippableVideoCallbacks { + override fun onNonSkippableVideoLoaded(p0: Boolean) { + channel.invokeMethod("onNonSkippableVideoLoaded", null) + } + + override fun onNonSkippableVideoFailedToLoad() { + channel.invokeMethod("onNonSkippableVideoFailedToLoad", null) + } + + override fun onNonSkippableVideoShown() { + channel.invokeMethod("onNonSkippableVideoShown", null) + } + + override fun onNonSkippableVideoShowFailed() { + channel.invokeMethod("onNonSkippableVideoShowFailed", null) + } + + override fun onNonSkippableVideoFinished() { + channel.invokeMethod("onNonSkippableVideoFinished", null) + } + + override fun onNonSkippableVideoClosed(p0: Boolean) { + channel.invokeMethod("onNonSkippableVideoClosed", null) + } + + override fun onNonSkippableVideoExpired() { + channel.invokeMethod("onNonSkippableVideoExpired", null) + } + } +} \ No newline at end of file diff --git a/android/src/main/kotlin/io/vinicius/appodeal_flutter/RewardedCallback.kt b/android/src/main/kotlin/io/vinicius/appodeal_flutter/RewardedCallback.kt new file mode 100644 index 0000000..87d335f --- /dev/null +++ b/android/src/main/kotlin/io/vinicius/appodeal_flutter/RewardedCallback.kt @@ -0,0 +1,40 @@ +package io.vinicius.appodeal_flutter + +import com.appodeal.ads.RewardedVideoCallbacks +import io.flutter.plugin.common.MethodChannel + +fun rewardedCallback(channel: MethodChannel): RewardedVideoCallbacks { + return object : RewardedVideoCallbacks { + override fun onRewardedVideoLoaded(isPrecache: Boolean) { + channel.invokeMethod("onRewardedVideoLoaded", null) + } + + override fun onRewardedVideoFailedToLoad() { + channel.invokeMethod("onRewardedVideoFailedToLoad", null) + } + + override fun onRewardedVideoShown() { + channel.invokeMethod("onRewardedVideoShown", null) + } + + override fun onRewardedVideoShowFailed() { + channel.invokeMethod("onRewardedVideoShowFailed", null) + } + + override fun onRewardedVideoFinished(p0: Double, p1: String?) { + channel.invokeMethod("onRewardedVideoFinished", null) + } + + override fun onRewardedVideoClosed(p0: Boolean) { + channel.invokeMethod("onRewardedVideoClosed", null) + } + + override fun onRewardedVideoExpired() { + channel.invokeMethod("onRewardedVideoExpired", null) + } + + override fun onRewardedVideoClicked() { + channel.invokeMethod("onRewardedVideoClicked", null) + } + } +} \ No newline at end of file diff --git a/lib/src/appodeal.dart b/lib/src/appodeal.dart index 69480bf..fdc3a9e 100644 --- a/lib/src/appodeal.dart +++ b/lib/src/appodeal.dart @@ -102,7 +102,7 @@ class Appodeal { _interstitialCallback?.call(call.method); } else if (call.method.startsWith('onRewarded')) { _rewardCallback?.call(call.method); - } else if (call.method.startsWith('onRewarded')) { + } else if (call.method.startsWith('onNonSkippable')) { _nonSkippableCallback?.call(call.method); }