using System; using System.Collections.Generic; using UnityEngine; namespace AppsFlyerSDK { #if UNITY_ANDROID public class AppsFlyerAndroid { private static AndroidJavaClass appsFlyerAndroid = new AndroidJavaClass("com.appsflyer.unity.AppsFlyerAndroidWrapper"); /// <summary> /// Use this method to init the sdk for the application. /// Call this method before startSDK. /// </summary> /// <param name="devkey"> AppsFlyer's Dev-Key, which is accessible from your AppsFlyer account under 'App Settings' in the dashboard.</param> /// <param name="gameObject">The current game object. This is used to get the conversion data callbacks. Pass null if you do not need the callbacks.</param> public static void initSDK(string devkey, MonoBehaviour gameObject) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("initSDK", devkey, gameObject ? gameObject.name : null); #endif } /// <summary> /// Use this method to start the sdk for the application. /// The AppsFlyer's Dev-Key must be provided. /// </summary> /// <param name="devkey"> AppsFlyer's Dev-Key, which is accessible from your AppsFlyer account under 'App Settings' in the dashboard.</param> public static void startSDK() { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("startTracking"); #endif } /// <summary> /// Once this API is invoked, our SDK no longer communicates with our servers and stops functioning. /// In some extreme cases you might want to shut down all SDK activity due to legal and privacy compliance. /// This can be achieved with the stopSDK API. /// </summary> /// <param name="isSDKStopped">boolean should SDK be stopped.</param> public static void stopSDK(bool isSDKStopped) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("stopTracking", isSDKStopped); #endif } /// <summary> /// Get the AppsFlyer SDK version used in app. /// </summary> /// <returns>AppsFlyer SDK version.</returns> public static string getSdkVersion() { #if !UNITY_EDITOR return appsFlyerAndroid.CallStatic<string>("getSdkVersion"); #else return ""; #endif } /// <summary> /// Manually pass the Firebase / GCM Device Token for Uninstall measurement. /// </summary> /// <param name="token">Firebase Device Token.</param> public static void updateServerUninstallToken(string token) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("updateServerUninstallToken", token); #endif } /// <summary> /// Enables Debug logs for the AppsFlyer SDK. /// Should only be set to true in development / debug. /// </summary> /// <param name="shouldEnable">shouldEnable boolean.</param> public static void setIsDebug(bool shouldEnable) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setIsDebug", shouldEnable); #endif } /// <summary> /// By default, IMEI and Android ID are not collected by the SDK if the OS version is higher than KitKat (4.4) /// and the device contains Google Play Services(on SDK versions 4.8.8 and below the specific app needed GPS). /// Use this API to explicitly send IMEI to AppsFlyer. /// </summary> /// <param name="aImei">device's IMEI.</param> public static void setImeiData(string aImei) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setImeiData", aImei); #endif } /// <summary> /// By default, IMEI and Android ID are not collected by the SDK if the OS version is higher than KitKat(4.4) /// and the device contains Google Play Services(on SDK versions 4.8.8 and below the specific app needed GPS). /// Use this API to explicitly send Android ID to AppsFlyer. /// </summary> /// <param name="aAndroidId">device's Android ID.</param> public static void setAndroidIdData(string aAndroidId) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setAndroidIdData", aAndroidId); #endif } /// <summary> /// Setting your own customer ID enables you to cross-reference your own unique ID with AppsFlyer’s unique ID and the other devices’ IDs. /// This ID is available in AppsFlyer CSV reports along with Postback APIs for cross-referencing with your internal IDs. /// </summary> /// <param name="id">Customer ID for client.</param> public static void setCustomerUserId(string id) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setCustomerUserId", id); #endif } /// <summary> /// It is possible to delay the SDK Initialization until the customerUserID is set. /// This feature makes sure that the SDK doesn't begin functioning until the customerUserID is provided. /// If this API is used, all in-app events and any other SDK API calls are discarded, until the customerUserID is provided. /// </summary> /// <param name="wait">wait boolean.</param> public static void waitForCustomerUserId(bool wait) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("waitForCustomerUserId", wait); #endif } /// <summary> /// Use this API to provide the SDK with the relevant customer user id and trigger the SDK to begin its normal activity. /// </summary> /// <param name="id">Customer ID for client.</param> public static void setCustomerIdAndStartSDK(string id) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setCustomerIdAndTrack", id); #endif } /// <summary> /// Get the current AF_STORE value. /// </summary> /// <returns>AF_Store value.</returns> public static string getOutOfStore() { #if !UNITY_EDITOR return appsFlyerAndroid.CallStatic<string>("getOutOfStore"); #else return ""; #endif } /// <summary> /// Manually set the AF_STORE value. /// </summary> /// <param name="sourceName">value to be set.</param> public static void setOutOfStore(string sourceName) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setOutOfStore", sourceName); #endif } /// <summary> /// Set the OneLink ID that should be used for User-Invites. /// The link that is generated for the user invite will use this OneLink as the base link. /// </summary> /// <param name="oneLinkId">OneLink ID obtained from the AppsFlyer Dashboard.</param> public static void setAppInviteOneLinkID(string oneLinkId) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setAppInviteOneLinkID", oneLinkId); #endif } /// <summary> /// Set additional data to be sent to AppsFlyer. /// </summary> /// <param name="customData">additional data Dictionary.</param> public static void setAdditionalData(Dictionary<string, string> customData) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setAdditionalData", convertDictionaryToJavaMap(customData)); #endif } /// <summary> /// Set the user emails. /// </summary> /// <param name="emails">User emails.</param> public static void setUserEmails(params string[] emails) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setUserEmails", (object)emails); #endif } /// <summary> /// Set the user phone number. /// </summary> /// <param name="phoneNumber">User phoneNumber.</param> public static void setPhoneNumber(string phoneNumber){ #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setPhoneNumber", phoneNumber); #endif } /// <summary> /// Set the user emails and encrypt them. /// cryptMethod Encryption method: /// EmailCryptType.EmailCryptTypeMD5 /// EmailCryptType.EmailCryptTypeSHA1 /// EmailCryptType.EmailCryptTypeSHA256 /// EmailCryptType.EmailCryptTypeNone /// </summary> /// <param name="cryptMethod">Encryption method.</param> /// <param name="emails">User emails.</param> public static void setUserEmails(EmailCryptType cryptMethod, params string[] emails) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setUserEmails", getEmailType(cryptMethod), (object)emails); #endif } /// <summary> /// Opt-out of collection of Android ID. /// If the app does NOT contain Google Play Services, Android ID is collected by the SDK. /// However, apps with Google play services should avoid Android ID collection as this is in violation of the Google Play policy. /// </summary> /// <param name="isCollect">boolean, false to opt-out.</param> public static void setCollectAndroidID(bool isCollect) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setCollectAndroidID", isCollect); #endif } /// <summary> /// Opt-out of collection of IMEI. /// If the app does NOT contain Google Play Services, device IMEI is collected by the SDK. /// However, apps with Google play services should avoid IMEI collection as this is in violation of the Google Play policy. /// </summary> /// <param name="isCollect">boolean, false to opt-out.</param> public static void setCollectIMEI(bool isCollect) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setCollectIMEI", isCollect); #endif } /// <summary> /// Advertisers can wrap AppsFlyer OneLink within another Universal Link. /// This Universal Link will invoke the app but any deep linking data will not propagate to AppsFlyer. /// </summary> /// <param name="urls">Array of urls.</param> public static void setResolveDeepLinkURLs(params string[] urls) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setResolveDeepLinkURLs", (object)urls); #endif } /// <summary> /// Advertisers can use this method to set vanity onelink domains. /// </summary> /// <param name="domains">Array of domains.</param> public static void setOneLinkCustomDomain(params string[] domains) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setOneLinkCustomDomain", (object)domains); #endif } /// <summary> /// Manually set that the application was updated. /// </summary> /// <param name="isUpdate">isUpdate boolean value.</param> public static void setIsUpdate(bool isUpdate) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setIsUpdate", isUpdate); #endif } /// <summary> /// Setting user local currency code for in-app purchases. /// The currency code should be a 3 character ISO 4217 code. (default is USD). /// You can set the currency code for all events by calling the following method. /// </summary> /// <param name="currencyCode">3 character ISO 4217 code.</param> public static void setCurrencyCode(string currencyCode) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setCurrencyCode", currencyCode); #endif } /// <summary> /// Manually record the location of the user. /// </summary> /// <param name="latitude">latitude as double.</param> /// <param name="longitude">longitude as double.</param> public static void recordLocation(double latitude, double longitude) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("trackLocation", latitude, longitude); #endif } /// <summary> /// Send an In-App Event. /// In-App Events provide insight on what is happening in your app. /// </summary> /// <param name="eventName">Event Name as String.</param> /// <param name="eventValues">Event Values as Dictionary.</param> public static void sendEvent(string eventName, Dictionary<string, string> eventValues) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("trackEvent", eventName, convertDictionaryToJavaMap(eventValues)); #endif } /// <summary> /// Anonymize user Data. /// Use this API during the SDK Initialization to explicitly anonymize a user's installs, events and sessions. /// Default is false. /// </summary> /// <param name="isDisabled">isDisabled boolean.</param> public static void anonymizeUser(bool isDisabled) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setDeviceTrackingDisabled", isDisabled); #endif } /// <summary> /// Enable the collection of Facebook Deferred AppLinks. /// Requires Facebook SDK and Facebook app on target/client device. /// This API must be invoked prior to initializing the AppsFlyer SDK in order to function properly. /// </summary> /// <param name="isEnabled">should Facebook's deferred app links be processed by the AppsFlyer SDK.</param> public static void enableFacebookDeferredApplinks(bool isEnabled) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("enableFacebookDeferredApplinks", isEnabled); #endif } /// <summary> /// Restrict reengagement via deep-link to once per each unique deep-link. /// Otherwise deep re-occurring deep-links will be permitted for non-singleTask Activities and deep-linking via AppsFlyer deep-links. /// The default value is false. /// </summary> /// <param name="doConsume">doConsume boolean.</param> public static void setConsumeAFDeepLinks(bool doConsume) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setConsumeAFDeepLinks", doConsume); #endif } /// <summary> /// Specify the manufacturer or media source name to which the preinstall is attributed. /// </summary> /// <param name="mediaSource">Manufacturer or media source name for preinstall attribution.</param> /// <param name="campaign">Campaign name for preinstall attribution.</param> /// <param name="siteId">Site ID for preinstall attribution.</param> public static void setPreinstallAttribution(string mediaSource, string campaign, string siteId) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setPreinstallAttribution", mediaSource, campaign, siteId); #endif } /// <summary> /// Boolean indicator for preinstall by Manufacturer. /// </summary> /// <returns>boolean isPreInstalledApp.</returns> public static bool isPreInstalledApp() { #if !UNITY_EDITOR return appsFlyerAndroid.CallStatic<bool>("isPreInstalledApp"); #else return false; #endif } /// <summary> /// Get the Facebook attribution ID, if one exists. /// </summary> /// <returns>string Facebook attribution ID.</returns> public static string getAttributionId() { #if !UNITY_EDITOR return appsFlyerAndroid.CallStatic<string>("getAttributionId"); #else return ""; #endif } /// <summary> /// Get AppsFlyer's unique device ID is created for every new install of an app. /// </summary> /// <returns>AppsFlyer's unique device ID.</returns> public static string getAppsFlyerId() { #if !UNITY_EDITOR return appsFlyerAndroid.CallStatic<string>("getAppsFlyerId"); #else return ""; #endif } /// <summary> /// API for server verification of in-app purchases. /// An af_purchase event with the relevant values will be automatically sent if the validation is successful. /// </summary> /// <param name="publicKey">License Key obtained from the Google Play Console.</param> /// <param name="signature"><code>data.INAPP_DATA_SIGNATURE</code> from <code>onActivityResult(int requestCode, int resultCode, Intent data)</code></param> /// <param name="purchaseData"><code>data.INAPP_PURCHASE_DATA</code> from <code>onActivityResult(int requestCode, int resultCode, Intent data)</code></param> /// <param name="price">Purchase price, should be derived from <code>skuDetails.getStringArrayList("DETAILS_LIST")</code></param> /// <param name="currency">Purchase currency, should be derived from <code>skuDetails.getStringArrayList("DETAILS_LIST")</code></param> /// <param name="additionalParameters">additionalParameters Freehand parameters to be sent with the purchase (if validated).</param> public static void validateAndSendInAppPurchase(string publicKey, string signature, string purchaseData, string price, string currency, Dictionary<string, string> additionalParameters, MonoBehaviour gameObject) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("validateAndTrackInAppPurchase", publicKey, signature, purchaseData, price, currency, convertDictionaryToJavaMap(additionalParameters), gameObject ? gameObject.name : null); #endif } /// <summary> /// Was the stopSDK(boolean) API set to true. /// </summary> /// <returns>boolean isSDKStopped.</returns> public static bool isSDKStopped() { #if !UNITY_EDITOR return appsFlyerAndroid.CallStatic<bool>("isTrackingStopped"); #else return false; #endif } /// <summary> /// Set a custom value for the minimum required time between sessions. /// By default, at least 5 seconds must lapse between 2 app launches to count as separate 2 sessions. /// </summary> /// <param name="seconds">minimum time between 2 separate sessions in seconds.</param> public static void setMinTimeBetweenSessions(int seconds) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setMinTimeBetweenSessions", seconds); #endif } /// <summary> /// Set a custom host. /// </summary> /// <param name="hostPrefixName">Host prefix.</param> /// <param name="hostName">Host name.</param> public static void setHost(string hostPrefixName, string hostName) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setHost", hostPrefixName, hostName); #endif } /// <summary> /// Get the host name. /// Default value is "appsflyer.com". /// </summary> /// <returns>Host name.</returns> public static string getHostName() { #if !UNITY_EDITOR return appsFlyerAndroid.CallStatic<string>("getHostName"); #else return ""; #endif } /// <summary> /// Get the custom host prefix. /// </summary> /// <returns>Host prefix.</returns> public static string getHostPrefix() { #if !UNITY_EDITOR return appsFlyerAndroid.CallStatic<string>("getHostPrefix"); #else return ""; #endif } /// <summary> /// Used by advertisers to exclude all networks/integrated partners from getting data. /// </summary> public static void setSharingFilterForAllPartners() { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setSharingFilterForAllPartners"); #endif } /// <summary> /// Used by advertisers to set some (one or more) networks/integrated partners to exclude from getting data. /// </summary> /// <param name="partners">partners to exclude from getting data</param> public static void setSharingFilter(params string[] partners) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setSharingFilter", (object)partners); #endif } /// <summary> /// Register a Conversion Data Listener. /// Allows the developer to access the user attribution data in real-time for every new install, directly from the SDK level. /// By doing this you can serve users with personalized content or send them to specific activities within the app, /// which can greatly enhance their engagement with your app. /// </summary> public static void getConversionData(string objectName) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("getConversionData", objectName); #endif } /// <summary> /// Register a validation listener for the validateAndSendInAppPurchase API. /// </summary> public static void initInAppPurchaseValidatorListener(MonoBehaviour gameObject) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("initInAppPurchaseValidatorListener", gameObject ? gameObject.name : null); #endif } /// <summary> /// setCollectOaid /// You must include the appsflyer oaid library for this api to work. /// </summary> /// <param name="isCollect">isCollect oaid - set fasle to opt out</param> public static void setCollectOaid(bool isCollect) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("setCollectOaid", isCollect); #endif } /// <summary> /// Use the following API to attribute the click and launch the app store's app page. /// </summary> /// <param name="promoted_app_id">promoted App ID</param> /// <param name="campaign">cross promotion campaign</param> /// <param name="userParams">additional user params</param> public static void attributeAndOpenStore(string promoted_app_id, string campaign, Dictionary<string, string> userParams) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("attributeAndOpenStore", promoted_app_id, campaign, convertDictionaryToJavaMap(userParams)); #endif } /// <summary> /// To attribute an impression use the following API call. /// Make sure to use the promoted App ID as it appears within the AppsFlyer dashboard. /// </summary> /// <param name="appID">promoted App ID.</param> /// <param name="campaign">cross promotion campaign.</param> /// <param name="parameters">parameters Dictionary.</param> public static void recordCrossPromoteImpression(string appID, string campaign, Dictionary<string, string> parameters) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("recordCrossPromoteImpression", appID, campaign, convertDictionaryToJavaMap(parameters)); #endif } /// <summary> /// The LinkGenerator class builds the invite URL according to various setter methods which allow passing on additional information on the click. /// See - https://support.appsflyer.com/hc/en-us/articles/115004480866-User-invite-attribution- /// </summary> /// <param name="parameters">parameters Dictionary.</param> public static void generateUserInviteLink(Dictionary<string, string> parameters, MonoBehaviour gameObject) { #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("createOneLinkInviteListener", convertDictionaryToJavaMap(parameters), gameObject ? gameObject.name : null); #endif } /// <summary> /// To measure push notifications as part of a retargeting campaign. /// </summary> public static void handlePushNotifications(){ #if !UNITY_EDITOR appsFlyerAndroid.CallStatic("handlePushNotifications"); #endif } /// <summary> /// Internal Helper Method. /// </summary> private static AndroidJavaObject getEmailType(EmailCryptType cryptType) { AndroidJavaClass emailsCryptTypeEnum = new AndroidJavaClass("com.appsflyer.AppsFlyerProperties$EmailsCryptType"); AndroidJavaObject emailsCryptType; switch (cryptType) { case EmailCryptType.EmailCryptTypeSHA256: emailsCryptType = emailsCryptTypeEnum.GetStatic<AndroidJavaObject>("SHA256"); break; default: emailsCryptType = emailsCryptTypeEnum.GetStatic<AndroidJavaObject>("NONE"); break; } return emailsCryptType; } /// <summary> /// Internal Helper Method. /// </summary> private static AndroidJavaObject convertDictionaryToJavaMap(Dictionary<string, string> dictionary) { AndroidJavaObject map = new AndroidJavaObject("java.util.HashMap"); IntPtr putMethod = AndroidJNIHelper.GetMethodID(map.GetRawClass(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); if (dictionary != null) { foreach (var entry in dictionary) { AndroidJNI.CallObjectMethod(map.GetRawObject(), putMethod, AndroidJNIHelper.CreateJNIArgArray(new object[] { entry.Key, entry.Value })); } } return map; } } #endif }