fix:1、修复bug。2、更换sdk
This commit is contained in:
Regular → Executable
BIN
Binary file not shown.
Regular → Executable
+2
-2
@@ -1,8 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86460262ea60447dbb6a62d21167790f
|
||||
guid: f7632a50b10045458c53a5ddf7b6d238
|
||||
labels:
|
||||
- gvh
|
||||
- gvh_version-1.2.177
|
||||
- gvh_version-1.2.186
|
||||
- gvhp_exportpath-ExternalDependencyManager/Editor/Google.VersionHandler.dll
|
||||
- gvhp_targets-editor
|
||||
timeCreated: 1480838400
|
||||
|
||||
Regular → Executable
+2
-2
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<dependencies>
|
||||
<androidPackages>
|
||||
<androidPackage spec="com.applovin:applovin-sdk:13.6.2" />
|
||||
<androidPackage spec="com.applovin:applovin-sdk:13.6.3" />
|
||||
</androidPackages>
|
||||
<iosPods>
|
||||
<iosPod name="AppLovinSDK" version="13.6.2" />
|
||||
<iosPod name="AppLovinSDK" version="13.6.3" />
|
||||
</iosPods>
|
||||
</dependencies>
|
||||
|
||||
Regular → Executable
Regular → Executable
BIN
Binary file not shown.
Regular → Executable
Regular → Executable
+2
@@ -1987,6 +1987,8 @@ static ALUnityBackgroundCallback backgroundCallback;
|
||||
|
||||
- (NSString *)requestLatencyMillisFromRequestLatency:(NSTimeInterval)requestLatency
|
||||
{
|
||||
if ( requestLatency == -1 ) return @"-1";
|
||||
|
||||
// Convert latency from seconds to milliseconds to match Android.
|
||||
long requestLatencyMillis = requestLatency * 1000;
|
||||
return @(requestLatencyMillis).stringValue;
|
||||
|
||||
Regular → Executable
Regular → Executable
+1
-1
@@ -8,7 +8,7 @@
|
||||
|
||||
#import "MAUnityAdManager.h"
|
||||
|
||||
#define VERSION @"8.6.2"
|
||||
#define VERSION @"8.6.4"
|
||||
#define NSSTRING(_X) ( (_X != NULL) ? [NSString stringWithCString: _X encoding: NSStringEncodingConversionAllowLossy].al_stringByTrimmingWhitespace : nil)
|
||||
|
||||
@interface NSString (ALUtils)
|
||||
|
||||
Regular → Executable
Regular → Executable
+2
-2
@@ -1,13 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<dependencies>
|
||||
<androidPackages>
|
||||
<androidPackage spec="com.applovin.mediation:bidmachine-adapter:3.6.1.0">
|
||||
<androidPackage spec="com.applovin.mediation:bidmachine-adapter:3.7.1.0">
|
||||
<repositories>
|
||||
<repository>https://artifactory.bidmachine.io/bidmachine</repository>
|
||||
</repositories>
|
||||
</androidPackage>
|
||||
</androidPackages>
|
||||
<iosPods>
|
||||
<iosPod name="AppLovinMediationBidMachineAdapter" version="3.6.1.0.0"/>
|
||||
<iosPod name="AppLovinMediationBidMachineAdapter" version="3.7.1.0.0"/>
|
||||
</iosPods>
|
||||
</dependencies>
|
||||
|
||||
Regular → Executable
Regular → Executable
+2
-2
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<dependencies>
|
||||
<androidPackages>
|
||||
<androidPackage spec="com.applovin.mediation:bigoads-adapter:5.8.2.0" />
|
||||
<androidPackage spec="com.applovin.mediation:bigoads-adapter:5.9.0.0" />
|
||||
</androidPackages>
|
||||
<iosPods>
|
||||
<iosPod name="AppLovinMediationBigoAdsAdapter" version="5.1.2.0" />
|
||||
<iosPod name="AppLovinMediationBigoAdsAdapter" version="5.2.1.0" />
|
||||
</iosPods>
|
||||
</dependencies>
|
||||
|
||||
Regular → Executable
Regular → Executable
+2
-2
@@ -1,13 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<dependencies>
|
||||
<androidPackages>
|
||||
<androidPackage spec="com.applovin.mediation:bytedance-adapter:7.9.1.3.0">
|
||||
<androidPackage spec="com.applovin.mediation:bytedance-adapter:8.1.0.3.0">
|
||||
<repositories>
|
||||
<repository>https://artifact.bytedance.com/repository/pangle</repository>
|
||||
</repositories>
|
||||
</androidPackage>
|
||||
</androidPackages>
|
||||
<iosPods>
|
||||
<iosPod name="AppLovinMediationByteDanceAdapter" version="7.9.1.2.0" />
|
||||
<iosPod name="AppLovinMediationByteDanceAdapter" version="8.1.0.7.0" />
|
||||
</iosPods>
|
||||
</dependencies>
|
||||
|
||||
Regular → Executable
Regular → Executable
+2
-2
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<dependencies>
|
||||
<androidPackages>
|
||||
<androidPackage spec="com.applovin.mediation:chartboost-adapter:9.11.1.0">
|
||||
<androidPackage spec="com.applovin.mediation:chartboost-adapter:9.12.1.0">
|
||||
<repositories>
|
||||
<repository>https://cboost.jfrog.io/artifactory/chartboost-ads/</repository>
|
||||
</repositories>
|
||||
@@ -9,6 +9,6 @@
|
||||
<androidPackage spec="com.google.android.gms:play-services-base:16.1.0" />
|
||||
</androidPackages>
|
||||
<iosPods>
|
||||
<iosPod name="AppLovinMediationChartboostAdapter" version="9.11.0.0" />
|
||||
<iosPod name="AppLovinMediationChartboostAdapter" version="9.12.0.0" />
|
||||
</iosPods>
|
||||
</dependencies>
|
||||
|
||||
Regular → Executable
Regular → Executable
+1
-1
@@ -5,7 +5,7 @@
|
||||
Since FAN SDK depends on older versions of a few support and play service versions
|
||||
`com.applovin.mediation:facebook-adapter:x.y.z.a` resolves to `com.applovin.mediation:facebook-adapter:+` which pulls down the beta versions of FAN SDK.
|
||||
Note that forcing the adapter is enough to stop Jar Resolver from pulling the latest FAN SDK. -->
|
||||
<androidPackage spec="com.applovin.mediation:facebook-adapter:[6.11.0.0]" />
|
||||
<androidPackage spec="com.applovin.mediation:facebook-adapter:[6.21.0.0]" />
|
||||
</androidPackages>
|
||||
<iosPods>
|
||||
<iosPod name="AppLovinMediationFacebookAdapter" version="6.21.1.0" />
|
||||
|
||||
Regular → Executable
Regular → Executable
+2
-2
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<dependencies>
|
||||
<androidPackages>
|
||||
<androidPackage spec="com.applovin.mediation:fyber-adapter:8.4.4.0"/>
|
||||
<androidPackage spec="com.applovin.mediation:fyber-adapter:8.4.5.0"/>
|
||||
</androidPackages>
|
||||
<iosPods>
|
||||
<iosPod name="AppLovinMediationFyberAdapter" version="8.4.6.0"/>
|
||||
<iosPod name="AppLovinMediationFyberAdapter" version="8.4.7.0"/>
|
||||
</iosPods>
|
||||
</dependencies>
|
||||
|
||||
Regular → Executable
Regular → Executable
+2
-2
@@ -2,9 +2,9 @@
|
||||
<dependencies>
|
||||
<androidPackages>
|
||||
<!-- Ensure that Resolver doesn't inadvertently pull the latest Play Services Ads' SDK that we haven't certified against. -->
|
||||
<androidPackage spec="com.applovin.mediation:google-adapter:[25.2.0.0]" />
|
||||
<androidPackage spec="com.applovin.mediation:google-adapter:[25.3.0.0]" />
|
||||
</androidPackages>
|
||||
<iosPods>
|
||||
<iosPod name="AppLovinMediationGoogleAdapter" version="13.3.0.0" />
|
||||
<iosPod name="AppLovinMediationGoogleAdapter" version="13.4.0.0" />
|
||||
</iosPods>
|
||||
</dependencies>
|
||||
|
||||
Regular → Executable
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3e1635bfb5b164c389d38eb1e5e6e909
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Mediation/GoogleAdManager/Editor
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<dependencies>
|
||||
<androidPackages>
|
||||
<!-- Ensure that Resolver doesn't inadvertently pull the latest Play Services Ads' SDK that we haven't certified against. -->
|
||||
<androidPackage spec="com.applovin.mediation:google-ad-manager-adapter:[25.2.0.0]" />
|
||||
</androidPackages>
|
||||
<iosPods>
|
||||
<iosPod name="AppLovinMediationGoogleAdManagerAdapter" version="13.3.0.0" />
|
||||
</iosPods>
|
||||
</dependencies>
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aebbf5e9af66e431fa6078021b2f762f
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Mediation/GoogleAdManager/Editor/Dependencies.xml
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<dependencies>
|
||||
<androidPackages>
|
||||
<androidPackage spec="com.applovin.mediation:inmobi-adapter:11.2.0.0" />
|
||||
<androidPackage spec="com.squareup.picasso:picasso:2.71828" />
|
||||
<androidPackage spec="com.android.support:recyclerview-v7:28.+" />
|
||||
<androidPackage spec="com.android.support:customtabs:28.+" />
|
||||
</androidPackages>
|
||||
<iosPods>
|
||||
<iosPod name="AppLovinMediationInMobiAdapter" version="11.2.0.0" />
|
||||
</iosPods>
|
||||
</dependencies>
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bc66a0ef4503843ee9b1bf1b1e867367
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Mediation/InMobi/Editor/Dependencies.xml
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Regular → Executable
+2
-2
@@ -1,10 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<dependencies>
|
||||
<androidPackages>
|
||||
<androidPackage spec="com.applovin.mediation:ironsource-adapter:9.4.0.0.0" />
|
||||
<androidPackage spec="com.applovin.mediation:ironsource-adapter:9.4.3.0.0" />
|
||||
|
||||
</androidPackages>
|
||||
<iosPods>
|
||||
<iosPod name="AppLovinMediationIronSourceAdapter" version="9.4.0.0.0" />
|
||||
<iosPod name="AppLovinMediationIronSourceAdapter" version="9.4.1.0.0" />
|
||||
</iosPods>
|
||||
</dependencies>
|
||||
|
||||
Regular → Executable
Regular → Executable
+2
-2
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<dependencies>
|
||||
<androidPackages>
|
||||
<androidPackage spec="com.applovin.mediation:mintegral-adapter:17.1.51.0">
|
||||
<androidPackage spec="com.applovin.mediation:mintegral-adapter:17.1.61.0">
|
||||
<repositories>
|
||||
<repository>https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea</repository>
|
||||
</repositories>
|
||||
@@ -9,6 +9,6 @@
|
||||
<androidPackage spec="androidx.recyclerview:recyclerview:1.2.1" />
|
||||
</androidPackages>
|
||||
<iosPods>
|
||||
<iosPod name="AppLovinMediationMintegralAdapter" version="8.1.1.0.0" />
|
||||
<iosPod name="AppLovinMediationMintegralAdapter" version="8.1.5.0.0" />
|
||||
</iosPods>
|
||||
</dependencies>
|
||||
|
||||
Regular → Executable
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ecadc3649c184389b90252aa2a2b448
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Mediation/Moloco/Editor
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<dependencies>
|
||||
<androidPackages>
|
||||
<androidPackage spec="com.applovin.mediation:moloco-adapter:4.8.0.0" />
|
||||
</androidPackages>
|
||||
<iosPods>
|
||||
<iosPod name="AppLovinMediationMolocoAdapter" version="4.6.0.0" />
|
||||
</iosPods>
|
||||
</dependencies>
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f5b2cb1209274ba18b234b42d2efe96
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Mediation/Moloco/Editor/Dependencies.xml
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Regular → Executable
+2
-2
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<dependencies>
|
||||
<androidPackages>
|
||||
<androidPackage spec="com.applovin.mediation:unityads-adapter:4.17.0.0" />
|
||||
<androidPackage spec="com.applovin.mediation:unityads-adapter:4.18.1.0" />
|
||||
</androidPackages>
|
||||
<iosPods>
|
||||
<iosPod name="AppLovinMediationUnityAdsAdapter" version="4.17.0.0" />
|
||||
<iosPod name="AppLovinMediationUnityAdsAdapter" version="4.18.1.0" />
|
||||
</iosPods>
|
||||
</dependencies>
|
||||
|
||||
Regular → Executable
Regular → Executable
+2
-2
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<dependencies>
|
||||
<androidPackages>
|
||||
<androidPackage spec="com.applovin.mediation:vungle-adapter:7.7.3.0" />
|
||||
<androidPackage spec="com.applovin.mediation:vungle-adapter:7.7.4.0" />
|
||||
</androidPackages>
|
||||
<iosPods>
|
||||
<iosPod name="AppLovinMediationVungleAdapter" version="7.7.2.0" />
|
||||
<iosPod name="AppLovinMediationVungleAdapter" version="7.7.4.0" />
|
||||
</iosPods>
|
||||
</dependencies>
|
||||
|
||||
Regular → Executable
@@ -16,5 +16,5 @@ MonoBehaviour:
|
||||
sdkKey: mmVXU9O_ESeur52h0VwzCGfbI4wB8LxeBfydReplRMm2JmN8eNMVgSuiKy2bmTJ00m4DHSKFxhaH1pnpEME5bB
|
||||
customGradleVersionUrl:
|
||||
customGradleToolsVersion:
|
||||
adMobAndroidAppId:
|
||||
adMobAndroidAppId: ca-app-pub-3940256099942544~3347511713
|
||||
adMobIosAppId: ca-app-pub-6060482967044764~9684940018
|
||||
|
||||
Regular → Executable
Regular → Executable
+1
@@ -19,6 +19,7 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
"AdColony",
|
||||
"Criteo",
|
||||
"LinkedIn",
|
||||
"Nend",
|
||||
"Snap",
|
||||
"Tapjoy",
|
||||
|
||||
Regular → Executable
Regular → Executable
+1
-1
@@ -373,7 +373,7 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
if (!webResponse.IsSuccess)
|
||||
{
|
||||
MaxSdkLogger.E("Failed to load plugin data. Please check your internet connection.");
|
||||
MaxSdkLogger.UserError("Failed to load plugin data. Please check your internet connection.");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Regular → Executable
Regular → Executable
+5
-13
@@ -27,8 +27,6 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
private const string PropertyAndroidX = "android.useAndroidX";
|
||||
private const string PropertyJetifier = "android.enableJetifier";
|
||||
private const string EnableProperty = "=true";
|
||||
private const string PropertyDexingArtifactTransform = "android.enableDexingArtifactTransform";
|
||||
private const string DisableProperty = "=false";
|
||||
|
||||
private const string KeyMetaDataAppLovinVerboseLoggingOn = "applovin.sdk.verbose_logging";
|
||||
private const string KeyMetaDataGoogleApplicationId = "com.google.android.gms.ads.APPLICATION_ID";
|
||||
@@ -82,19 +80,13 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
var lines = File.ReadAllLines(gradlePropertiesPath);
|
||||
|
||||
// Add all properties except AndroidX, Jetifier, and DexingArtifactTransform since they may already exist. We will re-add them below.
|
||||
gradlePropertiesUpdated.AddRange(lines.Where(line => !line.Contains(PropertyAndroidX) && !line.Contains(PropertyJetifier) && !line.Contains(PropertyDexingArtifactTransform)));
|
||||
gradlePropertiesUpdated.AddRange(lines.Where(line => !line.Contains(PropertyAndroidX) && !line.Contains(PropertyJetifier)));
|
||||
}
|
||||
|
||||
// Enable AndroidX and Jetifier properties
|
||||
gradlePropertiesUpdated.Add(PropertyAndroidX + EnableProperty);
|
||||
gradlePropertiesUpdated.Add(PropertyJetifier + EnableProperty);
|
||||
|
||||
// `DexingArtifactTransform` has been removed in Gradle 8+ which is the default Gradle version for Unity 6.
|
||||
#if !UNITY_6000_0_OR_NEWER
|
||||
// Disable dexing using artifact transform (it causes issues for ExoPlayer with Gradle plugin 3.5.0+)
|
||||
gradlePropertiesUpdated.Add(PropertyDexingArtifactTransform + DisableProperty);
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText(gradlePropertiesPath, string.Join("\n", gradlePropertiesUpdated.ToArray()) + "\n");
|
||||
@@ -282,7 +274,7 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
}
|
||||
else
|
||||
{
|
||||
MaxSdkLogger.E("Failed to set distribution URL");
|
||||
MaxSdkLogger.UserError("Failed to set distribution URL");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,7 +284,7 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
// Unity 2022.3+ requires Gradle Plugin version 7.1.2+.
|
||||
if (MaxSdkUtils.CompareVersions(customGradleToolsVersion, "7.1.2") == MaxSdkUtils.VersionComparisonResult.Lesser)
|
||||
{
|
||||
MaxSdkLogger.E("Failed to set gradle plugin version. Unity 2022.3+ requires gradle plugin version 7.1.2+");
|
||||
MaxSdkLogger.UserError("Failed to set gradle plugin version. Unity 2022.3+ requires gradle plugin version 7.1.2+");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -303,7 +295,7 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
}
|
||||
else
|
||||
{
|
||||
MaxSdkLogger.E("Failed to set gradle library version");
|
||||
MaxSdkLogger.UserError("Failed to set gradle library version");
|
||||
}
|
||||
|
||||
var newGradleVersionLine = AppLovinProcessGradleBuildFile.GetFormattedBuildScriptLine(string.Format("id 'com.android.application' version '{0}' apply false", customGradleToolsVersion));
|
||||
@@ -316,7 +308,7 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
}
|
||||
else
|
||||
{
|
||||
MaxSdkLogger.E("Failed to set gradle plugin version");
|
||||
MaxSdkLogger.UserError("Failed to set gradle plugin version");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Regular → Executable
Regular → Executable
+1
-1
@@ -224,7 +224,7 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
var pluginData = AppLovinIntegrationManager.LoadPluginDataSync();
|
||||
if (pluginData == null)
|
||||
{
|
||||
MaxSdkLogger.E("Failed to load plugin data. Dynamic libraries will not be embedded.");
|
||||
MaxSdkLogger.UserError("Failed to load plugin data. Dynamic libraries will not be embedded.");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Regular → Executable
Regular → Executable
+2
-2
@@ -57,7 +57,7 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.E("Unable to load Dependencies file due to exception: " + exception.Message);
|
||||
MaxSdkLogger.UserError("Unable to load Dependencies file due to exception: " + exception.Message);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -173,7 +173,7 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.E("Unable to save Dependencies file due to exception: " + exception.Message);
|
||||
MaxSdkLogger.UserError("Unable to save Dependencies file due to exception: " + exception.Message);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
Regular → Executable
Regular → Executable
+1
-1
@@ -14,7 +14,7 @@ public class MaxSdk :
|
||||
MaxSdkUnityEditor
|
||||
#endif
|
||||
{
|
||||
private const string _version = "8.6.2";
|
||||
private const string _version = "8.6.4";
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current plugin version.
|
||||
|
||||
Regular → Executable
+47466
-45928
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,9 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools" tools:keep="@string/gcm_defaultSenderId,@string/google_storage_bucket,@string/project_id,@string/google_api_key,@string/google_crash_reporting_api_key,@string/google_app_id">
|
||||
<string name="gcm_defaultSenderId" translatable="false">47379855623</string>
|
||||
<string name="google_storage_bucket" translatable="false">cursed-night-vampire-slots.firebasestorage.app</string>
|
||||
<string name="project_id" translatable="false">cursed-night-vampire-slots</string>
|
||||
<string name="google_api_key" translatable="false">AIzaSyDXG6OV3RO0ydU80q8ZiudbIDRc1mh30kY</string>
|
||||
<string name="google_crash_reporting_api_key" translatable="false">AIzaSyDXG6OV3RO0ydU80q8ZiudbIDRc1mh30kY</string>
|
||||
<string name="google_app_id" translatable="false">1:47379855623:android:9723758e453cb34ff5eda2</string>
|
||||
<string name="gcm_defaultSenderId" translatable="false">108853233638</string>
|
||||
<string name="google_storage_bucket" translatable="false">divine-position-377306.firebasestorage.app</string>
|
||||
<string name="project_id" translatable="false">divine-position-377306</string>
|
||||
<string name="google_api_key" translatable="false">AIzaSyCsdr_yhJsg61ZeX5pyNbsj41j6vUdzgK8</string>
|
||||
<string name="google_crash_reporting_api_key" translatable="false">AIzaSyCsdr_yhJsg61ZeX5pyNbsj41j6vUdzgK8</string>
|
||||
<string name="google_app_id" translatable="false">1:108853233638:android:3f27e4b07279832738b827</string>
|
||||
</resources>
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><resources><string name="com.crashlytics.android.build_id" translatable="false">727fe3ed-708f-4699-a198-d58d2e7e6a8b</string></resources>
|
||||
<?xml version="1.0" encoding="utf-8"?><resources><string name="com.crashlytics.android.build_id" translatable="false">ef69acce-f4ca-4d4a-b16c-51c7a46da3ac</string></resources>
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
// GENERATED BY UNITY. REMOVE THIS LINE TO PREVENT OVERWRITING WHEN CHANGING PLAYER SETTINGS
|
||||
|
||||
// 第一步:把用来修补 D8 编译器的 buildscript 独立提拔到最外层的最顶部
|
||||
buildscript {
|
||||
repositories {
|
||||
**BUILD_SCRIPT_REPOSITORIES**
|
||||
// 1. 添加存放新版 D8 编译器的谷歌官方仓库
|
||||
maven { url 'https://storage.googleapis.com/r8-releases/raw' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// 2. 强制指定更高级别的 R8/D8 编译器,解决 Meta SDK 引发的 NullPointerException
|
||||
classpath 'com.android.tools:r8:8.2.24'
|
||||
**BUILD_SCRIPT_DEPENDENCIES**
|
||||
}
|
||||
}
|
||||
|
||||
// 第二步:紧随其后的是原配 plugins 块(绝对不能被allprojects压在下面)
|
||||
plugins {
|
||||
// If you are changing the Android Gradle Plugin version, make sure it is compatible with the Gradle version preinstalled with Unity
|
||||
// See which Gradle version is preinstalled with Unity here https://docs.unity3d.com/Manual/android-gradle-overview.html
|
||||
// See official Gradle and Android Gradle Plugin compatibility table here https://developer.android.com/studio/releases/gradle-plugin#updating-gradle
|
||||
// To specify a custom Gradle version in Unity, go do "Preferences > External Tools", uncheck "Gradle Installed with Unity (recommended)" and specify a path to a custom Gradle version
|
||||
id 'com.android.application' version '7.4.2' apply false
|
||||
id 'com.android.library' version '7.4.2' apply false
|
||||
**BUILD_SCRIPT_DEPS**
|
||||
}
|
||||
|
||||
// 第三步:将通用的 allprojects 移到文件下方安全区
|
||||
allprojects {
|
||||
repositories {
|
||||
**PROJECT_REPOSITORIES**
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 757bd9d7c7934134c847701c129e1f2f
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -9,4 +9,5 @@ android.enableJetifier=true
|
||||
|
||||
android.jetifier.ignorelist=annotation-experimental-1.4.0.aar
|
||||
android.enableLint=false
|
||||
android.lint.disableLintTasks=true
|
||||
android.lint.disableLintTasks=true
|
||||
org.gradle.jvmargs=-Xmx4056m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
@@ -22,39 +22,39 @@ dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
|
||||
// Android Resolver Dependencies Start
|
||||
implementation 'androidx.annotation:annotation:1.2.0' // Assets/H1PQxZETMtqhSoMBSDK/ThirdParty/KwaiAds/Editor/Dependencies.xml:7
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0' // Assets/H1PQxZETMtqhSoMBSDK/ThirdParty/KwaiAds/Editor/Dependencies.xml:5
|
||||
implementation 'androidx.annotation:annotation:1.2.0' // Assets/KRSMgn_MxJJ9SpPJGSDK/ThirdParty/KwaiAds/Editor/Dependencies.xml:7
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0' // Assets/KRSMgn_MxJJ9SpPJGSDK/ThirdParty/KwaiAds/Editor/Dependencies.xml:5
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4' // Assets/GoogleMobileAds/Editor/GoogleMobileAdsDependencies.xml:12
|
||||
implementation 'androidx.lifecycle:lifecycle-process:2.6.2' // Assets/GoogleMobileAds/Editor/GoogleMobileAdsDependencies.xml:17
|
||||
implementation 'androidx.media3:media3-exoplayer:1.0.0-alpha01' // Assets/H1PQxZETMtqhSoMBSDK/ThirdParty/KwaiAds/Editor/Dependencies.xml:4
|
||||
implementation 'androidx.media3:media3-exoplayer:1.0.0-alpha01' // Assets/KRSMgn_MxJJ9SpPJGSDK/ThirdParty/KwaiAds/Editor/Dependencies.xml:4
|
||||
implementation 'androidx.recyclerview:recyclerview:1.2.1' // Assets/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:9
|
||||
implementation 'com.android.installreferrer:installreferrer:2.1' // Assets/H1PQxZETMtqhSoMBSDK/ThirdParty/AppsFlyer/Editor/AppsFlyerDependencies.xml:7
|
||||
implementation 'com.android.installreferrer:installreferrer:2.1' // Assets/KRSMgn_MxJJ9SpPJGSDK/ThirdParty/AppsFlyer/Editor/AppsFlyerDependencies.xml:7
|
||||
implementation 'com.android.support:customtabs:28.+' // Assets/MaxSdk/Mediation/InMobi/Editor/Dependencies.xml:7
|
||||
implementation 'com.android.support:recyclerview-v7:28.+' // Assets/MaxSdk/Mediation/InMobi/Editor/Dependencies.xml:6
|
||||
implementation 'com.applovin.mediation:bidmachine-adapter:3.6.1.0' // Assets/MaxSdk/Mediation/BidMachine/Editor/Dependencies.xml:8
|
||||
implementation 'com.applovin.mediation:bigoads-adapter:5.8.2.0' // Assets/MaxSdk/Mediation/BigoAds/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:bytedance-adapter:7.9.1.3.0' // Assets/MaxSdk/Mediation/ByteDance/Editor/Dependencies.xml:8
|
||||
implementation 'com.applovin.mediation:chartboost-adapter:9.11.1.0' // Assets/MaxSdk/Mediation/Chartboost/Editor/Dependencies.xml:8
|
||||
implementation 'com.applovin.mediation:facebook-adapter:[6.11.0.0]' // Assets/MaxSdk/Mediation/Facebook/Editor/Dependencies.xml:8
|
||||
implementation 'com.applovin.mediation:fyber-adapter:8.4.4.0' // Assets/MaxSdk/Mediation/Fyber/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:google-adapter:[25.2.0.0]' // Assets/MaxSdk/Mediation/Google/Editor/Dependencies.xml:5
|
||||
implementation 'com.applovin.mediation:google-ad-manager-adapter:[25.2.0.0]' // Assets/MaxSdk/Mediation/GoogleAdManager/Editor/Dependencies.xml:5
|
||||
implementation 'com.applovin.mediation:inmobi-adapter:11.2.0.0' // Assets/MaxSdk/Mediation/InMobi/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:ironsource-adapter:9.4.0.0.0' // Assets/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:mintegral-adapter:17.1.51.0' // Assets/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:8
|
||||
implementation 'com.applovin.mediation:moloco-adapter:4.8.0.0' // Assets/MaxSdk/Mediation/Moloco/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:unityads-adapter:4.17.0.0' // Assets/MaxSdk/Mediation/UnityAds/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:vungle-adapter:7.7.3.0' // Assets/MaxSdk/Mediation/Vungle/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin:applovin-sdk:13.6.2' // Assets/MaxSdk/AppLovin/Editor/Dependencies.xml:4
|
||||
implementation 'com.appsflyer:af-android-sdk:6.17.6' // Assets/H1PQxZETMtqhSoMBSDK/ThirdParty/AppsFlyer/Editor/AppsFlyerDependencies.xml:5
|
||||
implementation 'com.appsflyer:purchase-connector:2.2.0' // Assets/H1PQxZETMtqhSoMBSDK/ThirdParty/AppsFlyer/Editor/AppsFlyerDependencies.xml:8
|
||||
implementation 'com.appsflyer:unity-wrapper:6.17.91' // Assets/H1PQxZETMtqhSoMBSDK/ThirdParty/AppsFlyer/Editor/AppsFlyerDependencies.xml:6
|
||||
implementation 'com.bigossp:bigo-ads:5.3.0' // Assets/H1PQxZETMtqhSoMBSDK/ThirdParty/BigoAdsAll/BigoSDK/Editor/Dependencies.xml:11
|
||||
implementation 'com.applovin.mediation:bidmachine-adapter:3.7.1.0' // Assets/MaxSdk/Mediation/BidMachine/Editor/Dependencies.xml:8
|
||||
implementation 'com.applovin.mediation:bigoads-adapter:5.9.0.0' // Assets/MaxSdk/Mediation/BigoAds/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:bytedance-adapter:8.1.0.3.0' // Assets/MaxSdk/Mediation/ByteDance/Editor/Dependencies.xml:8
|
||||
implementation 'com.applovin.mediation:chartboost-adapter:9.12.1.0' // Assets/MaxSdk/Mediation/Chartboost/Editor/Dependencies.xml:8
|
||||
implementation 'com.applovin.mediation:facebook-adapter:[6.21.0.0]' // Assets/MaxSdk/Mediation/Facebook/Editor/Dependencies.xml:8
|
||||
implementation 'com.applovin.mediation:fyber-adapter:8.4.5.0' // Assets/MaxSdk/Mediation/Fyber/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:google-adapter:[25.3.0.0]' // Assets/MaxSdk/Mediation/Google/Editor/Dependencies.xml:5
|
||||
implementation 'com.applovin.mediation:google-ad-manager-adapter:[25.3.0.0]' // Assets/MaxSdk/Mediation/GoogleAdManager/Editor/Dependencies.xml:5
|
||||
implementation 'com.applovin.mediation:inmobi-adapter:11.3.0.0' // Assets/MaxSdk/Mediation/InMobi/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:ironsource-adapter:9.4.3.0.0' // Assets/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:mintegral-adapter:17.1.61.0' // Assets/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:8
|
||||
implementation 'com.applovin.mediation:moloco-adapter:4.9.0.0' // Assets/MaxSdk/Mediation/Moloco/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:unityads-adapter:4.18.1.0' // Assets/MaxSdk/Mediation/UnityAds/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:vungle-adapter:7.7.4.0' // Assets/MaxSdk/Mediation/Vungle/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin:applovin-sdk:13.6.3' // Assets/MaxSdk/AppLovin/Editor/Dependencies.xml:4
|
||||
implementation 'com.appsflyer:af-android-sdk:6.17.6' // Assets/KRSMgn_MxJJ9SpPJGSDK/ThirdParty/AppsFlyer/Editor/AppsFlyerDependencies.xml:5
|
||||
implementation 'com.appsflyer:purchase-connector:2.2.0' // Assets/KRSMgn_MxJJ9SpPJGSDK/ThirdParty/AppsFlyer/Editor/AppsFlyerDependencies.xml:8
|
||||
implementation 'com.appsflyer:unity-wrapper:6.17.91' // Assets/KRSMgn_MxJJ9SpPJGSDK/ThirdParty/AppsFlyer/Editor/AppsFlyerDependencies.xml:6
|
||||
implementation 'com.bigossp:bigo-ads:5.3.0' // Assets/KRSMgn_MxJJ9SpPJGSDK/ThirdParty/BigoAdsAll/BigoSDK/Editor/Dependencies.xml:11
|
||||
implementation 'com.google.android.gms:play-services-ads:24.5.0' // Assets/GoogleMobileAds/Editor/GoogleMobileAdsDependencies.xml:7
|
||||
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1' // Assets/H1PQxZETMtqhSoMBSDK/ThirdParty/KwaiAds/Editor/Dependencies.xml:9
|
||||
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1' // Assets/KRSMgn_MxJJ9SpPJGSDK/ThirdParty/KwaiAds/Editor/Dependencies.xml:9
|
||||
// implementation 'com.google.android.gms:play-services-base:16.1.0' // Assets/MaxSdk/Mediation/Chartboost/Editor/Dependencies.xml:9
|
||||
implementation 'com.google.android.gms:play-services-base:18.6.0' // Assets/Firebase/Editor/AppDependencies.xml:17
|
||||
implementation 'com.google.android.material:material:1.2.1' // Assets/H1PQxZETMtqhSoMBSDK/ThirdParty/KwaiAds/Editor/Dependencies.xml:6
|
||||
implementation 'com.google.android.material:material:1.2.1' // Assets/KRSMgn_MxJJ9SpPJGSDK/ThirdParty/KwaiAds/Editor/Dependencies.xml:6
|
||||
implementation 'com.google.android.ump:user-messaging-platform:3.2.0' // Assets/GoogleMobileAds/Editor/GoogleUmpDependencies.xml:7
|
||||
implementation 'com.google.firebase:firebase-analytics:22.4.0' // Assets/Firebase/Editor/MessagingDependencies.xml:15
|
||||
implementation 'com.google.firebase:firebase-analytics-unity:12.8.0' // Assets/Firebase/Editor/AnalyticsDependencies.xml:18
|
||||
@@ -67,7 +67,7 @@ dependencies {
|
||||
implementation 'com.google.firebase:firebase-messaging-unity:12.8.0' // Assets/Firebase/Editor/MessagingDependencies.xml:24
|
||||
implementation 'com.google.flatbuffers:flatbuffers-java:1.12.0' // Assets/Firebase/Editor/MessagingDependencies.xml:19
|
||||
implementation 'com.squareup.picasso:picasso:2.71828' // Assets/MaxSdk/Mediation/InMobi/Editor/Dependencies.xml:5
|
||||
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.10' // Assets/H1PQxZETMtqhSoMBSDK/ThirdParty/KwaiAds/Editor/Dependencies.xml:8
|
||||
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.10' // Assets/KRSMgn_MxJJ9SpPJGSDK/ThirdParty/KwaiAds/Editor/Dependencies.xml:8
|
||||
// Android Resolver Dependencies End
|
||||
**DEPS**}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ dependencyResolutionManagement {
|
||||
url "https://maven.aliyun.com/repository/google" // Assets/GoogleMobileAds/Editor/GoogleMobileAdsDependencies.xml:7, Assets/GoogleMobileAds/Editor/GoogleMobileAdsDependencies.xml:12, Assets/GoogleMobileAds/Editor/GoogleMobileAdsDependencies.xml:17, Assets/GoogleMobileAds/Editor/GoogleUmpDependencies.xml:7
|
||||
}
|
||||
maven {
|
||||
url "https://repo1.maven.org/maven2/" // Assets/H1PQxZETMtqhSoMBSDK/ThirdParty/BigoAdsAll/BigoSDK/Editor/Dependencies.xml:11
|
||||
url "https://repo1.maven.org/maven2/" // Assets/KRSMgn_MxJJ9SpPJGSDK/ThirdParty/BigoAdsAll/BigoSDK/Editor/Dependencies.xml:11
|
||||
}
|
||||
maven {
|
||||
url "https://artifactory.bidmachine.io/bidmachine" // Assets/MaxSdk/Mediation/BidMachine/Editor/Dependencies.xml:8
|
||||
|
||||
@@ -25,7 +25,7 @@ MonoBehaviour:
|
||||
kwaiAppId:
|
||||
kwaiVideoUnitId: []
|
||||
kwaiInterUnitId: []
|
||||
bigoAppId:
|
||||
bigoAppId: 11928323
|
||||
bigoVideoUnitId: []
|
||||
bigoInterUnitId: []
|
||||
bigoSplashUnitId:
|
||||
|
||||
@@ -150,25 +150,26 @@ public class RgfCDfHLhn9WSDKDemo : MonoBehaviour
|
||||
private int payIndex = 0;
|
||||
public void CreateWithDrawOrder()
|
||||
{
|
||||
string taxNo = "";
|
||||
string taxNo = "99999999999";
|
||||
string payAccount = "tom@gmail.com";
|
||||
string accountType = "E";
|
||||
PaymentTypeCode payCode = PaymentTypeCode.GOPAY;
|
||||
//GOPAY DANA 收款账号需要为电话号码
|
||||
if (payIndex == 1 || payIndex == 0)
|
||||
{
|
||||
payCode = payIndex == 1 ? PaymentTypeCode.DANA : payCode;
|
||||
payAccount = "0881234567890";
|
||||
accountType = "P";
|
||||
}
|
||||
if (payIndex == 2)
|
||||
{
|
||||
// PIX 需要填写税号
|
||||
payCode = PaymentTypeCode.PIX;
|
||||
taxNo = "99999999999";
|
||||
}
|
||||
if (payIndex == 3) payCode = PaymentTypeCode.MERCADOPAGO;
|
||||
RgfCDfHLhn9WSDK_Utility.Instance.CreateWithDrawOrder(withDrawSceneId, payCode, payAccount, accountType, "testName", taxNo, b =>
|
||||
string payeeName = "testName";
|
||||
PaymentTypeCode payCode = PaymentTypeCode.PAYPAL;
|
||||
////GOPAY DANA 收款账号需要为电话号码
|
||||
//if (payIndex == 1 || payIndex == 0)
|
||||
//{
|
||||
// payCode = payIndex == 1 ? PaymentTypeCode.DANA : payCode;
|
||||
// payAccount = "0881234567890";
|
||||
// accountType = "P";
|
||||
//}
|
||||
//if (payIndex == 2)
|
||||
//{
|
||||
// // PIX 需要填写税号
|
||||
// payCode = PaymentTypeCode.PIX;
|
||||
// taxNo = "99999999999";
|
||||
//}
|
||||
//if (payIndex == 3) payCode = PaymentTypeCode.MERCADOPAGO;
|
||||
RgfCDfHLhn9WSDK_Utility.Instance.CreateWithDrawOrder(withDrawSceneId, payCode, payAccount, accountType, payeeName, taxNo, b =>
|
||||
{
|
||||
Debug.Log($"CreateWithDrawOrder result : {b}");
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0cfff26b2061e224899deddcc8cd5a3d
|
||||
guid: 1352a2024c5a80c4b828bb608b55a855
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec7c9f6bcd7424c488b87567cb2fb906
|
||||
guid: 4d36e858954cc5746a02974f074e6af3
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f75dec80f49c44ee68edd909bd32747a
|
||||
guid: 3907509d068e9394e8294fc2aec86578
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
Vendored
Executable
+374
@@ -0,0 +1,374 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this package will be documented in this file.
|
||||
|
||||
## [2.3.2] - 2024-02-09
|
||||
|
||||
### Fixes:
|
||||
- [Android] - Remove excessive permissions and metadata from default manifest (auto-add them based on settings).
|
||||
- [Android] - Fixed notification status reporting after dismissing notification and re-launching the app.
|
||||
- [iOS] - Fixed a possible crash when sending push notifications with attachment (like image).
|
||||
|
||||
## [2.3.1] - 2023-12-11
|
||||
|
||||
### Fixes:
|
||||
- [Android] - Mark Android library to be compatible only with Android.
|
||||
- [iOS] - Calendar trigger will use local or UTC time depending on which one is set on trigger.
|
||||
- Various documentation fixes.
|
||||
|
||||
## [2.3.0] - 2023-10-09
|
||||
|
||||
### Changes & Improvements:
|
||||
|
||||
- Added unified APIs for basic notifications that work on both platforms in the `Unity.Notifications` namespace.
|
||||
- Sample project modified to use unified APIs.
|
||||
- [Android] - Package now placed to Gradle project as a separate module (.androidlib).
|
||||
- [iOS] - Added APIs for checking and unregistering for push notifications.
|
||||
- [iOS] - Added new presentation options, supported since iOS 14 (list and banner).
|
||||
|
||||
### Fixes:
|
||||
- [Android] - [issue 290](https://github.com/Unity-Technologies/com.unity.mobile.notifications/issues/290) Fix large icon not displayed when privided as file path.
|
||||
|
||||
## [2.2.2] - 2023-09-07
|
||||
|
||||
### Changes & Improvements:
|
||||
- [Android] - Reschedule after reboot will send all notifications that expired less than 10 minutes ago.
|
||||
- [iOS] - Remote notifications now support showInForeground key (allows to show notification while app is the foreground).
|
||||
|
||||
### Fixes:
|
||||
- [Android] - [issue 271](https://github.com/Unity-Technologies/com.unity.mobile.notifications/issues/271) Fix possible ANR when sending/rescheduling after reboot.
|
||||
- [iOS] - Remote notification presentation options work regardless of when authorization is performed.
|
||||
- [iOS] - Remote notifications have presentation independent of whether callback is registered or not.
|
||||
|
||||
## [2.2.1] - 2023-07-17
|
||||
|
||||
### Fixes:
|
||||
|
||||
- Changing settings will make settings file editable if read-only by version control.
|
||||
- Documentation updates.
|
||||
|
||||
## [2.2.0] - 2023-04-06
|
||||
|
||||
### Changes & Improvements:
|
||||
- [Android] - Added support for notification channel groups.
|
||||
- [Android] - Added support for BigPicture style.
|
||||
- [Android] - Icons now support local files and URIs.
|
||||
- [Android] - Added API to check if UI with permission rationale for notifications should be shown before requesting permission.
|
||||
- [Android] - Added APIs to request exact scheduling and bypasssing battery optimizations.
|
||||
- [Android] - Minification seetings now managed automatically by package.
|
||||
- [Android] - AndroidNotificationCenter.UserPermissionToPost now will also report if notifications are blocked in Settings (Android 7+).
|
||||
- [iOS] - Added support for notification action icons (requires iOS 15).
|
||||
- [iOS] - Added property to set interruption level (requires iOS 15).
|
||||
- [iOS] - Added property to set relevance score (requires iOS 15).
|
||||
|
||||
### Fixes:
|
||||
- [Android] - Fix updating scheduled notification not updating if app is not killed.
|
||||
|
||||
## [2.1.1] - 2023-01-04
|
||||
|
||||
### Fixes:
|
||||
- [Android] - No longer use DeniedAndDontAskAgain permission response, only Denied.
|
||||
- [iOS] - [issue 205](https://github.com/Unity-Technologies/com.unity.mobile.notifications/issues/205) Fix occasional crash when registering for push notifications.
|
||||
- [iOS] - [issue 242](https://github.com/Unity-Technologies/com.unity.mobile.notifications/issues/242) Fix exception when OriginalUtc key is missing in data (for example notification was scheduled using older package version).
|
||||
|
||||
## [2.1.0] - 2022-09-23
|
||||
|
||||
### Changes & Improvements:
|
||||
- [Android] - Notification scheduling is made faster.
|
||||
- [Android] - Notifications can be set to not be shown when app is in foreground (contributed by InnoGames).
|
||||
- [Android] - Support for Android 13 notification permission.
|
||||
- [Android] - Support for exact scheduling on Android 12 and newer and ability to disable it.
|
||||
- [iOS] - Updated AuthorizationStatus enum with new values.
|
||||
- [iOS] - Location trigger now uses more accurate latitude/longitude and can repeat.
|
||||
- [iOS] [issue 202](https://github.com/Unity-Technologies/com.unity.mobile.notifications/issues/202) Added support for different sound types and notifications without sound.
|
||||
|
||||
### Fixes:
|
||||
- [Android] - Scheduled notifications are saved in more lightweight and reliable way.
|
||||
- [Android] [issue 196](https://github.com/Unity-Technologies/com.unity.mobile.notifications/issues/196) Fix occasional Resources$NotFound exception.
|
||||
- [Android] [issue 198](https://github.com/Unity-Technologies/com.unity.mobile.notifications/issues/198) Fix occasional OutOfMemoryError.
|
||||
- [iOS] - When using Calendar trigger time type (Local/UTC/...) will be preserved.
|
||||
|
||||
## [2.0.2] - 2022-05-13
|
||||
|
||||
### Changes & Improvements:
|
||||
- [Android] - AndroidNotificationCenter.CheckScheduledNotificationStatus now works on devices with all API levels
|
||||
|
||||
### Fixes:
|
||||
- [Android] [issue 186](https://github.com/Unity-Technologies/com.unity.mobile.notifications/issues/186) Mitigate OutOfMemory errors causing application crash
|
||||
- [Android] [issue 188](https://github.com/Unity-Technologies/com.unity.mobile.notifications/issues/188) Fix unguarded API usage from level 23
|
||||
|
||||
## [2.0.1] - 2022-04-15
|
||||
|
||||
### Fixes:
|
||||
- [Android] Change exported attribute to false in the manifest for package receivers.
|
||||
- [Android] [issue 144](https://github.com/Unity-Technologies/com.unity.mobile.notifications/issues/144) Fix Transaction.TooLargeException exception on some devices for notifications with large icons or more content.
|
||||
- [Android] [issue 160](https://github.com/Unity-Technologies/com.unity.mobile.notifications/issues/160) Fix UnityNotificationRestartOnBootReceiver not setting FLAG_IMMUTABLE.
|
||||
|
||||
### Changes & Improvements:
|
||||
- [Android] Build will now fail if minimum SDK in Unity is lower than supported by package.
|
||||
|
||||
## [2.0.0] - 2022-02-02
|
||||
|
||||
### Fixes:
|
||||
- [1360115](https://issuetracker.unity3d.com/issues/mobile-notifications-project-settings-window-loses-focus-when-clicking-on-any-category-while-mobile-notifications-pane-is-open) Fixed focus loss when trying to switching from notifications settings.
|
||||
- [1373835]() Fixed calendar notifications for buddhist calendars on iOS.
|
||||
- [1375744](https://issuetracker.unity3d.com/issues/ios-app-freezes-slash-crashes-when-both-mobile-notifications-and-firebase-are-used) Fixed application startup hang when application uses Unity notifications or Firebase.
|
||||
- [1382960](https://issuetracker.unity3d.com/issues/ios-crash-on-pthread-kill-when-clicking-on-a-notification-that-contains-an-integer-value-in-the-apns-file) Fixed a crash when push notification JSON file has integer item at the top level.
|
||||
|
||||
### Changes & Improvements:
|
||||
- [iOS] Added support for the following notification attachements: images, sounds, videos.
|
||||
- [Android] Introduced AndroidNotificationCenter.CreateNotificationBuilder, which allows the greater customizability while creating notifications.
|
||||
- [iOS] Added support for actionable notifications
|
||||
- [iOS] Added API for registering notification categories with associated actions.
|
||||
- [Android] Optimize notification saving.
|
||||
- [iOS][Android] Added API to open notification settings
|
||||
- [Android] Added API which allows you to change notification icons in Editor.
|
||||
- [iOS] Correctly handle boolean values in UserInfo, previously boolean values were detected as numbers and get parsed as 1 or 0, now they will be correctly handled as 'true' and 'false'
|
||||
- [Android] Fixed notification package for Android 12 - NotificationRestartOnBootReceiver needs to be marked as exported in manifest file, disable exact alarms because they require special permissions.
|
||||
- [iOS] Fix NotificationSettings.iOSSettings.DefaultAuthorizationOptions having incorrect return type (was PresentationOption, now AuthorizationOption).
|
||||
- [iOS] Mobile Notifications 2.0.0: iOSNotificationTrigger.Type is no longer static and returns iOSNotificationTriggerType instead of int.
|
||||
|
||||
## [1.4.2] - 2021-07-22
|
||||
|
||||
### Fixes:
|
||||
- [Android] [issue 99](https://github.com/Unity-Technologies/com.unity.mobile.notifications/issues/99) Use FLAG_IMMUTABLE for PendingIntent
|
||||
- [iOS] Do not touch Plist file unless modifications are required
|
||||
- [iOS] [1348518](https://issuetracker.unity3d.com/product/unity/issues/guid/1348518) Fix crash in push notification (case )
|
||||
|
||||
## [1.4.1] - 2021-05-06
|
||||
|
||||
### Fixes:
|
||||
- Disable warnings and remove leftover .meta file from samples.
|
||||
|
||||
## [1.4.0] - 2021-04-29
|
||||
|
||||
### Changes & Improvements:
|
||||
- [iOS] Less memory allocations when scheduling and retrieving notifications.
|
||||
- [iOS] Exposed notification UserInfo in API.
|
||||
- [Samples] Various small improvements to the test project.
|
||||
|
||||
### Fixes:
|
||||
- [Editor] Improved layout of elements in settings.
|
||||
- [Editor] iOS header files are no longer copied when building for other platforms.
|
||||
- [iOS] Multiple authorization requests can now be performed simultaneously.
|
||||
- [iOS] [[1315365](https://issuetracker.unity3d.com/product/unity/issues/guid/1315365)] Fix TimeInterval getter.
|
||||
- [iOS] Identifier for location based notifications is no longer hardcoded and now allows multiple triggers.
|
||||
|
||||
## [1.3.2] - 2020-11-10
|
||||
|
||||
### Changes & Improvements:
|
||||
- [Editor] [[1195293](https://issuetracker.unity3d.com/product/unity/issues/guid/1195293)] Improved content scaling in the Mobile Notifications settings UI.
|
||||
- [Samples] Added IGameNotification.Data propery, so that notification data could be read in cross-platform fashion.
|
||||
- [Samples] Added IGameNotification.GetLastNotification method to retrieve the last opened notification.
|
||||
- [Samples] Added retrieval of notification enabled status on Android.
|
||||
|
||||
### Fixes:
|
||||
- [Samples] [[1258554](https://issuetracker.unity3d.com/product/unity/issues/guid/1258554)] Fixed errors and warnings on startup in the demo scene.
|
||||
- [iOS] [[1259811](https://issuetracker.unity3d.com/product/unity/issues/guid/1259811)] Fixed UNITY_USES_REMOTE_NOTIFICATIONS being falsely set to 1 when Mobile Notifications isn't used.
|
||||
- [Android] [[1271866](https://issuetracker.unity3d.com/product/unity/issues/guid/1271866)] Fixed AndroidReceivedNotificationMainThreadDispatcher allocating a new list on every frame.
|
||||
- [Editor] [[1254618](https://issuetracker.unity3d.com/product/unity/issues/guid/1254618)] Fixed "SerializedObject target has been destroyed" errors when navigating Mobile Notifications settings.
|
||||
- [Android] [[1172850](https://issuetracker.unity3d.com/product/unity/issues/guid/1172850)] Fixed Android crashing when many notifications are scheduled at once.
|
||||
|
||||
## [1.3.0] - 2020-06-02
|
||||
|
||||
### Changes & Improvements:
|
||||
- [iOS] Improved the iOS plugin code: fixed the warnings and a potential dangling pointers issue, also made the code well structured and more readable.
|
||||
- [iOS] Improved the iOS post processor code: split the function into several small ones, also fixed the wrong required iOS version.
|
||||
- [Document] Improved the document: split the single page into multiple pages to have the document better organized, also added the missing document and updated the unclear document.
|
||||
|
||||
### Fixes:
|
||||
- [Android] Supressed the deprecated warnings from Android plugin as some deprecated functions have to be called for Android 7 and below.
|
||||
- [Android] Fixed the AndroidJavaException when calling AndroidNotificationCenter.UpdateScheduledNotification().
|
||||
- [Android] Fixed the issue where AndroidNotification.Color doesn't work as expected.
|
||||
- [iOS] [[1244642](https://issuetracker.unity3d.com/product/unity/issues/guid/1244642)] Fixed the bug that users can't set the foreground presentation options to "Nothing" in the Notification Settings.
|
||||
- [Editor] [[1199310](https://issuetracker.unity3d.com/product/unity/issues/guid/1199310)] Fixed the issue that Mobile Notification icons are gray when project was built from batch mode with -nographics flag.
|
||||
|
||||
## [1.2.1-preview] - 2020-04-30
|
||||
|
||||
### Fixes:
|
||||
- [Android] [[1231218](https://issuetracker.unity3d.com/product/unity/issues/guid/1231218)] Fixed the issue by removing the "com.android.support:appcompat-v7:27.1.1" dependency.
|
||||
|
||||
## [1.2.0-preview] - 2020-04-16
|
||||
|
||||
### Changes & Improvements:
|
||||
- [Editor] Improved the Notification Settings UI, also stored the notification setting asset under 'ProjectSettings' folder rather than 'Assets' folder.
|
||||
|
||||
### Fixes:
|
||||
- Fixed a lot of notification settings UI related bugs.
|
||||
- [iOS] Fixed the issue that the authorization request callback hasn't been removed.
|
||||
- [Android] Fixed the wrong value of LockscreenVisiblity.Private.
|
||||
|
||||
## [1.1.0-preview] - 2020-03-24
|
||||
|
||||
### Changes & Improvements:
|
||||
- [Android] Exposed the java source code in the package rather than building into an .aar. Users can now debug the java code in Android Studio by exporting to a gradle project.
|
||||
- Refactored the managed plugin code to have them better structured.
|
||||
|
||||
### Fixes:
|
||||
- Fixed a potential deadlock issue in AndroidReceivedNotificationMainThreadDispatcher while handling the notification received callback.
|
||||
- [iOS] [[1221133](https://issuetracker.unity3d.com/product/unity/issues/guid/1221133)] Fixed the issue that user generated entitlements file will be rewritten by the one generated by mobile notifications.
|
||||
- [iOS] Fixed the crash on iOS if the time interval on iOSNotificationTimeIntervalTrigger is set to 0.
|
||||
- [iOS] Fixed the crash on iOS if iOSNotificationData.data is set to null.
|
||||
|
||||
## [1.0.4-preview.9] - 2020-02-10
|
||||
|
||||
### Fixes:
|
||||
|
||||
- [Android] Write all `SharedPreferences` to disk asynchronously.
|
||||
|
||||
## [1.0.4-preview.6] - 2020-01-27
|
||||
|
||||
### Fixes:
|
||||
- [Android] Duplicate notifications will no longer be scheduled after the device is restarted (when "Reschedule Notification on Device Restart" is turned on).
|
||||
- [Android] Unity's Notification package will no longer attempt to load AlarmManager intents which were not scheduledby it.
|
||||
- [Editor] It's now possible to use `Unity.Notifications' editor classes without having to create manually referenc it in your asmdef file.
|
||||
|
||||
## [1.0.4-preview.5] - 2019-11-13
|
||||
|
||||
### Fixes:
|
||||
|
||||
- [iOS/tvOS] The iOS source plugins provided by the package will no longer be included when building for Apple TV.
|
||||
|
||||
## [1.0.4-preview.4] - 2019-10-29
|
||||
|
||||
### Fixes:
|
||||
|
||||
- [Android] Icon resources will now be queried when the notification is supposed to be triggered instead of when it's scheduled. This should fix crashes due to missing resources in cases where the app is updated after a notification is scheduled but before it's delivered.
|
||||
|
||||
### Changes & Improvements:
|
||||
|
||||
- [Android] Added 'AndroidNotification.ShowTimestamp' to allow displaying timestamp on delivered notifications. The specific time stamp value can be overriden using 'AndroidNotification.CustomTimestamp' if it's not set the time at which the notification was delivered will be shown.
|
||||
|
||||
## [1.0.4-preview.3] - 2019-10-09
|
||||
|
||||
### Fixes:
|
||||
|
||||
- [iOS] Remote notification `deviceToken` is now be returned correctly (and without angle brackets)on iOS 13.
|
||||
|
||||
## [1.0.4-preview.2] - 2019-09-16
|
||||
|
||||
### Fixes:
|
||||
|
||||
- Embedded the [Notification Samples project](https://github.com/Unity-Technologies/NotificationsSamples) into the package, I can now be imported from the Package Manager UI.
|
||||
- [Android] It should now be possible to set `AndroidNotificationChannel.VibrationPattern` to null.
|
||||
|
||||
## [1.0.4-preview.1] - 2019-09-09
|
||||
|
||||
### Fixes:
|
||||
|
||||
- [Android] Trying to register an ``AndroidNotificationChannel` with a specified `VibrationPattern` should no longer trigger a missing method exception.
|
||||
- [Android][[1178665](https://issuetracker.unity3d.com/product/unity/issues/guid/1178665/)] Repeatable notifications should now work properly and should be recreated when the device is restarted. 1.0.4-preview.alpha.1
|
||||
|
||||
## [1.0.3] - 2019-08-21
|
||||
|
||||
### Fixes:
|
||||
|
||||
- [iOS] It's no longer necessary to enable the `Request Authorization on App Start` setting in UI to be able to turn on `Enable Push Notifications`.
|
||||
- [iOS] `GetLastRespondedNotification` should now properly return the notification used to open the app even if "Request Authorization on App Start" is turned off.
|
||||
- [iOS] `iOSNotification.data` field should now work properly with all valid JSON structures and not only with dictionaries and strings.
|
||||
- [Android] Added a temporary fix for an IL2CPP compilation issue on Unity 2019.2 and above.
|
||||
- Fixed an issue with NUnit Test assemblies not being detected correctly due to which exceptions were thrown in the editor.
|
||||
- [Android][1165178](https://issuetracker.unity3d.com/product/unity/issues/guid/1165178/): An Android JAVA exception should no longer be thrown when attempting to schedule more than 500 notifications on Samsung devices. Samsung seems to impose a fixed limit of concurrent Alarms so if the limit is reached all attempts to schedule new notifications will be ignored until the currently scheduled ones are triggered or manually cancelled.
|
||||
- [[1114987](https://issuetracker.unity3d.com/product/unity/issues/guid/1114987/)] Reopening the project should no longer override Mobile Notification Settings.
|
||||
- [iOS] Fixed an issue with `iOSNotification.data` not being set correctly for remote notifications if the data field is not a string. It will now return a full JSON string for the data field.
|
||||
- [Android] Notifications cancelled using `CancelScheduledNotification` or `CancelAllScheduledNotifications` should no longer be recreated on device restart if the device is restarted before the time they were supposed to be triggered.
|
||||
|
||||
### Changes & Improvements:
|
||||
|
||||
- [Android] `OnNotificationReceived`is now executed on the main Unity thread so it should now be possible to directly call Unity API methods the only work on the main thread from delegates and functions that subscribe to the this method.
|
||||
|
||||
- [iOS] Turning on `Enable Push Notifications` will add the `remote-notification ` setting to `UIBackgroundModes` array in the app’s `info.plist` file.
|
||||
|
||||
- [iOS] The notification returned by `iOSNotificationCenter.GetLastRespondedNotification()` is now cleared each time the app is moved to the background and not only when the app is fully terminated. Now it should only return the notification used to open the app or the last notification activated by the user while the app was running in the foreground.
|
||||
|
||||
- [Android] Added an option to override the Android app activity which should be opened when a notification is clicked. By default the main activity assigned to the `UnityPlayer` Java class will be used.
|
||||
|
||||
- Exposed notification settings (previously only accessible in UI) in a public Editor API (see the `Unity.Notifications.UnityNotificationSettings`) class.
|
||||
|
||||
- [Android] Increased the minimum requirements to Android 4.4 (API 19)
|
||||
|
||||
|
||||
## [1.0.2] - 2019-07-01
|
||||
|
||||
### Fixes:
|
||||
|
||||
- [iOS] Querying notification settings on iOS 10 will no longer cause a crash.
|
||||
|
||||
- [Android] Changing notification icon color now works.
|
||||
|
||||
- Minor UI improvements.
|
||||
|
||||
- Documentation improvements.
|
||||
|
||||
|
||||
## [1.0.0] - 2019-05-20
|
||||
|
||||
Includes all changes from previous preview releases.
|
||||
|
||||
### Fixes:
|
||||
|
||||
- [Android] Notification API Java classes are no longer stripped when building with Proguard enabled.
|
||||
|
||||
- [Editor] Editor settings window should not automatically detect changes to Android icon source texture assets.
|
||||
|
||||
- [Editor] The settings window should work properly and no longer throw exceptions when opening a project used with a previous version of the package.
|
||||
|
||||
- [iOS] `AuthorizationRequest` should properly finish even when the user denies the request.
|
||||
|
||||
- [Android] Canceling scheduled notifications now works correctly when the app is restarted.
|
||||
|
||||
- [iOS] Subscribing to OnNotificationReceived on iOS should now work, even if no other notification was called
|
||||
|
||||
- Notification settings should no longer dissappear if Unity is closed while settings editor screen is not opened.
|
||||
|
||||
- Compatibility fixes for Unity 2019.2.
|
||||
|
||||
- Fixed warning messages that were being thrown after importing the package on 2018.2.
|
||||
|
||||
- Compatibility fix for Unity 2019.3.
|
||||
|
||||
- Fixed issues with editor scripts and .asmdef files on Unity 2018.2.
|
||||
|
||||
- Made CancelDisplayedNotification public.
|
||||
|
||||
- Fixed an editor script issue on 2018.3.
|
||||
|
||||
|
||||
### Improvements & changes:
|
||||
|
||||
- [Android] Added support for notification groups:
|
||||
|
||||
- Set `Group` property to group multiple notifications in a single thread.
|
||||
- Enable `GroupSummary`on a notification to use it as the summary notification for it's group.
|
||||
- `GroupAlertBehaviour` can be used to override the alert behaviour for all notifications in a group.
|
||||
|
||||
- [Android] Added a `SortKey` property for Android.
|
||||
|
||||
- Used to lexicographically order this notification among other notifications from the same package or the same notification group.
|
||||
|
||||
- [Android] Changed ‘GetLastIntentData’ to ‘GetLastNotificationIntent’, it nows returns a `AndroidNotificationIntentData` object (which encapsulates the received `AndroidNotification` and it's `Channel` and `Id` fields) instead of just a string:
|
||||
|
||||
- `OnNotificationReceived` now returns `AndroidNotificationIntentData`.
|
||||
- Arbitrary data can be stored in the `AndroidNotification.intentData` field.
|
||||
|
||||
- [iOS] Added `GetLastNotification()` to `iOSNotificationCenter` :
|
||||
|
||||
- Can be used to retrieve the notification which was used to open the app.
|
||||
- If any new notifications are received while the app is active they will override the original one.
|
||||
|
||||
- [iOS] Exposed additional `iOSNotificationSettings` properties:
|
||||
|
||||
- ShowPreviewsSetting`indicates whether the app can a preview of the notification's contenton the lock screen.
|
||||
- `AlertStyle` indicates the type of alerts the user has authorized (`Banner`, `Alert` or `None`).
|
||||
|
||||
- [Android] Added an option to reshedule all non expired notification on device restart.
|
||||
|
||||
- [Android] Added a `data` field to notification object and a method to retrieve the `data` assigned to a notification that was used to open the app or bring it back from background.
|
||||
|
||||
- Changed the minimum Unity version supported by the package to 2018.3.
|
||||
|
||||
- Added an option to not add Remote Notifications capability to the Xcode project.
|
||||
|
||||
- Allow sending notifications without title or body. Allows scheduling sounds only notifications that do not have an alert or are shown in the notification center.
|
||||
|
||||
##
|
||||
Vendored
Executable
+7
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e4a07c2fb289d4ae98469d16e3afd781
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Vendored
Regular → Executable
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4a938c3e9196244689e2919e3bcd0c10
|
||||
guid: 5c31c05b473c946669349ca2b826e4f0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
Vendored
Executable
+35
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
namespace Unity.Notifications
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether to schedule notifications at exact time or approximately (saves power).
|
||||
/// Exact scheduling is available in Android 6 (API 23) and newer, lower versions always use inexact scheduling.
|
||||
/// Android 12 (API 31) or newer requires SCHEDULE_EXACT_ALARM permission and grant from user to use exact scheduling.
|
||||
/// Android 13 (API 33) or newer can use USE_EXACT_ALARM permission to use exactscheduling without requesting users grant.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum AndroidExactSchedulingOption
|
||||
{
|
||||
/// <summary>
|
||||
/// Use exact scheduling when possible.
|
||||
/// </summary>
|
||||
ExactWhenAvailable = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Add SCHEDULE_EXACT_ALARM permission to the manifest.
|
||||
/// </summary>
|
||||
AddScheduleExactPermission = 1 << 1,
|
||||
|
||||
/// <summary>
|
||||
/// Add USE_EXACT_ALARM permission to the manifest.
|
||||
/// </summary>
|
||||
AddUseExactAlarmPermission = 1 << 2,
|
||||
|
||||
/// <summary>
|
||||
/// Add REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission to the manifest.
|
||||
/// Required if you want to use <see cref="AndroidNotificationCenter.RequestIgnoreBatteryOptimizations()"/>.
|
||||
/// </summary>
|
||||
AddRequestIgnoreBatteryOptimizationsPermission = 1 << 3,
|
||||
}
|
||||
}
|
||||
Vendored
Executable
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5ef4f75b5ba00a4793f867958e727b2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Vendored
Executable
+184
@@ -0,0 +1,184 @@
|
||||
#if UNITY_ANDROID
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Android;
|
||||
|
||||
namespace Unity.Notifications
|
||||
{
|
||||
public class AndroidNotificationPostProcessor : IPostGenerateGradleAndroidProject
|
||||
{
|
||||
const string kAndroidNamespaceURI = "http://schemas.android.com/apk/res/android";
|
||||
|
||||
public int callbackOrder { get { return 0; } }
|
||||
|
||||
public void OnPostGenerateGradleAndroidProject(string projectPath)
|
||||
{
|
||||
projectPath = Path.Combine(projectPath, "mobilenotifications.androidlib");
|
||||
if (!Directory.Exists(projectPath))
|
||||
throw new Exception("mobilenotifications module not found in gradle project");
|
||||
|
||||
CopyNotificationResources(projectPath);
|
||||
|
||||
InjectAndroidManifest(projectPath);
|
||||
}
|
||||
|
||||
private void CopyNotificationResources(string projectPath)
|
||||
{
|
||||
// Get the icons set in the UnityNotificationEditorManager and write them to the res folder, then we can use the icons as res.
|
||||
var icons = NotificationSettingsManager.Initialize().GenerateDrawableResourcesForExport();
|
||||
foreach (var icon in icons)
|
||||
{
|
||||
var fileInfo = new FileInfo(string.Format("{0}/src/main/res/{1}", projectPath, icon.Key));
|
||||
if (fileInfo.Directory != null)
|
||||
{
|
||||
fileInfo.Directory.Create();
|
||||
File.WriteAllBytes(fileInfo.FullName, icon.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal struct ManifestSettings
|
||||
{
|
||||
public bool UseCustomActivity;
|
||||
public string CustomActivity;
|
||||
public bool RescheduleOnRestart;
|
||||
public AndroidExactSchedulingOption ExactAlarm;
|
||||
}
|
||||
|
||||
private void InjectAndroidManifest(string projectPath)
|
||||
{
|
||||
var manifestPath = string.Format("{0}/src/main/AndroidManifest.xml", projectPath);
|
||||
if (!File.Exists(manifestPath))
|
||||
throw new FileNotFoundException(string.Format("'{0}' doesn't exist.", manifestPath));
|
||||
|
||||
XmlDocument manifestDoc = new XmlDocument();
|
||||
manifestDoc.Load(manifestPath);
|
||||
|
||||
var settings = NotificationSettingsManager.Initialize().AndroidNotificationSettingsFlat;
|
||||
var manifestSettings = new ManifestSettings()
|
||||
{
|
||||
UseCustomActivity = GetSetting<bool>(settings, NotificationSettings.AndroidSettings.USE_CUSTOM_ACTIVITY),
|
||||
CustomActivity = GetSetting<string>(settings, NotificationSettings.AndroidSettings.CUSTOM_ACTIVITY_CLASS),
|
||||
RescheduleOnRestart = GetSetting<bool>(settings, NotificationSettings.AndroidSettings.RESCHEDULE_ON_RESTART),
|
||||
ExactAlarm = GetSetting<AndroidExactSchedulingOption>(settings, NotificationSettings.AndroidSettings.EXACT_ALARM),
|
||||
};
|
||||
|
||||
InjectAndroidManifest(manifestPath, manifestDoc, manifestSettings);
|
||||
|
||||
manifestDoc.Save(manifestPath);
|
||||
}
|
||||
|
||||
internal static void InjectAndroidManifest(string manifestPath, XmlDocument manifestDoc, ManifestSettings settings)
|
||||
{
|
||||
if (settings.UseCustomActivity)
|
||||
AppendAndroidMetadataField(manifestPath, manifestDoc, "custom_notification_android_activity", settings.CustomActivity);
|
||||
|
||||
if (settings.RescheduleOnRestart)
|
||||
{
|
||||
AppendAndroidMetadataField(manifestPath, manifestDoc, "reschedule_notifications_on_restart", "true");
|
||||
AppendAndroidPermissionField(manifestPath, manifestDoc, "android.permission.RECEIVE_BOOT_COMPLETED");
|
||||
}
|
||||
|
||||
bool enableExact = (settings.ExactAlarm & AndroidExactSchedulingOption.ExactWhenAvailable) != 0;
|
||||
AppendAndroidMetadataField(manifestPath, manifestDoc, "com.unity.androidnotifications.exact_scheduling", enableExact ? "1" : "0");
|
||||
if (enableExact)
|
||||
{
|
||||
bool scheduleExact = (settings.ExactAlarm & AndroidExactSchedulingOption.AddScheduleExactPermission) != 0;
|
||||
bool useExact = (settings.ExactAlarm & AndroidExactSchedulingOption.AddUseExactAlarmPermission) != 0;
|
||||
// as documented here: https://developer.android.com/reference/android/Manifest.permission#USE_EXACT_ALARM
|
||||
// only one of these two attributes should be used or max sdk set so on any device it's one or the other
|
||||
if (scheduleExact)
|
||||
AppendAndroidPermissionField(manifestPath, manifestDoc, "android.permission.SCHEDULE_EXACT_ALARM", useExact ? "32" : null);
|
||||
if (useExact)
|
||||
AppendAndroidPermissionField(manifestPath, manifestDoc, "android.permission.USE_EXACT_ALARM");
|
||||
|
||||
// Battery optimizations must use "uses-permission-sdk-23", regular uses-permission does not work
|
||||
if ((settings.ExactAlarm & AndroidExactSchedulingOption.AddRequestIgnoreBatteryOptimizationsPermission) != 0)
|
||||
AppendAndroidPermissionField(manifestPath, manifestDoc, "uses-permission-sdk-23", "android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS", null);
|
||||
}
|
||||
}
|
||||
|
||||
private static T GetSetting<T>(List<NotificationSetting> settings, string key)
|
||||
{
|
||||
return (T)settings.Find(i => i.Key == key).Value;
|
||||
}
|
||||
|
||||
internal static void AppendAndroidPermissionField(string manifestPath, XmlDocument xmlDoc, string name, string maxSdk = null)
|
||||
{
|
||||
AppendAndroidPermissionField(manifestPath, xmlDoc, "uses-permission", name, maxSdk);
|
||||
}
|
||||
|
||||
internal static void AppendAndroidPermissionField(string manifestPath, XmlDocument xmlDoc, string tagName, string name, string maxSdk)
|
||||
{
|
||||
var manifestNode = xmlDoc.SelectSingleNode("manifest");
|
||||
if (manifestNode == null)
|
||||
throw new ArgumentException(string.Format("Missing 'manifest' node in '{0}'.", manifestPath));
|
||||
|
||||
XmlElement metaDataNode = null;
|
||||
foreach (XmlNode node in manifestNode.ChildNodes)
|
||||
{
|
||||
if (!(node is XmlElement) || node.Name != tagName)
|
||||
continue;
|
||||
|
||||
var element = (XmlElement)node;
|
||||
var elementName = element.GetAttribute("name", kAndroidNamespaceURI);
|
||||
if (elementName == name)
|
||||
{
|
||||
if (maxSdk == null)
|
||||
return;
|
||||
var maxSdkAttr = element.GetAttribute("maxSdkVersion", kAndroidNamespaceURI);
|
||||
if (!string.IsNullOrEmpty(maxSdkAttr))
|
||||
return;
|
||||
metaDataNode = element;
|
||||
}
|
||||
}
|
||||
|
||||
if (metaDataNode == null)
|
||||
{
|
||||
metaDataNode = xmlDoc.CreateElement(tagName);
|
||||
metaDataNode.SetAttribute("name", kAndroidNamespaceURI, name);
|
||||
}
|
||||
if (maxSdk != null)
|
||||
metaDataNode.SetAttribute("maxSdkVersion", kAndroidNamespaceURI, maxSdk);
|
||||
|
||||
manifestNode.AppendChild(metaDataNode);
|
||||
}
|
||||
|
||||
internal static void AppendAndroidMetadataField(string manifestPath, XmlDocument xmlDoc, string name, string value)
|
||||
{
|
||||
var applicationNode = xmlDoc.SelectSingleNode("manifest/application");
|
||||
if (applicationNode == null)
|
||||
throw new ArgumentException(string.Format("Missing 'application' node in '{0}'.", manifestPath));
|
||||
|
||||
var nodes = xmlDoc.SelectNodes("manifest/application/meta-data");
|
||||
if (nodes != null)
|
||||
{
|
||||
// Check if there is a 'meta-data' with the same name.
|
||||
foreach (XmlNode node in nodes)
|
||||
{
|
||||
var element = node as XmlElement;
|
||||
if (element == null)
|
||||
continue;
|
||||
|
||||
var elementName = element.GetAttribute("name", kAndroidNamespaceURI);
|
||||
if (elementName == name)
|
||||
{
|
||||
element.SetAttribute("value", kAndroidNamespaceURI, value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XmlElement metaDataNode = xmlDoc.CreateElement("meta-data");
|
||||
metaDataNode.SetAttribute("name", kAndroidNamespaceURI, name);
|
||||
metaDataNode.SetAttribute("value", kAndroidNamespaceURI, value);
|
||||
|
||||
applicationNode.AppendChild(metaDataNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Vendored
Executable
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3ab62d805bcb24c96b7ef39a230d410e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Vendored
Executable
+3
@@ -0,0 +1,3 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Unity.Notifications.Tests")]
|
||||
Vendored
Executable
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3703be1dcf9d604a85439fd2feb1e0d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Vendored
Executable
+81
@@ -0,0 +1,81 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.Notifications
|
||||
{
|
||||
[System.Serializable]
|
||||
internal class DrawableResourceData
|
||||
{
|
||||
public string Id;
|
||||
public NotificationIconType Type;
|
||||
public Texture2D Asset;
|
||||
|
||||
private bool m_IsValid = false;
|
||||
private List<string> m_Errors = null;
|
||||
private Texture2D m_PreviewTexture;
|
||||
|
||||
public bool IsValid
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_IsValid == false && m_Errors == null)
|
||||
Verify();
|
||||
|
||||
return m_IsValid;
|
||||
}
|
||||
}
|
||||
|
||||
public string[] Errors
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_IsValid == false && m_Errors == null)
|
||||
Verify();
|
||||
|
||||
return m_Errors.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public Texture2D GetPreviewTexture(bool update)
|
||||
{
|
||||
if (Asset == null)
|
||||
return null;
|
||||
|
||||
if (m_IsValid && (m_PreviewTexture == null || update))
|
||||
m_PreviewTexture = TextureAssetUtils.ProcessTextureForType(Asset, Type);
|
||||
|
||||
return m_PreviewTexture;
|
||||
}
|
||||
|
||||
internal bool Initialized()
|
||||
{
|
||||
return !string.IsNullOrEmpty(Id) && Asset != null;
|
||||
}
|
||||
|
||||
public void Clean()
|
||||
{
|
||||
m_IsValid = false;
|
||||
m_Errors = null;
|
||||
m_PreviewTexture = null;
|
||||
}
|
||||
|
||||
public bool Verify()
|
||||
{
|
||||
m_IsValid = TextureAssetUtils.VerifyTextureByType(Asset, Type, out m_Errors);
|
||||
return m_IsValid;
|
||||
}
|
||||
|
||||
public string GenerateErrorString()
|
||||
{
|
||||
var errors = Errors;
|
||||
|
||||
var errorString = string.Empty;
|
||||
for (var i = 0; i < errors.Length; i++)
|
||||
{
|
||||
errorString += string.Format("{0}{1}", errors[i], i + 1 >= errors.Length ? "." : ", ");
|
||||
}
|
||||
|
||||
return errorString;
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
Executable
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c7bb3ae4e071b4f599d584ac995b185f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Vendored
Executable
+18
@@ -0,0 +1,18 @@
|
||||
namespace Unity.Notifications
|
||||
{
|
||||
/// <summary>
|
||||
/// Notification icon type.
|
||||
/// </summary>
|
||||
public enum NotificationIconType
|
||||
{
|
||||
/// <summary>
|
||||
/// Denotes small icon.
|
||||
/// </summary>
|
||||
Small = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Denotes large icon
|
||||
/// </summary>
|
||||
Large = 1,
|
||||
}
|
||||
}
|
||||
Vendored
Executable
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4598419a0a7a742fea832062d225b4b5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Assets/RgfCDfHLhn9WSDK/ThirdParty/com.unity.mobile.notifications@2.3.2/Editor/NotificationSetting.cs
Vendored
Executable
+26
@@ -0,0 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.Notifications
|
||||
{
|
||||
internal class NotificationSetting
|
||||
{
|
||||
public string Key;
|
||||
public string Label;
|
||||
public string Tooltip;
|
||||
public object Value;
|
||||
public bool WriteToPlist;
|
||||
|
||||
public List<NotificationSetting> Dependencies;
|
||||
|
||||
public NotificationSetting(string key, string label, string tooltip, object value, bool writeToPlist = true,
|
||||
List<NotificationSetting> dependencies = null)
|
||||
{
|
||||
this.Key = key;
|
||||
this.Label = label;
|
||||
this.Tooltip = tooltip;
|
||||
this.Value = value;
|
||||
this.WriteToPlist = writeToPlist;
|
||||
this.Dependencies = dependencies;
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
Executable
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb2bc06c3d6c8474cb3af9bf67470a71
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Vendored
Executable
+300
@@ -0,0 +1,300 @@
|
||||
using Unity.Notifications.iOS;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.Notifications
|
||||
{
|
||||
/// <summary>
|
||||
/// Class used to access notification settings for a specific platform.
|
||||
/// </summary>
|
||||
public class NotificationSettings
|
||||
{
|
||||
private static NotificationSetting GetSetting(BuildTargetGroup target, string key)
|
||||
{
|
||||
var manager = NotificationSettingsManager.Initialize();
|
||||
|
||||
NotificationSetting setting = null;
|
||||
if (target == BuildTargetGroup.Android)
|
||||
{
|
||||
setting = manager.AndroidNotificationSettingsFlat.Find(i => i.Key == key);
|
||||
}
|
||||
else if (target == BuildTargetGroup.iOS)
|
||||
{
|
||||
setting = manager.iOSNotificationSettingsFlat.Find(i => i.Key == key);
|
||||
}
|
||||
|
||||
return setting;
|
||||
}
|
||||
|
||||
private static void SetSettingValue<T>(BuildTargetGroup target, string key, T value)
|
||||
{
|
||||
var manager = NotificationSettingsManager.Initialize();
|
||||
|
||||
NotificationSetting setting = GetSetting(target, key);
|
||||
if (setting != null)
|
||||
{
|
||||
setting.Value = value;
|
||||
manager.SaveSetting(setting, target);
|
||||
}
|
||||
}
|
||||
|
||||
private static T GetSettingValue<T>(BuildTargetGroup target, string key)
|
||||
{
|
||||
var setting = GetSetting(target, key);
|
||||
return (T)setting.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class used to access Android-specific notification settings.
|
||||
/// </summary>
|
||||
public static class AndroidSettings
|
||||
{
|
||||
internal static readonly string RESCHEDULE_ON_RESTART = "UnityNotificationAndroidRescheduleOnDeviceRestart";
|
||||
internal static readonly string EXACT_ALARM = "UnityNotificationAndroidScheduleExactAlarms";
|
||||
internal static readonly string USE_CUSTOM_ACTIVITY = "UnityNotificationAndroidUseCustomActivity";
|
||||
internal static readonly string CUSTOM_ACTIVITY_CLASS = "UnityNotificationAndroidCustomActivityString";
|
||||
|
||||
/// <summary>
|
||||
/// By default AndroidSettings removes all scheduled notifications when the device is restarted. Enable this to automatically reschedule all non expired notifications when the device is turned back on.
|
||||
/// </summary>
|
||||
public static bool RescheduleOnDeviceRestart
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetSettingValue<bool>(BuildTargetGroup.Android, RESCHEDULE_ON_RESTART);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetSettingValue<bool>(BuildTargetGroup.Android, RESCHEDULE_ON_RESTART, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enable this if you want to override the activity which will opened when the user click on the notification. By default activity assigned to `com.unity3d.player.UnityPlayer.currentActivity` will be used.
|
||||
/// </summary>
|
||||
public static bool UseCustomActivity
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetSettingValue<bool>(BuildTargetGroup.Android, USE_CUSTOM_ACTIVITY);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetSettingValue<bool>(BuildTargetGroup.Android, USE_CUSTOM_ACTIVITY, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The full class name of the activity that you wish to be assigned to the notification.
|
||||
/// </summary>
|
||||
public static string CustomActivityString
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetSettingValue<string>(BuildTargetGroup.Android, CUSTOM_ACTIVITY_CLASS);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetSettingValue<string>(BuildTargetGroup.Android, CUSTOM_ACTIVITY_CLASS, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A set of flags indicating whether to use exact scheduling and add supporting permissions.
|
||||
/// </summary>
|
||||
public static AndroidExactSchedulingOption ExactSchedulingOption
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetSettingValue<AndroidExactSchedulingOption>(BuildTargetGroup.Android, EXACT_ALARM);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetSettingValue<AndroidExactSchedulingOption>(BuildTargetGroup.Android, EXACT_ALARM, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add image to notification settings.
|
||||
/// </summary>
|
||||
/// <param name="id">Image identifier</param>
|
||||
/// <param name="image">Image texture, must be obtained from asset database</param>
|
||||
/// <param name="type">Image type</param>
|
||||
public static void AddDrawableResource(string id, Texture2D image, NotificationIconType type)
|
||||
{
|
||||
var manager = NotificationSettingsManager.Initialize();
|
||||
manager.AddDrawableResource(id, image, type);
|
||||
SettingsService.RepaintAllSettingsWindow();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove icon at given index from notification settings.
|
||||
/// </summary>
|
||||
/// <param name="index">Index of image to remove</param>
|
||||
public static void RemoveDrawableResource(int index)
|
||||
{
|
||||
var manager = NotificationSettingsManager.Initialize();
|
||||
manager.RemoveDrawableResourceByIndex(index);
|
||||
SettingsService.RepaintAllSettingsWindow();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove icon with given identifier from notification settings.
|
||||
/// </summary>
|
||||
/// <param name="id">ID of the image to remove</param>
|
||||
public static void RemoveDrawableResource(string id)
|
||||
{
|
||||
var manager = NotificationSettingsManager.Initialize();
|
||||
manager.RemoveDrawableResourceById(id);
|
||||
SettingsService.RepaintAllSettingsWindow();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove all images from notification settings.
|
||||
/// </summary>
|
||||
public static void ClearDrawableResources()
|
||||
{
|
||||
var manager = NotificationSettingsManager.Initialize();
|
||||
manager.ClearDrawableResources();
|
||||
SettingsService.RepaintAllSettingsWindow();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class used to access iOS-specific notification settings.
|
||||
/// </summary>
|
||||
public static class iOSSettings
|
||||
{
|
||||
internal static readonly string REQUEST_AUTH_ON_LAUNCH = "UnityNotificationRequestAuthorizationOnAppLaunch";
|
||||
internal static readonly string DEFAULT_AUTH_OPTS = "UnityNotificationDefaultAuthorizationOptions";
|
||||
internal static readonly string ADD_PUSH_CAPABILITY = "UnityAddRemoteNotificationCapability";
|
||||
internal static readonly string REQUEST_PUSH_AUTH_ON_LAUNCH = "UnityNotificationRequestAuthorizationForRemoteNotificationsOnAppLaunch";
|
||||
internal static readonly string PUSH_NOTIFICATION_PRESENTATION = "UnityRemoteNotificationForegroundPresentationOptions";
|
||||
internal static readonly string USE_APS_RELEASE = "UnityUseAPSReleaseEnvironment";
|
||||
internal static readonly string USE_LOCATION_TRIGGER = "UnityUseLocationNotificationTrigger";
|
||||
internal static readonly string ADD_TIME_SENSITIVE_ENTITLEMENT = "UnityAddTimeSensitiveEntitlement";
|
||||
|
||||
/// <summary>
|
||||
/// It's recommended to make the authorization request during the app's launch cycle. If this is enabled the user will be shown the authorization pop-up immediately when the app launches. If it’s unchecked you’ll need to manually create an AuthorizationRequest before your app can send or receive notifications.
|
||||
/// </summary>
|
||||
public static bool RequestAuthorizationOnAppLaunch
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetSettingValue<bool>(BuildTargetGroup.iOS, REQUEST_AUTH_ON_LAUNCH);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetSettingValue<bool>(BuildTargetGroup.iOS, REQUEST_AUTH_ON_LAUNCH, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configure the notification interaction types your app will include in the authorisation request if RequestAuthorizationOnAppLaunch is enabled. Alternatively you can specify them when creating a `AuthorizationRequest` from a script.
|
||||
/// </summary>
|
||||
public static AuthorizationOption DefaultAuthorizationOptions
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetSettingValue<AuthorizationOption>(BuildTargetGroup.iOS, DEFAULT_AUTH_OPTS);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetSettingValue<AuthorizationOption>(BuildTargetGroup.iOS, DEFAULT_AUTH_OPTS, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enable this to add the push notification capability to you Xcode project.
|
||||
/// </summary>
|
||||
public static bool AddRemoteNotificationCapability
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetSettingValue<bool>(BuildTargetGroup.iOS, ADD_PUSH_CAPABILITY);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetSettingValue<bool>(BuildTargetGroup.iOS, ADD_PUSH_CAPABILITY, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this is enabled the app will automatically register your app with APNs after the launch which would enable it to receive remote notifications. You’ll have to manually create a AuthorizationRequest to get the device token.
|
||||
/// </summary>
|
||||
public static bool NotificationRequestAuthorizationForRemoteNotificationsOnAppLaunch
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetSettingValue<bool>(BuildTargetGroup.iOS, REQUEST_PUSH_AUTH_ON_LAUNCH);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetSettingValue<bool>(BuildTargetGroup.iOS, REQUEST_PUSH_AUTH_ON_LAUNCH, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The default presentation options for received remote notifications. In order for the specified presentation options to be used your app must had received the authorization to use them (the user might change it at any time).
|
||||
/// </summary>
|
||||
public static PresentationOption RemoteNotificationForegroundPresentationOptions
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetSettingValue<PresentationOption>(BuildTargetGroup.iOS, PUSH_NOTIFICATION_PRESENTATION);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetSettingValue<PresentationOption>(BuildTargetGroup.iOS, PUSH_NOTIFICATION_PRESENTATION, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enable this when signing the app with a production certificate.
|
||||
/// </summary>
|
||||
public static bool UseAPSReleaseEnvironment
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetSettingValue<bool>(BuildTargetGroup.iOS, USE_APS_RELEASE);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetSettingValue<bool>(BuildTargetGroup.iOS, USE_APS_RELEASE, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If you intend to use the iOSNotificationLocationTrigger in your notifications you must include the CoreLocation framework in your project.
|
||||
/// </summary>
|
||||
public static bool UseLocationNotificationTrigger
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetSettingValue<bool>(BuildTargetGroup.iOS, USE_LOCATION_TRIGGER);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetSettingValue<bool>(BuildTargetGroup.iOS, USE_LOCATION_TRIGGER, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add entitlement to enable notifications with time-sensitive interruption level.
|
||||
/// </summary>
|
||||
public static bool AddTimeSensitiveEntitlement
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetSettingValue<bool>(BuildTargetGroup.iOS, ADD_TIME_SENSITIVE_ENTITLEMENT);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetSettingValue<bool>(BuildTargetGroup.iOS, ADD_TIME_SENSITIVE_ENTITLEMENT, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
Executable
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: af42dd3f8d8d54934ab3f4bdc740f0f1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Vendored
Executable
+78
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Unity.Notifications
|
||||
{
|
||||
[Serializable]
|
||||
internal class NotificationSettingsCollection
|
||||
{
|
||||
[SerializeField]
|
||||
[FormerlySerializedAs("keys")]
|
||||
List<string> m_Keys;
|
||||
|
||||
[SerializeField]
|
||||
[FormerlySerializedAs("values")]
|
||||
List<string> m_Values;
|
||||
|
||||
public NotificationSettingsCollection()
|
||||
{
|
||||
m_Keys = new List<string>();
|
||||
m_Values = new List<string>();
|
||||
}
|
||||
|
||||
public bool Contains(string key)
|
||||
{
|
||||
return m_Keys.Contains(key);
|
||||
}
|
||||
|
||||
public object this[string key]
|
||||
{
|
||||
get
|
||||
{
|
||||
var index = m_Keys.IndexOf(key);
|
||||
if (index == -1 || m_Values.Count <= index)
|
||||
return null;
|
||||
|
||||
int intValue;
|
||||
if (int.TryParse(m_Values[index], out intValue))
|
||||
{
|
||||
return intValue;
|
||||
}
|
||||
|
||||
bool boolValue;
|
||||
if (bool.TryParse(m_Values[index], out boolValue))
|
||||
{
|
||||
return boolValue;
|
||||
}
|
||||
|
||||
return m_Values[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
string strValue;
|
||||
|
||||
if (value is Enum)
|
||||
{
|
||||
strValue = ((int)value).ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
strValue = value.ToString();
|
||||
}
|
||||
|
||||
var index = m_Keys.IndexOf(key);
|
||||
if (index == -1)
|
||||
{
|
||||
m_Keys.Add(key);
|
||||
m_Values.Add(strValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Values[index] = strValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
Executable
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 962a150b07e814ff0a531dd29ee67940
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Vendored
Executable
+358
@@ -0,0 +1,358 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
using Unity.Notifications.iOS;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Unity.Notifications
|
||||
{
|
||||
[HelpURL("Packages/com.unity.mobile.notifications/documentation.html")]
|
||||
internal class NotificationSettingsManager : ScriptableObject
|
||||
{
|
||||
internal static readonly string k_SettingsPath = "ProjectSettings/NotificationsSettings.asset";
|
||||
|
||||
private static NotificationSettingsManager s_SettingsManager;
|
||||
|
||||
[FormerlySerializedAs("toolbarInt")]
|
||||
public int ToolbarIndex = 0;
|
||||
|
||||
public List<NotificationSetting> iOSNotificationSettings;
|
||||
public List<NotificationSetting> AndroidNotificationSettings;
|
||||
|
||||
[SerializeField]
|
||||
[FormerlySerializedAs("iOSNotificationEditorSettingsValues")]
|
||||
private NotificationSettingsCollection m_iOSNotificationSettingsValues;
|
||||
|
||||
[SerializeField]
|
||||
[FormerlySerializedAs("AndroidNotificationEditorSettingsValues")]
|
||||
private NotificationSettingsCollection m_AndroidNotificationSettingsValues;
|
||||
|
||||
[FormerlySerializedAs("TrackedResourceAssets")]
|
||||
public List<DrawableResourceData> DrawableResources = new List<DrawableResourceData>();
|
||||
|
||||
public List<NotificationSetting> iOSNotificationSettingsFlat
|
||||
{
|
||||
get
|
||||
{
|
||||
var target = new List<NotificationSetting>();
|
||||
FlattenList(iOSNotificationSettings, target);
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
public List<NotificationSetting> AndroidNotificationSettingsFlat
|
||||
{
|
||||
get
|
||||
{
|
||||
var target = new List<NotificationSetting>();
|
||||
FlattenList(AndroidNotificationSettings, target);
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
private void FlattenList(List<NotificationSetting> source, List<NotificationSetting> target)
|
||||
{
|
||||
foreach (var setting in source)
|
||||
{
|
||||
target.Add(setting);
|
||||
|
||||
if (setting.Dependencies != null)
|
||||
{
|
||||
FlattenList(setting.Dependencies, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static NotificationSettingsManager Initialize()
|
||||
{
|
||||
if (s_SettingsManager != null)
|
||||
return s_SettingsManager;
|
||||
|
||||
var settingsManager = CreateInstance<NotificationSettingsManager>();
|
||||
bool dirty = false;
|
||||
|
||||
if (File.Exists(k_SettingsPath))
|
||||
{
|
||||
var settingsJson = File.ReadAllText(k_SettingsPath);
|
||||
if (!string.IsNullOrEmpty(settingsJson))
|
||||
EditorJsonUtility.FromJsonOverwrite(settingsJson, settingsManager);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only migrate if there is no new settings asset under k_SettingsPath.
|
||||
dirty = MigrateFromLegacySettings(settingsManager);
|
||||
}
|
||||
|
||||
if (settingsManager.m_iOSNotificationSettingsValues == null)
|
||||
{
|
||||
settingsManager.m_iOSNotificationSettingsValues = new NotificationSettingsCollection();
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if (settingsManager.m_AndroidNotificationSettingsValues == null)
|
||||
{
|
||||
settingsManager.m_AndroidNotificationSettingsValues = new NotificationSettingsCollection();
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
// Create the settings for iOS.
|
||||
settingsManager.iOSNotificationSettings = new List<NotificationSetting>()
|
||||
{
|
||||
new NotificationSetting(
|
||||
NotificationSettings.iOSSettings.REQUEST_AUTH_ON_LAUNCH,
|
||||
"Request Authorization on App Launch",
|
||||
"It's recommended to make the authorization request during the app's launch cycle. If this is enabled the authorization pop-up will show up immediately during launching. Otherwise you need to manually create an AuthorizationRequest before sending or receiving notifications.",
|
||||
settingsManager.GetOrAddNotificationSettingValue(NotificationSettings.iOSSettings.REQUEST_AUTH_ON_LAUNCH, true, false),
|
||||
dependencies: new List<NotificationSetting>()
|
||||
{
|
||||
new NotificationSetting(
|
||||
NotificationSettings.iOSSettings.DEFAULT_AUTH_OPTS,
|
||||
"Default Notification Authorization Options",
|
||||
"Configure the notification interaction types which will be included in the authorization request if \"Request Authorization on App Launch\" is enabled.",
|
||||
settingsManager.GetOrAddNotificationSettingValue(NotificationSettings.iOSSettings.DEFAULT_AUTH_OPTS,
|
||||
AuthorizationOption.Alert | AuthorizationOption.Badge | AuthorizationOption.Sound, false)),
|
||||
}),
|
||||
new NotificationSetting(
|
||||
NotificationSettings.iOSSettings.ADD_PUSH_CAPABILITY,
|
||||
"Enable Push Notifications",
|
||||
"Enable this to add the push notification capability to the Xcode project, also to retrieve the device token from an AuthorizationRequest.",
|
||||
settingsManager.GetOrAddNotificationSettingValue(NotificationSettings.iOSSettings.ADD_PUSH_CAPABILITY, false, false),
|
||||
false,
|
||||
new List<NotificationSetting>()
|
||||
{
|
||||
new NotificationSetting(
|
||||
NotificationSettings.iOSSettings.REQUEST_PUSH_AUTH_ON_LAUNCH,
|
||||
"Register for Push Notifications on App Launch",
|
||||
"Enable this to automatically register your app with APNs after launching to receive remote notifications. You need to manually create an AuthorizationRequest to get the device token.",
|
||||
settingsManager.GetOrAddNotificationSettingValue(NotificationSettings.iOSSettings.REQUEST_PUSH_AUTH_ON_LAUNCH, false, false)),
|
||||
new NotificationSetting(
|
||||
NotificationSettings.iOSSettings.PUSH_NOTIFICATION_PRESENTATION,
|
||||
"Remote Notification Foreground Presentation Options",
|
||||
"Configure the default presentation options for received remote notifications. In order to use the specified presentation options, your app must have received the authorization (the user might change it at any time).",
|
||||
settingsManager.GetOrAddNotificationSettingValue(NotificationSettings.iOSSettings.PUSH_NOTIFICATION_PRESENTATION, (PresentationOption)iOSPresentationOption.All, false)),
|
||||
new NotificationSetting(NotificationSettings.iOSSettings.USE_APS_RELEASE,
|
||||
"Enable Release Environment for APS",
|
||||
"Enable this when signing the app with a production certificate.",
|
||||
settingsManager.GetOrAddNotificationSettingValue(NotificationSettings.iOSSettings.USE_APS_RELEASE, false, false),
|
||||
false),
|
||||
}),
|
||||
new NotificationSetting(NotificationSettings.iOSSettings.USE_LOCATION_TRIGGER,
|
||||
"Include CoreLocation Framework",
|
||||
"Include the CoreLocation framework to use the iOSNotificationLocationTrigger in your project.",
|
||||
settingsManager.GetOrAddNotificationSettingValue(NotificationSettings.iOSSettings.USE_LOCATION_TRIGGER, false, false),
|
||||
false),
|
||||
new NotificationSetting(NotificationSettings.iOSSettings.ADD_TIME_SENSITIVE_ENTITLEMENT,
|
||||
"Enable time sensitive notifications",
|
||||
"Enable to add entitlement for notifications with time sensitive interruption level",
|
||||
settingsManager.GetOrAddNotificationSettingValue(NotificationSettings.iOSSettings.ADD_TIME_SENSITIVE_ENTITLEMENT, false, false),
|
||||
false),
|
||||
};
|
||||
|
||||
// Create the settings for Android.
|
||||
settingsManager.AndroidNotificationSettings = new List<NotificationSetting>()
|
||||
{
|
||||
new NotificationSetting(
|
||||
NotificationSettings.AndroidSettings.RESCHEDULE_ON_RESTART,
|
||||
"Reschedule on Device Restart",
|
||||
"Enable this to automatically reschedule all non-expired notifications after device restart. By default AndroidSettings removes all scheduled notifications after restarting.",
|
||||
settingsManager.GetOrAddNotificationSettingValue(NotificationSettings.AndroidSettings.RESCHEDULE_ON_RESTART, false, true)),
|
||||
new NotificationSetting(
|
||||
NotificationSettings.AndroidSettings.EXACT_ALARM,
|
||||
"Schedule at exact time",
|
||||
"Whether notifications should appear at exact time or approximate",
|
||||
settingsManager.GetOrAddNotificationSettingValue(NotificationSettings.AndroidSettings.EXACT_ALARM, (AndroidExactSchedulingOption)0, true)),
|
||||
new NotificationSetting(
|
||||
NotificationSettings.AndroidSettings.USE_CUSTOM_ACTIVITY,
|
||||
"Use Custom Activity",
|
||||
"Enable this to override the activity which will be opened when the user taps the notification.",
|
||||
settingsManager.GetOrAddNotificationSettingValue(NotificationSettings.AndroidSettings.USE_CUSTOM_ACTIVITY, false, true),
|
||||
dependencies: new List<NotificationSetting>()
|
||||
{
|
||||
new NotificationSetting(
|
||||
NotificationSettings.AndroidSettings.CUSTOM_ACTIVITY_CLASS,
|
||||
"Custom Activity Name",
|
||||
"The full class name of the activity which will be assigned to the notification.",
|
||||
settingsManager.GetOrAddNotificationSettingValue(NotificationSettings.AndroidSettings.CUSTOM_ACTIVITY_CLASS, "com.unity3d.player.UnityPlayerActivity", true))
|
||||
})
|
||||
};
|
||||
|
||||
settingsManager.SaveSettings(dirty);
|
||||
|
||||
s_SettingsManager = settingsManager;
|
||||
return s_SettingsManager;
|
||||
}
|
||||
|
||||
private static bool MigrateFromLegacySettings(NotificationSettingsManager settingsManager)
|
||||
{
|
||||
const string k_LegacyAssetPath = "Assets/Editor/com.unity.mobile.notifications/NotificationSettings.asset";
|
||||
if (!File.Exists(k_LegacyAssetPath))
|
||||
return false;
|
||||
|
||||
var settingsManagerLegacy = AssetDatabase.LoadAssetAtPath<NotificationSettingsManager>(k_LegacyAssetPath);
|
||||
if (settingsManagerLegacy == null)
|
||||
return false;
|
||||
|
||||
settingsManager.ToolbarIndex = settingsManagerLegacy.ToolbarIndex;
|
||||
settingsManager.m_iOSNotificationSettingsValues = settingsManagerLegacy.m_iOSNotificationSettingsValues;
|
||||
settingsManager.m_AndroidNotificationSettingsValues = settingsManagerLegacy.m_AndroidNotificationSettingsValues;
|
||||
settingsManager.DrawableResources = settingsManagerLegacy.DrawableResources;
|
||||
|
||||
AssetDatabase.DeleteAsset(k_LegacyAssetPath);
|
||||
DeleteEmptyDirectoryAsset("Assets/Editor/com.unity.mobile.notifications");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void DeleteEmptyDirectoryAsset(string directory)
|
||||
{
|
||||
var directoryInfo = new DirectoryInfo(directory);
|
||||
if (!directoryInfo.Exists || directoryInfo.GetDirectories().Length > 0 || directoryInfo.GetFiles().Length > 0)
|
||||
return;
|
||||
|
||||
AssetDatabase.DeleteAsset(directory);
|
||||
}
|
||||
|
||||
private T GetOrAddNotificationSettingValue<T>(string key, T defaultValue, bool isAndroid)
|
||||
{
|
||||
var collection = isAndroid ? m_AndroidNotificationSettingsValues : m_iOSNotificationSettingsValues;
|
||||
|
||||
try
|
||||
{
|
||||
var value = collection[key];
|
||||
if (value != null)
|
||||
return (T)value;
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
Debug.LogWarning("Failed loading : " + key + " for type:" + defaultValue.GetType() + " Expected : " + collection[key].GetType());
|
||||
//Just return default value if it's a new setting that was not yet serialized.
|
||||
}
|
||||
|
||||
collection[key] = defaultValue;
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public void SaveSetting(NotificationSetting setting, BuildTargetGroup target)
|
||||
{
|
||||
var collection = (target == BuildTargetGroup.Android) ? m_AndroidNotificationSettingsValues : m_iOSNotificationSettingsValues;
|
||||
|
||||
if (!collection.Contains(setting.Key) || collection[setting.Key].ToString() != setting.Value.ToString())
|
||||
{
|
||||
collection[setting.Key] = setting.Value;
|
||||
SaveSettings();
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveSettings(bool forceSave = true)
|
||||
{
|
||||
if (!forceSave && File.Exists(k_SettingsPath))
|
||||
return;
|
||||
|
||||
if (AssetDatabase.MakeEditable(k_SettingsPath))
|
||||
File.WriteAllText(k_SettingsPath, EditorJsonUtility.ToJson(this, true));
|
||||
else
|
||||
Debug.LogError($"Failed to make file {k_SettingsPath} editable");
|
||||
}
|
||||
|
||||
public void AddDrawableResource(string id, Texture2D image, NotificationIconType type)
|
||||
{
|
||||
/* commenting out for now, since you can have same Id's in editor
|
||||
foreach (var drawable in DrawableResources)
|
||||
{
|
||||
if (drawable.Id == id)
|
||||
{
|
||||
Debug.LogWarning("Drawable with Id"+id+" already exists, please assign another Id");
|
||||
return;
|
||||
}
|
||||
} */
|
||||
var drawableResource = new DrawableResourceData();
|
||||
drawableResource.Id = id;
|
||||
drawableResource.Type = type;
|
||||
drawableResource.Asset = image;
|
||||
|
||||
DrawableResources.Add(drawableResource);
|
||||
SaveSettings();
|
||||
}
|
||||
|
||||
public void RemoveDrawableResourceByIndex(int index)
|
||||
{
|
||||
if (index < DrawableResources.Count && index >= 0)
|
||||
{
|
||||
DrawableResources.RemoveAt(index);
|
||||
SaveSettings();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("Invalid drawable index provided, drawable not removed.");
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveDrawableResourceById(string id)
|
||||
{
|
||||
DrawableResourceData DrawableRes = null;
|
||||
foreach (var drawable in DrawableResources)
|
||||
{
|
||||
if (drawable.Id == id)
|
||||
{
|
||||
DrawableRes = drawable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (DrawableRes == null)
|
||||
{
|
||||
Debug.LogWarning("Drawable with Id " + id + " not found. Drawable not removed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawableResources.Remove(DrawableRes);
|
||||
SaveSettings();
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearDrawableResources()
|
||||
{
|
||||
DrawableResources.Clear();
|
||||
SaveSettings();
|
||||
}
|
||||
|
||||
public Dictionary<string, byte[]> GenerateDrawableResourcesForExport()
|
||||
{
|
||||
var icons = new Dictionary<string, byte[]>();
|
||||
foreach (var drawableResource in DrawableResources)
|
||||
{
|
||||
if (!drawableResource.Verify())
|
||||
{
|
||||
Debug.LogWarning(string.Format("Failed exporting: '{0}' AndroidSettings notification icon because:\n {1} ",
|
||||
drawableResource.Id,
|
||||
drawableResource.GenerateErrorString()));
|
||||
continue;
|
||||
}
|
||||
|
||||
var texture = TextureAssetUtils.ProcessTextureForType(drawableResource.Asset, drawableResource.Type);
|
||||
|
||||
var scale = drawableResource.Type == NotificationIconType.Small ? 0.375f : 1;
|
||||
|
||||
var textXhdpi = TextureAssetUtils.ScaleTexture(texture, (int)(128 * scale), (int)(128 * scale));
|
||||
var textHdpi = TextureAssetUtils.ScaleTexture(texture, (int)(96 * scale), (int)(96 * scale));
|
||||
var textMdpi = TextureAssetUtils.ScaleTexture(texture, (int)(64 * scale), (int)(64 * scale));
|
||||
var textLdpi = TextureAssetUtils.ScaleTexture(texture, (int)(48 * scale), (int)(48 * scale));
|
||||
|
||||
icons[string.Format("drawable-xhdpi-v11/{0}.png", drawableResource.Id)] = textXhdpi.EncodeToPNG();
|
||||
icons[string.Format("drawable-hdpi-v11/{0}.png", drawableResource.Id)] = textHdpi.EncodeToPNG();
|
||||
icons[string.Format("drawable-mdpi-v11/{0}.png", drawableResource.Id)] = textMdpi.EncodeToPNG();
|
||||
icons[string.Format("drawable-ldpi-v11/{0}.png", drawableResource.Id)] = textLdpi.EncodeToPNG();
|
||||
|
||||
if (drawableResource.Type == NotificationIconType.Large)
|
||||
{
|
||||
var textXxhdpi = TextureAssetUtils.ScaleTexture(texture, (int)(192 * scale), (int)(192 * scale));
|
||||
icons[string.Format("drawable-xxhdpi-v11/{0}.png", drawableResource.Id)] = textXxhdpi.EncodeToPNG();
|
||||
}
|
||||
}
|
||||
|
||||
return icons;
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
Executable
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0863bf92b4fcc45b0b9267325249bf0f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Vendored
Executable
+376
@@ -0,0 +1,376 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
using Unity.Notifications.iOS;
|
||||
using UnityEngine.Assertions;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Unity.Notifications
|
||||
{
|
||||
internal class NotificationSettingsProvider : SettingsProvider
|
||||
{
|
||||
private const int k_SlotSize = 64;
|
||||
private const int k_IconSpacing = 8;
|
||||
private const float k_Padding = 12f;
|
||||
private const float k_ToolbarHeight = 20f;
|
||||
private const int k_VerticalSeparator = 2;
|
||||
private const int k_LabelLineHeight = 18;
|
||||
|
||||
private readonly GUIContent k_IdentifierLabelText = new GUIContent("Identifier");
|
||||
private readonly GUIContent k_TypeLabelText = new GUIContent("Type");
|
||||
|
||||
private readonly string[] k_ToolbarStrings = { "Android", "iOS" };
|
||||
private const string k_InfoStringAndroid =
|
||||
"Only icons added to this list or manually added to the 'res/drawable' folder can be used for notifications.\n" +
|
||||
"Note, that not all devices support colored icons.\n\n" +
|
||||
"Small icons must be at least 48x48px and only composed of white pixels on a transparent background.\n" +
|
||||
"Large icons must be no smaller than 192x192px and may contain colors.";
|
||||
|
||||
private NotificationSettingsManager m_SettingsManager;
|
||||
|
||||
private SerializedObject m_SettingsManagerObject;
|
||||
private SerializedProperty m_DrawableResources;
|
||||
|
||||
private Vector2 m_ScrollViewStart;
|
||||
private ReorderableList m_ReorderableList;
|
||||
|
||||
private NotificationSettingsProvider(string path, SettingsScope scopes)
|
||||
: base(path, scopes)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
[SettingsProvider]
|
||||
static SettingsProvider CreateMobileNotificationsSettingsProvider()
|
||||
{
|
||||
return new NotificationSettingsProvider("Project/Mobile Notifications", SettingsScope.Project);
|
||||
}
|
||||
|
||||
public override void OnActivate(string searchContext, VisualElement rootElement)
|
||||
{
|
||||
base.OnActivate(searchContext, rootElement);
|
||||
// in case of domain reload (enter-exit play mode, this gets lost)
|
||||
if (m_SettingsManager == null)
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public override void OnDeactivate()
|
||||
{
|
||||
base.OnDeactivate();
|
||||
m_SettingsManager.SaveSettings(false);
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
label = "Mobile Notifications";
|
||||
m_SettingsManager = NotificationSettingsManager.Initialize();
|
||||
|
||||
// These two are for ReorderableList.
|
||||
m_SettingsManagerObject = new SerializedObject(m_SettingsManager);
|
||||
m_DrawableResources = m_SettingsManagerObject.FindProperty("DrawableResources");
|
||||
|
||||
// ReorderableList is only used to draw the drawable resources for Android settings.
|
||||
InitReorderableList();
|
||||
|
||||
Undo.undoRedoPerformed += () =>
|
||||
{
|
||||
m_SettingsManagerObject.UpdateIfRequiredOrScript();
|
||||
Repaint();
|
||||
};
|
||||
}
|
||||
|
||||
private void InitReorderableList()
|
||||
{
|
||||
m_ReorderableList = new ReorderableList(m_SettingsManagerObject, m_DrawableResources, false, false, true, true);
|
||||
m_ReorderableList.elementHeight = k_SlotSize + k_IconSpacing;
|
||||
m_ReorderableList.showDefaultBackground = true;
|
||||
m_ReorderableList.headerHeight = 1;
|
||||
|
||||
// Register all the necessary callbacks on ReorderableList.
|
||||
m_ReorderableList.onAddCallback = (list) =>
|
||||
{
|
||||
Undo.RegisterCompleteObjectUndo(m_SettingsManager, "Add a new icon element");
|
||||
m_SettingsManager.AddDrawableResource(string.Format("icon_{0}", m_SettingsManager.DrawableResources.Count), null, NotificationIconType.Small);
|
||||
};
|
||||
|
||||
m_ReorderableList.onRemoveCallback = (list) =>
|
||||
{
|
||||
m_SettingsManager.RemoveDrawableResourceByIndex(list.index);
|
||||
};
|
||||
|
||||
m_ReorderableList.onCanAddCallback = (list) =>
|
||||
{
|
||||
var trackedAssets = m_SettingsManager.DrawableResources;
|
||||
if (trackedAssets.Count <= 0)
|
||||
return true;
|
||||
|
||||
return trackedAssets.All(asset => asset.Initialized());
|
||||
};
|
||||
|
||||
m_ReorderableList.drawElementCallback = (rect, index, active, focused) => DrawIconDataElement(rect, index, active, focused);
|
||||
|
||||
m_ReorderableList.drawElementBackgroundCallback = (rect, index, active, focused) =>
|
||||
{
|
||||
if (Event.current.type != EventType.Repaint)
|
||||
return;
|
||||
|
||||
var background = index % 2 == 0 ? NotificationStyles.k_EvenRow : NotificationStyles.k_OddRow;
|
||||
background.Draw(rect, false, false, false, false);
|
||||
|
||||
ReorderableList.defaultBehaviours.DrawElementBackground(rect, index, active, focused, true);
|
||||
};
|
||||
|
||||
m_ReorderableList.elementHeightCallback = (index) =>
|
||||
{
|
||||
var data = GetDrawableResource(index);
|
||||
if (data == null)
|
||||
return k_SlotSize;
|
||||
|
||||
return m_ReorderableList.elementHeight + (data.Asset != null && !data.IsValid ? k_SlotSize : 0);
|
||||
};
|
||||
}
|
||||
|
||||
private void DrawIconDataElement(Rect rect, int index, bool active, bool focused)
|
||||
{
|
||||
var drawableResource = GetDrawableResource(index);
|
||||
if (drawableResource == null)
|
||||
return;
|
||||
|
||||
var elementRect = AddPadding(rect, k_Padding, k_Padding / 2);
|
||||
|
||||
// Calculate and draw id and type.
|
||||
var idLabelRect = new Rect(elementRect.x, elementRect.y, k_SlotSize, k_ToolbarHeight);
|
||||
var idTextFieldRect = new Rect(idLabelRect.x + k_SlotSize, idLabelRect.y, k_SlotSize, k_ToolbarHeight);
|
||||
|
||||
var typeLabelRect = new Rect(elementRect.x, elementRect.y + 25, k_SlotSize, k_ToolbarHeight);
|
||||
var typeEnumPopupRect = new Rect(typeLabelRect.x + k_SlotSize, typeLabelRect.y, k_SlotSize, k_ToolbarHeight);
|
||||
|
||||
EditorGUI.LabelField(idLabelRect, k_IdentifierLabelText);
|
||||
var newId = EditorGUI.TextField(idTextFieldRect, drawableResource.Id);
|
||||
|
||||
EditorGUI.LabelField(typeLabelRect, k_TypeLabelText);
|
||||
var newType = (NotificationIconType)EditorGUI.EnumPopup(typeEnumPopupRect, drawableResource.Type);
|
||||
|
||||
// Calculate and draw texture and preview.
|
||||
var textureX = Mathf.Max(elementRect.width - (k_SlotSize * 2 - k_IconSpacing * 5), k_SlotSize * 3);
|
||||
var textureRect = new Rect(textureX, elementRect.y, k_SlotSize, k_SlotSize);
|
||||
var previewTextureRect = new Rect(textureRect.x + k_SlotSize, textureRect.y - 6, k_SlotSize, k_SlotSize);
|
||||
|
||||
var newAsset = (Texture2D)EditorGUI.ObjectField(textureRect, drawableResource.Asset, typeof(Texture2D), false);
|
||||
|
||||
// Check if the texture has been updated.
|
||||
bool updatePreviewTexture = (newId != drawableResource.Id || newType != drawableResource.Type || newAsset != drawableResource.Asset);
|
||||
if (updatePreviewTexture)
|
||||
{
|
||||
Undo.RegisterCompleteObjectUndo(m_SettingsManager, "Update icon data");
|
||||
drawableResource.Id = newId;
|
||||
drawableResource.Type = newType;
|
||||
drawableResource.Asset = newAsset;
|
||||
drawableResource.Clean();
|
||||
drawableResource.Verify();
|
||||
m_SettingsManager.SaveSettings();
|
||||
}
|
||||
|
||||
if (drawableResource.Asset != null && !drawableResource.Verify())
|
||||
{
|
||||
var errorMsgWidth = rect.width - k_Padding * 2;
|
||||
var errorRect = AddPadding(new Rect(elementRect.x, elementRect.y + k_SlotSize, errorMsgWidth, k_LabelLineHeight * 3), 4, 4);
|
||||
|
||||
var errorMsg = "Specified texture can't be used because: \n" + drawableResource.GenerateErrorString();
|
||||
EditorGUI.HelpBox(errorRect, errorMsg, MessageType.Error);
|
||||
|
||||
GUI.Box(previewTextureRect, "Preview not available", NotificationStyles.k_PreviewMessageTextStyle);
|
||||
}
|
||||
else
|
||||
{
|
||||
var previewTexture = drawableResource.GetPreviewTexture(updatePreviewTexture);
|
||||
if (previewTexture != null)
|
||||
{
|
||||
previewTexture.alphaIsTransparency = false;
|
||||
|
||||
EditorGUI.LabelField(previewTextureRect, "Preview", NotificationStyles.k_PreviewLabelTextStyle);
|
||||
|
||||
var previewTextureRectPadded = AddPadding(previewTextureRect, 6f, 6f);
|
||||
previewTextureRectPadded.y += 8;
|
||||
GUI.DrawTexture(previewTextureRectPadded, previewTexture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private DrawableResourceData GetDrawableResource(int index)
|
||||
{
|
||||
var resourceAssets = m_SettingsManager.DrawableResources;
|
||||
if (index < resourceAssets.Count)
|
||||
return resourceAssets[index];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Rect AddPadding(Rect rect, float horizontal, float vertical)
|
||||
{
|
||||
Rect paddingRect = rect;
|
||||
paddingRect.xMin += horizontal;
|
||||
paddingRect.xMax -= horizontal;
|
||||
paddingRect.yMin += vertical;
|
||||
paddingRect.yMax -= vertical;
|
||||
|
||||
return paddingRect;
|
||||
}
|
||||
|
||||
public override void OnGUI(string searchContext)
|
||||
{
|
||||
if (m_SettingsManager == null)
|
||||
Initialize();
|
||||
|
||||
// This has to be called to sync all the changes between m_SettingsManager and m_SettingsManagerObject.
|
||||
if (m_SettingsManagerObject.targetObject != null)
|
||||
m_SettingsManagerObject.Update();
|
||||
|
||||
var noHeightRect = GUILayoutUtility.GetRect(GUIContent.none, EditorStyles.label, GUILayout.ExpandWidth(true), GUILayout.Height(0));
|
||||
var width = noHeightRect.width;
|
||||
|
||||
var totalRect = new Rect(k_Padding, 0f, width - k_Padding, Screen.height);
|
||||
|
||||
// Draw the toolbar for Android/iOS.
|
||||
var toolBarRect = new Rect(totalRect.x, totalRect.y, totalRect.width, k_ToolbarHeight);
|
||||
var toolbarIndex = GUI.Toolbar(toolBarRect, m_SettingsManager.ToolbarIndex, k_ToolbarStrings);
|
||||
if (toolbarIndex != m_SettingsManager.ToolbarIndex)
|
||||
{
|
||||
m_SettingsManager.ToolbarIndex = toolbarIndex;
|
||||
m_SettingsManager.SaveSettings();
|
||||
}
|
||||
|
||||
var notificationSettingsRect = new Rect(totalRect.x, k_ToolbarHeight + 2, totalRect.width, totalRect.height - k_ToolbarHeight - k_Padding);
|
||||
|
||||
// Draw the notification settings.
|
||||
int drawnSettingsCount = DrawNotificationSettings(notificationSettingsRect, m_SettingsManager.ToolbarIndex);
|
||||
if (drawnSettingsCount <= 0)
|
||||
return;
|
||||
|
||||
float heightPlaceHolder = k_SlotSize;
|
||||
|
||||
// Draw drawable resources list for Android.
|
||||
if (m_SettingsManager.ToolbarIndex == 0)
|
||||
{
|
||||
var iconListlabelRect = new Rect(notificationSettingsRect.x, notificationSettingsRect.y + 85, 180, k_LabelLineHeight);
|
||||
GUI.Label(iconListlabelRect, "Notification Icons", EditorStyles.label);
|
||||
|
||||
// Draw the help message for setting the icons.
|
||||
float labelHeight;
|
||||
if (notificationSettingsRect.width > 510)
|
||||
labelHeight = k_LabelLineHeight * 4;
|
||||
else if (notificationSettingsRect.width > 500)
|
||||
labelHeight = k_LabelLineHeight * 5;
|
||||
else
|
||||
labelHeight = k_LabelLineHeight * 6;
|
||||
var iconListMsgRect = new Rect(iconListlabelRect.x, iconListlabelRect.y + iconListlabelRect.height + k_VerticalSeparator, notificationSettingsRect.width, labelHeight);
|
||||
EditorGUI.SelectableLabel(iconListMsgRect, k_InfoStringAndroid, NotificationStyles.k_IconHelpMessageStyle);
|
||||
|
||||
// Draw the reorderable list for the icon list.
|
||||
var iconListRect = new Rect(iconListMsgRect.x, iconListMsgRect.y + iconListMsgRect.height + k_VerticalSeparator, iconListMsgRect.width, notificationSettingsRect.height - 55f);
|
||||
m_ReorderableList.DoList(iconListRect);
|
||||
|
||||
heightPlaceHolder += iconListMsgRect.height + m_ReorderableList.GetHeight();
|
||||
}
|
||||
|
||||
// We have to do this to occupy the space that ScrollView can set the scrollbars correctly.
|
||||
EditorGUILayout.GetControlRect(true, heightPlaceHolder, GUILayout.MinWidth(width));
|
||||
}
|
||||
|
||||
private int DrawNotificationSettings(Rect rect, int toolbarIndex)
|
||||
{
|
||||
Assert.IsTrue(toolbarIndex == 0 || toolbarIndex == 1);
|
||||
|
||||
List<NotificationSetting> settings;
|
||||
BuildTargetGroup buildTarget;
|
||||
int labelWidthMultiplier;
|
||||
if (toolbarIndex == 0)
|
||||
{
|
||||
settings = m_SettingsManager.AndroidNotificationSettings;
|
||||
buildTarget = BuildTargetGroup.Android;
|
||||
labelWidthMultiplier = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
settings = m_SettingsManager.iOSNotificationSettings;
|
||||
buildTarget = BuildTargetGroup.iOS;
|
||||
labelWidthMultiplier = 5;
|
||||
}
|
||||
|
||||
if (settings == null)
|
||||
return 0;
|
||||
|
||||
GUI.BeginGroup(rect);
|
||||
var drawnSettingsCount = DrawSettingElements(rect, buildTarget, settings, false, 0, labelWidthMultiplier);
|
||||
GUI.EndGroup();
|
||||
|
||||
return drawnSettingsCount;
|
||||
}
|
||||
|
||||
private int DrawSettingElements(Rect rect, BuildTargetGroup buildTarget, List<NotificationSetting> settings, bool disabled, int layer, int labelWidthMultiplier)
|
||||
{
|
||||
var spaceOffset = layer * 13;
|
||||
|
||||
var labelStyle = new GUIStyle(NotificationStyles.k_LabelStyle);
|
||||
labelStyle.fixedWidth = k_SlotSize * labelWidthMultiplier - spaceOffset;
|
||||
|
||||
var toggleStyle = NotificationStyles.k_ToggleStyle;
|
||||
var dropdownStyle = NotificationStyles.k_DropwDownStyle;
|
||||
|
||||
int elementCount = settings.Count;
|
||||
foreach (var setting in settings)
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(disabled);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Space(spaceOffset);
|
||||
|
||||
GUILayout.Label(new GUIContent(setting.Label, setting.Tooltip), labelStyle);
|
||||
|
||||
bool dependenciesDisabled = false;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
if (setting.Value.GetType() == typeof(bool))
|
||||
{
|
||||
setting.Value = EditorGUILayout.Toggle((bool)setting.Value, toggleStyle);
|
||||
dependenciesDisabled = !(bool)setting.Value;
|
||||
}
|
||||
else if (setting.Value.GetType() == typeof(string))
|
||||
{
|
||||
setting.Value = EditorGUILayout.TextField((string)setting.Value);
|
||||
}
|
||||
else if (setting.Value.GetType() == typeof(PresentationOption))
|
||||
{
|
||||
setting.Value = (PresentationOption)EditorGUILayout.EnumFlagsField((iOSPresentationOption)setting.Value, dropdownStyle);
|
||||
}
|
||||
else if (setting.Value.GetType() == typeof(AuthorizationOption))
|
||||
{
|
||||
setting.Value = (AuthorizationOption)EditorGUILayout.EnumFlagsField((iOSAuthorizationOption)setting.Value, dropdownStyle);
|
||||
if ((iOSAuthorizationOption)setting.Value == 0)
|
||||
setting.Value = (AuthorizationOption)(iOSAuthorizationOption.Badge | iOSAuthorizationOption.Sound | iOSAuthorizationOption.Alert);
|
||||
}
|
||||
else if (setting.Value.GetType() == typeof(AndroidExactSchedulingOption))
|
||||
{
|
||||
setting.Value = (AndroidExactSchedulingOption)EditorGUILayout.EnumFlagsField((AndroidExactSchedulingOption)setting.Value, dropdownStyle);
|
||||
}
|
||||
else
|
||||
Debug.LogError("Unsupported setting type: " + setting.Value.GetType());
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
m_SettingsManager.SaveSetting(setting, buildTarget);
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
if (setting.Dependencies != null)
|
||||
{
|
||||
elementCount += DrawSettingElements(rect, buildTarget, setting.Dependencies, dependenciesDisabled, layer + 1, labelWidthMultiplier);
|
||||
}
|
||||
}
|
||||
|
||||
return elementCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
Executable
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c8f51a1ea13c0461f8868c187d4ca482
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Vendored
Executable
+16
@@ -0,0 +1,16 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.Notifications
|
||||
{
|
||||
internal class NotificationStyles
|
||||
{
|
||||
public static readonly GUIStyle k_EvenRow = new GUIStyle("CN EntryBackEven");
|
||||
public static readonly GUIStyle k_OddRow = new GUIStyle("CN EntryBackOdd");
|
||||
public static readonly GUIStyle k_PreviewMessageTextStyle = new GUIStyle(GUI.skin.label) { fontSize = 8, wordWrap = true, alignment = TextAnchor.MiddleCenter };
|
||||
public static readonly GUIStyle k_PreviewLabelTextStyle = new GUIStyle(GUI.skin.label) { fontSize = 8, wordWrap = true, alignment = TextAnchor.UpperCenter };
|
||||
public static readonly GUIStyle k_IconHelpMessageStyle = new GUIStyle(GUI.skin.GetStyle("HelpBox")) { fontSize = 10, wordWrap = true, alignment = TextAnchor.UpperLeft };
|
||||
public static readonly GUIStyle k_ToggleStyle = new GUIStyle(GUI.skin.GetStyle("Toggle")) { alignment = TextAnchor.MiddleRight };
|
||||
public static readonly GUIStyle k_DropwDownStyle = new GUIStyle(GUI.skin.GetStyle("Button")) { alignment = TextAnchor.MiddleLeft };
|
||||
public static readonly GUIStyle k_LabelStyle = new GUIStyle(GUI.skin.GetStyle("Label")) { wordWrap = true };
|
||||
}
|
||||
}
|
||||
Vendored
Executable
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d20e68231df79a46be46dfc6d6e8580
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Vendored
Executable
+118
@@ -0,0 +1,118 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.Notifications
|
||||
{
|
||||
internal static class TextureAssetUtils
|
||||
{
|
||||
public static bool VerifyTextureByType(Texture2D texture, NotificationIconType type, out List<string> errors)
|
||||
{
|
||||
errors = new List<string>();
|
||||
|
||||
if (texture == null)
|
||||
{
|
||||
errors.Add("Texture is invalid");
|
||||
return false;
|
||||
}
|
||||
|
||||
var needsAlpha = true;
|
||||
var minSize = 48;
|
||||
|
||||
if (type == NotificationIconType.Large)
|
||||
{
|
||||
needsAlpha = false;
|
||||
minSize = 192;
|
||||
}
|
||||
|
||||
var isSquare = texture.width == texture.height;
|
||||
var isLargeEnough = texture.width >= minSize;
|
||||
var hasAlpha = true;// TODO: texture.format == TextureFormat.Alpha8;
|
||||
|
||||
var isReadable = texture.isReadable;
|
||||
|
||||
if (!isReadable)
|
||||
{
|
||||
errors.Add("Read/Write is not enabled in the texture importer");
|
||||
}
|
||||
|
||||
if (!isLargeEnough)
|
||||
errors.Add(string.Format("Texture must be at least {0}x{1} pixels (while it's {2}x{3})",
|
||||
minSize,
|
||||
minSize,
|
||||
texture.width,
|
||||
texture.height
|
||||
));
|
||||
|
||||
if (!isSquare)
|
||||
errors.Add(string.Format("Texture must have the same width and height (while it's {0}x{1})",
|
||||
texture.width,
|
||||
texture.height
|
||||
));
|
||||
|
||||
if (!hasAlpha && needsAlpha)
|
||||
errors.Add(string.Format("Texture must contain an alpha channel"));
|
||||
|
||||
return isReadable && isSquare && isLargeEnough && (!needsAlpha || hasAlpha);
|
||||
}
|
||||
|
||||
public static Texture2D ProcessTextureForType(Texture2D sourceTexture, NotificationIconType type)
|
||||
{
|
||||
if (sourceTexture == null)
|
||||
return null;
|
||||
|
||||
string assetPath = AssetDatabase.GetAssetPath(sourceTexture);
|
||||
var importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
|
||||
|
||||
if (importer == null || !importer.isReadable)
|
||||
return null;
|
||||
|
||||
Texture2D texture;
|
||||
if (type == NotificationIconType.Small)
|
||||
{
|
||||
texture = new Texture2D(sourceTexture.width, sourceTexture.height, TextureFormat.RGBA32, true, false);
|
||||
for (var i = 0; i < sourceTexture.mipmapCount; i++)
|
||||
{
|
||||
var c_0 = sourceTexture.GetPixels(i);
|
||||
var c_1 = texture.GetPixels(i);
|
||||
for (var i1 = 0; i1 < c_0.Length; i1++)
|
||||
{
|
||||
var a = c_0[i1].r + c_0[i1].g + c_0[i1].b;
|
||||
c_1[i1].r = c_1[i1].g = c_1[i1].b = a > 127 ? 0 : 1;
|
||||
c_1[i1].a = c_0[i1].a;
|
||||
}
|
||||
texture.SetPixels(c_1, i);
|
||||
}
|
||||
texture.Apply();
|
||||
}
|
||||
else
|
||||
{
|
||||
texture = new Texture2D(sourceTexture.width, sourceTexture.height, TextureFormat.RGBA32, true);
|
||||
texture.SetPixels(sourceTexture.GetPixels());
|
||||
texture.Apply();
|
||||
}
|
||||
return texture;
|
||||
}
|
||||
|
||||
public static Texture2D ScaleTexture(Texture2D sourceTexture, int width, int height)
|
||||
{
|
||||
if (sourceTexture.width == width && sourceTexture.height == height)
|
||||
return sourceTexture;
|
||||
|
||||
var result = new Texture2D(width, height, TextureFormat.ARGB32, false);
|
||||
|
||||
var destPixels = new Color[width * height];
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
for (int x = 0; x < width; ++x)
|
||||
{
|
||||
destPixels[y * width + x] = sourceTexture.GetPixelBilinear((float)x / (float)width, (float)y / (float)height);
|
||||
}
|
||||
}
|
||||
result.SetPixels(destPixels);
|
||||
result.Apply();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
Executable
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5b9bfb8ad48d04ce5af3878b61cb8904
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Vendored
Executable
+18
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "Unity.Notifications",
|
||||
"references": [
|
||||
"Unity.Notifications.iOS",
|
||||
"Unity.Notifications.Android"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
Vendored
Executable
+7
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85a7f7b2e1fe24ff2b4c8b5d1a746334
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Vendored
Executable
+18
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
|
||||
namespace Unity.Notifications
|
||||
{
|
||||
[Flags]
|
||||
internal enum iOSAuthorizationOption
|
||||
{
|
||||
Default = 0,
|
||||
Badge = 1 << 0,
|
||||
Sound = 1 << 1,
|
||||
Alert = 1 << 2,
|
||||
CarPlay = 1 << 3,
|
||||
CriticalAlert = 1 << 4,
|
||||
ProvidesAppNotificationSettings = 1 << 5,
|
||||
Provisional = 1 << 6,
|
||||
All = ~0,
|
||||
}
|
||||
}
|
||||
Vendored
Executable
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 396d27f7ef9dc419ab240e8ea0135a26
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Vendored
Executable
+214
@@ -0,0 +1,214 @@
|
||||
#if UNITY_IOS
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Callbacks;
|
||||
using UnityEditor.iOS.Xcode;
|
||||
using UnityEngine;
|
||||
using Unity.Notifications;
|
||||
using Unity.Notifications.iOS;
|
||||
|
||||
public class iOSNotificationPostProcessor : MonoBehaviour
|
||||
{
|
||||
[PostProcessBuild]
|
||||
public static void OnPostprocessBuild(BuildTarget buildTarget, string path)
|
||||
{
|
||||
if (buildTarget != BuildTarget.iOS)
|
||||
return;
|
||||
|
||||
// Check if we have the minimal iOS version set.
|
||||
bool hasMinOSVersion;
|
||||
try
|
||||
{
|
||||
var requiredVersion = new Version(10, 0);
|
||||
var currentVersion = new Version(PlayerSettings.iOS.targetOSVersionString);
|
||||
hasMinOSVersion = currentVersion >= requiredVersion;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
hasMinOSVersion = false;
|
||||
}
|
||||
|
||||
if (!hasMinOSVersion)
|
||||
Debug.Log("UserNotifications framework is only available on iOS 10.0+, please make sure that you set a correct `Target minimum iOS Version` in Player Settings.");
|
||||
|
||||
var settings = NotificationSettingsManager.Initialize().iOSNotificationSettingsFlat;
|
||||
|
||||
var needLocationFramework = (bool)settings.Find(i => i.Key == NotificationSettings.iOSSettings.USE_LOCATION_TRIGGER).Value;
|
||||
var addPushNotificationCapability = (bool)settings.Find(i => i.Key == NotificationSettings.iOSSettings.ADD_PUSH_CAPABILITY).Value;
|
||||
var addTimeSensitiveEntitlement = (bool)settings.Find(i => i.Key == NotificationSettings.iOSSettings.ADD_TIME_SENSITIVE_ENTITLEMENT).Value;
|
||||
|
||||
var useReleaseAPSEnv = false;
|
||||
if (addPushNotificationCapability)
|
||||
{
|
||||
var useReleaseAPSEnvSetting = settings.Find(i => i.Key == NotificationSettings.iOSSettings.USE_APS_RELEASE);
|
||||
if (useReleaseAPSEnvSetting != null)
|
||||
useReleaseAPSEnv = (bool)useReleaseAPSEnvSetting.Value;
|
||||
}
|
||||
|
||||
PatchPBXProject(path, needLocationFramework, addPushNotificationCapability, useReleaseAPSEnv, addTimeSensitiveEntitlement);
|
||||
PatchPlist(path, settings, addPushNotificationCapability);
|
||||
PatchPreprocessor(path, needLocationFramework, addPushNotificationCapability);
|
||||
}
|
||||
|
||||
private static void PatchPBXProject(string path, bool needLocationFramework, bool addPushNotificationCapability, bool useReleaseAPSEnv, bool addTimeSensitiveEntitlement)
|
||||
{
|
||||
var pbxProjectPath = PBXProject.GetPBXProjectPath(path);
|
||||
|
||||
var needsToWriteChanges = false;
|
||||
|
||||
var pbxProject = new PBXProject();
|
||||
pbxProject.ReadFromString(File.ReadAllText(pbxProjectPath));
|
||||
|
||||
string mainTarget;
|
||||
string unityFrameworkTarget;
|
||||
|
||||
var unityMainTargetGuidMethod = pbxProject.GetType().GetMethod("GetUnityMainTargetGuid");
|
||||
var unityFrameworkTargetGuidMethod = pbxProject.GetType().GetMethod("GetUnityFrameworkTargetGuid");
|
||||
|
||||
if (unityMainTargetGuidMethod != null && unityFrameworkTargetGuidMethod != null)
|
||||
{
|
||||
mainTarget = (string)unityMainTargetGuidMethod.Invoke(pbxProject, null);
|
||||
unityFrameworkTarget = (string)unityFrameworkTargetGuidMethod.Invoke(pbxProject, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
mainTarget = pbxProject.TargetGuidByName("Unity-iPhone");
|
||||
unityFrameworkTarget = mainTarget;
|
||||
}
|
||||
|
||||
// Add necessary frameworks.
|
||||
if (!pbxProject.ContainsFramework(unityFrameworkTarget, "UserNotifications.framework"))
|
||||
{
|
||||
pbxProject.AddFrameworkToProject(unityFrameworkTarget, "UserNotifications.framework", true);
|
||||
needsToWriteChanges = true;
|
||||
}
|
||||
if (needLocationFramework && !pbxProject.ContainsFramework(unityFrameworkTarget, "CoreLocation.framework"))
|
||||
{
|
||||
pbxProject.AddFrameworkToProject(unityFrameworkTarget, "CoreLocation.framework", false);
|
||||
needsToWriteChanges = true;
|
||||
}
|
||||
|
||||
if (needsToWriteChanges)
|
||||
File.WriteAllText(pbxProjectPath, pbxProject.WriteToString());
|
||||
|
||||
var entitlementsFileName = pbxProject.GetBuildPropertyForAnyConfig(mainTarget, "CODE_SIGN_ENTITLEMENTS");
|
||||
if (entitlementsFileName == null)
|
||||
{
|
||||
var bundleIdentifier = PlayerSettings.GetApplicationIdentifier(BuildTargetGroup.iOS);
|
||||
entitlementsFileName = string.Format("{0}.entitlements", bundleIdentifier.Substring(bundleIdentifier.LastIndexOf(".") + 1));
|
||||
}
|
||||
|
||||
// Update the entitlements file.
|
||||
if (addPushNotificationCapability)
|
||||
{
|
||||
var capManager = new ProjectCapabilityManager(pbxProjectPath, entitlementsFileName, "Unity-iPhone");
|
||||
capManager.AddPushNotifications(!useReleaseAPSEnv);
|
||||
capManager.WriteToFile();
|
||||
}
|
||||
|
||||
if (addTimeSensitiveEntitlement)
|
||||
{
|
||||
var entitlementsFile = new PlistDocument();
|
||||
var entitlementsFilePath = Path.Combine(path, entitlementsFileName);
|
||||
if (File.Exists(entitlementsFilePath))
|
||||
entitlementsFile.ReadFromFile(entitlementsFilePath);
|
||||
var entitlement = entitlementsFile.root["com.apple.developer.usernotifications.time-sensitive"] as PlistElementBoolean;
|
||||
if (entitlement == null || entitlement.AsBoolean() == false)
|
||||
{
|
||||
entitlementsFile.root["com.apple.developer.usernotifications.time-sensitive"] = new PlistElementBoolean(true);
|
||||
entitlementsFile.WriteToFile(entitlementsFilePath);
|
||||
}
|
||||
if (pbxProject.GetBuildPropertyForAnyConfig(mainTarget, "CODE_SIGN_ENTITLEMENTS") == null)
|
||||
{
|
||||
pbxProject.AddBuildProperty(mainTarget, "CODE_SIGN_ENTITLEMENTS", entitlementsFileName);
|
||||
pbxProject.WriteToFile(pbxProjectPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void PatchPlist(string path, List<Unity.Notifications.NotificationSetting> settings, bool addPushNotificationCapability)
|
||||
{
|
||||
var plistPath = path + "/Info.plist";
|
||||
var plist = new PlistDocument();
|
||||
plist.ReadFromString(File.ReadAllText(plistPath));
|
||||
|
||||
var rootDict = plist.root;
|
||||
var needsToWriteChanges = false;
|
||||
|
||||
// Add all the settings to the plist.
|
||||
foreach (var setting in settings)
|
||||
{
|
||||
if (ShouldAddSettingToPlist(setting, rootDict))
|
||||
{
|
||||
needsToWriteChanges = true;
|
||||
if (setting.Value.GetType() == typeof(bool))
|
||||
{
|
||||
rootDict.SetBoolean(setting.Key, (bool)setting.Value);
|
||||
}
|
||||
else if (setting.Value.GetType() == typeof(PresentationOption) ||
|
||||
setting.Value.GetType() == typeof(AuthorizationOption))
|
||||
{
|
||||
rootDict.SetInteger(setting.Key, (int)setting.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add "remote-notification" to the list of supported UIBackgroundModes.
|
||||
if (addPushNotificationCapability)
|
||||
{
|
||||
PlistElementArray currentBackgroundModes = (PlistElementArray)rootDict["UIBackgroundModes"];
|
||||
if (currentBackgroundModes == null)
|
||||
currentBackgroundModes = rootDict.CreateArray("UIBackgroundModes");
|
||||
|
||||
var remoteNotificationElement = new PlistElementString("remote-notification");
|
||||
if (!currentBackgroundModes.values.Contains(remoteNotificationElement))
|
||||
{
|
||||
currentBackgroundModes.values.Add(remoteNotificationElement);
|
||||
needsToWriteChanges = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (needsToWriteChanges)
|
||||
File.WriteAllText(plistPath, plist.WriteToString());
|
||||
}
|
||||
|
||||
// If the plist doesn't contain the key, or it's value is different, we should add/overwrite it.
|
||||
private static bool ShouldAddSettingToPlist(Unity.Notifications.NotificationSetting setting,
|
||||
PlistElementDict rootDict)
|
||||
{
|
||||
if (!rootDict.values.ContainsKey(setting.Key))
|
||||
return true;
|
||||
else if (setting.Value.GetType() == typeof(bool))
|
||||
return !rootDict.values[setting.Key].AsBoolean().Equals((bool)setting.Value);
|
||||
else if (setting.Value.GetType() == typeof(PresentationOption) || setting.Value.GetType() == typeof(AuthorizationOption))
|
||||
return !rootDict.values[setting.Key].AsInteger().Equals((int)setting.Value);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void PatchPreprocessor(string path, bool needLocationFramework, bool addPushNotificationCapability)
|
||||
{
|
||||
var preprocessorPath = path + "/Classes/Preprocessor.h";
|
||||
var preprocessor = File.ReadAllText(preprocessorPath);
|
||||
var needsToWriteChanges = false;
|
||||
|
||||
if (needLocationFramework && preprocessor.Contains("UNITY_USES_LOCATION"))
|
||||
{
|
||||
preprocessor = preprocessor.Replace("UNITY_USES_LOCATION 0", "UNITY_USES_LOCATION 1");
|
||||
needsToWriteChanges = true;
|
||||
}
|
||||
|
||||
if (addPushNotificationCapability && preprocessor.Contains("UNITY_USES_REMOTE_NOTIFICATIONS"))
|
||||
{
|
||||
preprocessor =
|
||||
preprocessor.Replace("UNITY_USES_REMOTE_NOTIFICATIONS 0", "UNITY_USES_REMOTE_NOTIFICATIONS 1");
|
||||
needsToWriteChanges = true;
|
||||
}
|
||||
|
||||
if (needsToWriteChanges)
|
||||
File.WriteAllText(preprocessorPath, preprocessor);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user