提交修改

This commit is contained in:
changyunjia
2026-06-09 15:16:52 +08:00
co-authored by changyunjia
parent d4442fc21f
commit 3ac4fe0cd0
330 changed files with 48115 additions and 36763 deletions
+231 -231
View File
@@ -1,231 +1,231 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Newtonsoft.Json;
using MYp0ZVTT2QSDK;
using UnityEngine;
using UnityEngine.UI;
using Random = UnityEngine.Random;
public class MYp0ZVTT2QSDKDemo : MonoBehaviour
{
public void ShowReward()
{
MYp0ZVTT2QSDKHelper.Instance.ShowRewardVideo("TAG", b =>
{
Debug.LogError($"reward result = {b}");
},(() =>
{
Debug.LogError($"reward close!!!");
}));
}
public void ShowInter()
{
MYp0ZVTT2QSDKHelper.Instance.ShowInter("TAG", () =>
{
Debug.LogError("inter hide");
});
}
public void ShowAdmobInter()
{
MYp0ZVTT2QSDKHelper.Instance.ShowAdmobInter("TAG", () =>
{
Debug.LogError("inter hide");
});
}
public void ShowSplash()
{
MYp0ZVTT2QSDKHelper.Instance.ShowSplash();
}
public void CheckReward(Image btnImg)
{
var isReady = MYp0ZVTT2QSDKHelper.Instance.IsVideoReady();
btnImg.color = isReady ? Color.green : Color.white;
Debug.Log($"Reward : {isReady}");
}
public void CheckInter(Image btnImg)
{
var isReady = MYp0ZVTT2QSDKHelper.Instance.IsInterReady();
btnImg.color = isReady ? Color.green : Color.white;
Debug.Log($"Inter : {isReady}");
}
public void CheckSplash(Image btnImg)
{
var isReady = MYp0ZVTT2QSDKHelper.Instance.IsSplashReady();
btnImg.color = isReady ? Color.green : Color.white;
Debug.Log($"Splash : {isReady}");
}
public void Track()
{
MYp0ZVTT2QSDKHelper.Instance.Track("test", new Dictionary<string, string>()
{
{"evt1", "1"},
{"evt2", "2"},
{"evt3", "3"},
{"evt4", "4"},
{"evt5", "5"},
{"evt6", "6"},
{"evt7", "7"},
{"evt8", "8"},
{"evt9", "9"},
});
}
public void GetCountryCode()
{
var code = MYp0ZVTT2QSDKHelper.Instance.GetCountryCode();
Debug.Log($"country : {code}");
}
public void ShowH5()
{
MYp0ZVTT2QSDKHelper.Instance.H5.ShowH5((() =>
{
Debug.Log("H5 close");
}), () =>
{
Debug.Log($"H5 show failed!");
});
}
public void ShowH5(RectTransform rectTransform)
{
MYp0ZVTT2QSDKHelper.Instance.H5.ShowH5(rectTransform);
}
public void HideH5()
{
MYp0ZVTT2QSDKHelper.Instance.H5.HideH5();
}
public void CheckShowH5(Image btnImg)
{
var show = MYp0ZVTT2QSDKHelper.Instance.H5.IsShowH5();
btnImg.color = show ? Color.green : Color.red;
Debug.Log($"CheckShowH5 : {show}");
}
private int _level = 1;
public void TrackLevel()
{
MYp0ZVTT2QSDKHelper.Instance.TrackLevelUp(_level);
if (Random.Range(0, 100) < 50)
{
_level++;
}
}
private string withDrawSceneId = "";
public void GetWithDrawConfigs()
{
MYp0ZVTT2QSDKHelper.Instance.GetWithDrawConfigs(((b, s) =>
{
Debug.Log($"GetWithDrawConfigs result : {b}, data : {s}");
if (b)
{
var cfgs = JsonConvert.DeserializeObject<List<WithDrawConfig>>(s);
int idx = 0;
foreach (WithDrawConfig config in cfgs)
{
Debug.Log($"index = {idx}, {config.ToString()}");
if (idx == 0)
withDrawSceneId = config.SecneId;
idx++;
}
}
}));
}
private int payIndex = 0;
public void CreateWithDrawOrder()
{
string taxNo = "";
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;
MYp0ZVTT2QSDKHelper.Instance.CreateWithDrawOrder(withDrawSceneId, payCode, payAccount, accountType, "testName", taxNo, b =>
{
Debug.Log($"CreateWithDrawOrder result : {b}");
});
payIndex++;
payIndex = payIndex > 3 ? 0 : payIndex;
}
public void GetWithDrawOrders()
{
MYp0ZVTT2QSDKHelper.Instance.GetWithDrawOrders(((b, s) =>
{
Debug.Log($"GetWithDrawOrders result : {b}, data : {s}");
if (b)
{
var cfgs = JsonConvert.DeserializeObject<List<WithDrawOrder>>(s);
int idx = 0;
foreach (WithDrawOrder config in cfgs)
{
Debug.Log($"index = {idx}, {config.ToString()}");
idx++;
}
}
}));
}
// Start is called before the first frame update
void Start()
{
Init();
Invoke("ShowSplash", 5);
}
// Update is called once per frame
void Update()
{
}
private void Init()
{
MYp0ZVTT2QSDKHelper.Instance.RegistIosParam((i =>
{
Debug.Log($"ios ab param : {i}");
}));
void GameConfig(bool result, string config)
{
Debug.Log($"************* game config result : {result}, config : {config}");
}
MYp0ZVTT2QSDKHelper.Instance.Init(null, "app_config", GameConfig);
}
public static string GetSdkVersion()
{
return MYp0ZVTT2QSDKHelper.SdkVersion;
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using Newtonsoft.Json;
using MYp0ZVTT2QSDK;
using UnityEngine;
using UnityEngine.UI;
using Random = UnityEngine.Random;
public class MYp0ZVTT2QSDKDemo : MonoBehaviour
{
public void ShowReward()
{
MYp0ZVTT2QSDKHelper.Instance.ShowRewardVideo("TAG", b =>
{
Debug.LogError($"reward result = {b}");
},(() =>
{
Debug.LogError($"reward close!!!");
}));
}
public void ShowInter()
{
MYp0ZVTT2QSDKHelper.Instance.ShowInter("TAG", () =>
{
Debug.LogError("inter hide");
});
}
public void ShowAdmobInter()
{
MYp0ZVTT2QSDKHelper.Instance.ShowAdmobInter("TAG", () =>
{
Debug.LogError("inter hide");
});
}
public void ShowSplash()
{
MYp0ZVTT2QSDKHelper.Instance.ShowSplash();
}
public void CheckReward(Image btnImg)
{
var isReady = MYp0ZVTT2QSDKHelper.Instance.IsVideoReady();
btnImg.color = isReady ? Color.green : Color.white;
Debug.Log($"Reward : {isReady}");
}
public void CheckInter(Image btnImg)
{
var isReady = MYp0ZVTT2QSDKHelper.Instance.IsInterReady();
btnImg.color = isReady ? Color.green : Color.white;
Debug.Log($"Inter : {isReady}");
}
public void CheckSplash(Image btnImg)
{
var isReady = MYp0ZVTT2QSDKHelper.Instance.IsSplashReady();
btnImg.color = isReady ? Color.green : Color.white;
Debug.Log($"Splash : {isReady}");
}
public void Track()
{
MYp0ZVTT2QSDKHelper.Instance.Track("test", new Dictionary<string, string>()
{
{"evt1", "1"},
{"evt2", "2"},
{"evt3", "3"},
{"evt4", "4"},
{"evt5", "5"},
{"evt6", "6"},
{"evt7", "7"},
{"evt8", "8"},
{"evt9", "9"},
});
}
public void GetCountryCode()
{
var code = MYp0ZVTT2QSDKHelper.Instance.GetCountryCode();
Debug.Log($"country : {code}");
}
public void ShowH5()
{
MYp0ZVTT2QSDKHelper.Instance.H5.ShowH5((() =>
{
Debug.Log("H5 close");
}), () =>
{
Debug.Log($"H5 show failed!");
});
}
public void ShowH5(RectTransform rectTransform)
{
MYp0ZVTT2QSDKHelper.Instance.H5.ShowH5(rectTransform);
}
public void HideH5()
{
MYp0ZVTT2QSDKHelper.Instance.H5.HideH5();
}
public void CheckShowH5(Image btnImg)
{
var show = MYp0ZVTT2QSDKHelper.Instance.H5.IsShowH5();
btnImg.color = show ? Color.green : Color.red;
Debug.Log($"CheckShowH5 : {show}");
}
private int _level = 1;
public void TrackLevel()
{
MYp0ZVTT2QSDKHelper.Instance.TrackLevelUp(_level);
if (Random.Range(0, 100) < 50)
{
_level++;
}
}
private string withDrawSceneId = "";
public void GetWithDrawConfigs()
{
MYp0ZVTT2QSDKHelper.Instance.GetWithDrawConfigs(((b, s) =>
{
Debug.Log($"GetWithDrawConfigs result : {b}, data : {s}");
if (b)
{
var cfgs = JsonConvert.DeserializeObject<List<WithDrawConfig>>(s);
int idx = 0;
foreach (WithDrawConfig config in cfgs)
{
Debug.Log($"index = {idx}, {config.ToString()}");
if (idx == 0)
withDrawSceneId = config.SecneId;
idx++;
}
}
}));
}
private int payIndex = 0;
public void CreateWithDrawOrder()
{
string taxNo = "";
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;
MYp0ZVTT2QSDKHelper.Instance.CreateWithDrawOrder(withDrawSceneId, payCode, payAccount, accountType, "testName", taxNo, b =>
{
Debug.Log($"CreateWithDrawOrder result : {b}");
});
payIndex++;
payIndex = payIndex > 3 ? 0 : payIndex;
}
public void GetWithDrawOrders()
{
MYp0ZVTT2QSDKHelper.Instance.GetWithDrawOrders(((b, s) =>
{
Debug.Log($"GetWithDrawOrders result : {b}, data : {s}");
if (b)
{
var cfgs = JsonConvert.DeserializeObject<List<WithDrawOrder>>(s);
int idx = 0;
foreach (WithDrawOrder config in cfgs)
{
Debug.Log($"index = {idx}, {config.ToString()}");
idx++;
}
}
}));
}
// Start is called before the first frame update
void Start()
{
Init();
Invoke("ShowSplash", 5);
}
// Update is called once per frame
void Update()
{
}
private void Init()
{
MYp0ZVTT2QSDKHelper.Instance.RegistIosParam((i =>
{
Debug.Log($"ios ab param : {i}");
}));
void GameConfig(bool result, string config)
{
Debug.Log($"************* game config result : {result}, config : {config}");
}
MYp0ZVTT2QSDKHelper.Instance.Init(null, "app_config", GameConfig);
}
public static string GetSdkVersion()
{
return MYp0ZVTT2QSDKHelper.SdkVersion;
}
}
+11 -11
View File
@@ -1,11 +1,11 @@
fileFormatVersion: 2
guid: 959ec24a7131c9d488e5007fa82612be
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 959ec24a7131c9d488e5007fa82612be
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+653 -653
View File
File diff suppressed because it is too large Load Diff
View File
+16 -16
View File
@@ -1,17 +1,17 @@
package com.tool.countrycode;
import android.app.Activity;
import java.util.Locale;
public class AcquireCountryCode {
// 获取国家码
public static String getCountryCode()
{
Locale locale = Locale.getDefault();
return locale.getCountry();
}
public static String getCountryCode3() {
Locale currentLocale = Locale.getDefault();
return currentLocale.getISO3Country();
}
package com.tool.countrycode;
import android.app.Activity;
import java.util.Locale;
public class AcquireCountryCode {
// 获取国家码
public static String getCountryCode()
{
Locale locale = Locale.getDefault();
return locale.getCountry();
}
public static String getCountryCode3() {
Locale currentLocale = Locale.getDefault();
return currentLocale.getISO3Country();
}
}
View File
View File
+33 -33
View File
@@ -1,33 +1,33 @@
fileFormatVersion: 2
guid: 6e3da5c7fe21c1347a563e64e8f305d4
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 6e3da5c7fe21c1347a563e64e8f305d4
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
View File
View File
+12 -12
View File
@@ -1,12 +1,12 @@
#import <Foundation/Foundation.h>
extern "C" {
__attribute__((visibility("default")))
const char* _GetDeviceCountryCode() {
@autoreleasepool {
NSLocale *currentLocale = [NSLocale currentLocale];
NSString *countryCode = [currentLocale objectForKey:NSLocaleCountryCode];
return strdup([countryCode UTF8String]); // 使用strdup确保内存安全
}
}
}
#import <Foundation/Foundation.h>
extern "C" {
__attribute__((visibility("default")))
const char* _GetDeviceCountryCode() {
@autoreleasepool {
NSLocale *currentLocale = [NSLocale currentLocale];
NSString *countryCode = [currentLocale objectForKey:NSLocaleCountryCode];
return strdup([countryCode UTF8String]); // 使用strdup确保内存安全
}
}
}
View File
+13 -13
View File
@@ -1,14 +1,14 @@
{
"name": "SDKConfig",
"rootNamespace": "",
"references": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
{
"name": "SDKConfig",
"rootNamespace": "",
"references": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
+7 -7
View File
@@ -1,7 +1,7 @@
fileFormatVersion: 2
guid: 8b6da46957b38914aa097a61bd86a16d
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 8b6da46957b38914aa097a61bd86a16d
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+234 -234
View File
@@ -1,234 +1,234 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MYp0ZVTT2QSDK
{
[System.Serializable]
public class SDKConfig : ScriptableObject
{
public string appsFlyerDevKey;
public string appsFlyerIosAppleAppId;
public string appKey;
public string appSecret;
public string logReportUrl;
public string maxAppKey;
public string splashUnitId;
public string bannerUnitId;
public string interUnitId;
public string videoUnitId;
public string kwaiAppId;
public List<string> kwaiVideoUnitId = new();
public List<string> kwaiInterUnitId = new();
public string bigoAppId;
public List<string> bigoVideoUnitId = new();
public List<string> bigoInterUnitId = new();
public string bigoSplashUnitId;
public string toponAppId;
public string toponAppkey;
public string toponVideoUnitId;
public string toponInterUnitId;
public string admobAppId;
public string admobVideoUnitId;
public string admobInterUnitId;
public string admobSplashUnitId;
public bool isDebug = false;
public bool isPrintLog = false;
public bool isUseAdmobSplash = false;
private static SDKConfig _instance;
public static SDKConfig Instance
{
get
{
if (_instance != null) return _instance;
_instance = AssetUtils.GetScriptableObject<SDKConfig>(typeof(SDKConfig).Name, "Assets/Resources", false, false);
return _instance;
}
set
{
_instance = value;
}
}
public static string AppsFlyerDevKey
{
get { return Instance.appsFlyerDevKey; }
}
public static string AppsFlyerIosAppleAppId
{
get { return Instance.appsFlyerIosAppleAppId; }
}
public static string AppKey
{
get { return Instance.appKey; }
}
public static string AppSecret
{
get { return Instance.appSecret; }
}
public static string LogReportUrl
{
get
{
if (!Instance.logReportUrl.StartsWith("http"))
{
return "https://" + Instance.logReportUrl.Replace(" ", ""); ;
}
return Instance.logReportUrl.Replace(" ", ""); ;
}
}
public static string MaxAppKey
{
get { return Instance.maxAppKey; }
}
public static string SplashUnitID
{
get { return Instance.splashUnitId; }
}
public static string BannerUnitId
{
get { return Instance.bannerUnitId; }
}
public static string InterUnitId
{
get { return Instance.interUnitId; }
}
public static string VideoUnitId
{
get { return Instance.videoUnitId; }
}
public static string KwaiAppId
{
get => Instance.kwaiAppId;
set => Instance.kwaiAppId = value;
}
public static List<string> KwaiVideoUnitId
{
get => Instance.kwaiVideoUnitId;
set => Instance.kwaiVideoUnitId = value;
}
public static List<string> KwaiInterUnitId
{
get => Instance.kwaiInterUnitId;
set => Instance.kwaiInterUnitId = value;
}
public static string BigoAppId
{
get => Instance.bigoAppId;
set => Instance.bigoAppId = value;
}
public static List<string> BigoVideoUnitId
{
get => Instance.bigoVideoUnitId;
set => Instance.bigoVideoUnitId = value;
}
public static List<string> BigoInterUnitId
{
get => Instance.bigoInterUnitId;
set => Instance.bigoInterUnitId = value;
}
public static string BigoSplashUnitId
{
get => Instance.bigoSplashUnitId;
set => Instance.bigoSplashUnitId = value;
}
public static string ToponAppId
{
get { return Instance.toponAppId; }
}
public static string ToponAppkey
{
get { return Instance.toponAppkey; }
}
public static string ToponVideoUnitId
{
get { return Instance.toponVideoUnitId; }
}
public static string ToponInterUnitId
{
get { return Instance.toponInterUnitId; }
}
public static string AdmobAppId
{
get => Instance.admobAppId;
set => Instance.admobAppId = value;
}
public static string AdmobVideoUnitId
{
get => Instance.admobVideoUnitId;
set => Instance.admobVideoUnitId = value;
}
public static string AdmobSplashUnitId
{
get => Instance.admobSplashUnitId;
set => Instance.admobSplashUnitId = value;
}
public static string AdmobInterUnitId
{
get => Instance.admobInterUnitId;
set => Instance.admobInterUnitId = value;
}
public static bool IsDebug => Instance.isDebug;
public static bool IsPrintLog => Instance.isPrintLog;
public static bool IsUseAdmobSplash => Instance.isUseAdmobSplash;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MYp0ZVTT2QSDK
{
[System.Serializable]
public class SDKConfig : ScriptableObject
{
public string appsFlyerDevKey;
public string appsFlyerIosAppleAppId;
public string appKey;
public string appSecret;
public string logReportUrl;
public string maxAppKey;
public string splashUnitId;
public string bannerUnitId;
public string interUnitId;
public string videoUnitId;
public string kwaiAppId;
public List<string> kwaiVideoUnitId = new();
public List<string> kwaiInterUnitId = new();
public string bigoAppId;
public List<string> bigoVideoUnitId = new();
public List<string> bigoInterUnitId = new();
public string bigoSplashUnitId;
public string toponAppId;
public string toponAppkey;
public string toponVideoUnitId;
public string toponInterUnitId;
public string admobAppId;
public string admobVideoUnitId;
public string admobInterUnitId;
public string admobSplashUnitId;
public bool isDebug = false;
public bool isPrintLog = false;
public bool isUseAdmobSplash = false;
private static SDKConfig _instance;
public static SDKConfig Instance
{
get
{
if (_instance != null) return _instance;
_instance = AssetUtils.GetScriptableObject<SDKConfig>(typeof(SDKConfig).Name, "Assets/Resources", false, false);
return _instance;
}
set
{
_instance = value;
}
}
public static string AppsFlyerDevKey
{
get { return Instance.appsFlyerDevKey; }
}
public static string AppsFlyerIosAppleAppId
{
get { return Instance.appsFlyerIosAppleAppId; }
}
public static string AppKey
{
get { return Instance.appKey; }
}
public static string AppSecret
{
get { return Instance.appSecret; }
}
public static string LogReportUrl
{
get
{
if (!Instance.logReportUrl.StartsWith("http"))
{
return "https://" + Instance.logReportUrl.Replace(" ", ""); ;
}
return Instance.logReportUrl.Replace(" ", ""); ;
}
}
public static string MaxAppKey
{
get { return Instance.maxAppKey; }
}
public static string SplashUnitID
{
get { return Instance.splashUnitId; }
}
public static string BannerUnitId
{
get { return Instance.bannerUnitId; }
}
public static string InterUnitId
{
get { return Instance.interUnitId; }
}
public static string VideoUnitId
{
get { return Instance.videoUnitId; }
}
public static string KwaiAppId
{
get => Instance.kwaiAppId;
set => Instance.kwaiAppId = value;
}
public static List<string> KwaiVideoUnitId
{
get => Instance.kwaiVideoUnitId;
set => Instance.kwaiVideoUnitId = value;
}
public static List<string> KwaiInterUnitId
{
get => Instance.kwaiInterUnitId;
set => Instance.kwaiInterUnitId = value;
}
public static string BigoAppId
{
get => Instance.bigoAppId;
set => Instance.bigoAppId = value;
}
public static List<string> BigoVideoUnitId
{
get => Instance.bigoVideoUnitId;
set => Instance.bigoVideoUnitId = value;
}
public static List<string> BigoInterUnitId
{
get => Instance.bigoInterUnitId;
set => Instance.bigoInterUnitId = value;
}
public static string BigoSplashUnitId
{
get => Instance.bigoSplashUnitId;
set => Instance.bigoSplashUnitId = value;
}
public static string ToponAppId
{
get { return Instance.toponAppId; }
}
public static string ToponAppkey
{
get { return Instance.toponAppkey; }
}
public static string ToponVideoUnitId
{
get { return Instance.toponVideoUnitId; }
}
public static string ToponInterUnitId
{
get { return Instance.toponInterUnitId; }
}
public static string AdmobAppId
{
get => Instance.admobAppId;
set => Instance.admobAppId = value;
}
public static string AdmobVideoUnitId
{
get => Instance.admobVideoUnitId;
set => Instance.admobVideoUnitId = value;
}
public static string AdmobSplashUnitId
{
get => Instance.admobSplashUnitId;
set => Instance.admobSplashUnitId = value;
}
public static string AdmobInterUnitId
{
get => Instance.admobInterUnitId;
set => Instance.admobInterUnitId = value;
}
public static bool IsDebug => Instance.isDebug;
public static bool IsPrintLog => Instance.isPrintLog;
public static bool IsUseAdmobSplash => Instance.isUseAdmobSplash;
}
}
View File
+152 -152
View File
@@ -1,152 +1,152 @@
using System;
using System.IO;
using UnityEngine;
#if UNITY_EDITOR
using System.Collections.Generic;
using UnityEditor;
#endif
namespace MYp0ZVTT2QSDK
{
public static class AssetUtils
{
/// <summary>
/// Returns a reference to a scriptable object of type T with the given fileName at the relative resourcesPath.
/// <para/> If the asset is not found, one will get created automatically (in the Editor only)
/// </summary>
/// <param name="fileName"></param>
/// <param name="resourcesPath"></param>
/// <param name="saveAssetDatabase"></param>
/// <param name="refreshAssetDatabase"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T GetScriptableObject<T>(string fileName,
string resourcesPath,
bool saveAssetDatabase,
bool refreshAssetDatabase)
where T : ScriptableObject
{
if (string.IsNullOrEmpty(resourcesPath)) return null;
if (string.IsNullOrEmpty(fileName)) return null;
// ReSharper disable once SuspiciousTypeConversion.Global
// if (!resourcesPath[resourcesPath.Length - 1].Equals(@"\")) resourcesPath += @"\";
// resourcesPath = resourcesPath.Replace(@"\", "/");
resourcesPath = CleanPath(resourcesPath);
var obj = (T)Resources.Load(fileName, typeof(T));
if (obj == null)
{
string simpleResourcesPath = resourcesPath.Replace(resourcesPath.Substring(0, resourcesPath.LastIndexOf("Resources", StringComparison.Ordinal)), "");
simpleResourcesPath = simpleResourcesPath.Replace("Resources", "").Remove(0, 1);
obj = (T)Resources.Load(Path.Combine(simpleResourcesPath, fileName), typeof(T));
}
#if UNITY_EDITOR
if (obj != null) return obj;
if (!Directory.Exists("Assets/Resources"))
{
Directory.CreateDirectory("Assets/Resources");
}
obj = CreateAsset<T>(resourcesPath, fileName, ".asset", saveAssetDatabase, refreshAssetDatabase);
#endif
return obj;
}
public static T GetResource<T>(string resourcesPath, string fileName) where T : ScriptableObject
{
if (string.IsNullOrEmpty(resourcesPath)) return null;
if (string.IsNullOrEmpty(fileName)) return null;
resourcesPath = CleanPath(resourcesPath);
// ReSharper disable once SuspiciousTypeConversion.Global
// if (!resourcesPath[resourcesPath.Length - 1].Equals(@"\")) resourcesPath += @"\";
// resourcesPath = resourcesPath.Replace(@"\", "/");
return (T)Resources.Load(resourcesPath + fileName, typeof(T));
}
public static string CleanPath(string path)
{
// ReSharper disable once SuspiciousTypeConversion.Global
if (!path[path.Length - 1].Equals(@"\")) path += @"\";
path = path.Replace(@"\\", @"\");
path = path.Replace(@"\", "/");
return path;
}
#if UNITY_EDITOR
public static T CreateAsset<T>(string relativePath,
string fileName,
string extension = ".asset",
bool saveAssetDatabase = true,
bool refreshAssetDatabase = true)
where T : ScriptableObject
{
if (string.IsNullOrEmpty(relativePath)) return null;
if (string.IsNullOrEmpty(fileName)) return null;
relativePath = CleanPath(relativePath);
// ReSharper disable once SuspiciousTypeConversion.Global
// if (!relativePath[relativePath.Length - 1].Equals(@"\")) relativePath += @"\";
// relativePath = relativePath.Replace(@"\\", @"\");
var asset = ScriptableObject.CreateInstance<T>();
AssetDatabase.CreateAsset(asset, relativePath + fileName + extension);
EditorUtility.SetDirty(asset);
if (saveAssetDatabase) AssetDatabase.SaveAssets();
if (refreshAssetDatabase) AssetDatabase.Refresh();
return asset;
}
public static List<T> GetAssets<T>() where T : ScriptableObject
{
var list = new List<T>();
string[] guids = AssetDatabase.FindAssets("t:" + typeof(T).Name);
foreach (string guid in guids)
{
var asset = AssetDatabase.LoadAssetAtPath<T>(AssetDatabase.GUIDToAssetPath(guid));
if (asset == null) continue;
list.Add(asset);
}
return list;
}
public static void MoveAssetToTrash(string relativePath, string fileName, bool saveAssetDatabase = true,
bool refreshAssetDatabase = true, bool printDebugMessage = true)
{
if (string.IsNullOrEmpty(relativePath)) return;
if (string.IsNullOrEmpty(fileName)) return;
// ReSharper disable once SuspiciousTypeConversion.Global
// if (!relativePath[relativePath.Length - 1].Equals(@"\")) relativePath += @"\";
relativePath = CleanPath(relativePath);
if (!AssetDatabase.MoveAssetToTrash(relativePath + fileName + ".asset")) return;
if (printDebugMessage) Debug.Log("The " + fileName + ".asset file has been moved to trash.");
if (saveAssetDatabase) AssetDatabase.SaveAssets();
if (refreshAssetDatabase) AssetDatabase.Refresh();
}
public static Texture GetTexture(string filePath, string fileName, string fileExtension = ".png")
{
if (string.IsNullOrEmpty(filePath)) return null;
if (string.IsNullOrEmpty(fileName)) return null;
// ReSharper disable once SuspiciousTypeConversion.Global
// if (!filePath[filePath.Length - 1].Equals(@"\")) filePath += @"\";
filePath = CleanPath(filePath);
return AssetDatabase.LoadAssetAtPath<Texture>(filePath + fileName + fileExtension);
}
public static Texture2D GetTexture2D(string filePath, string fileName, string fileExtension = ".png")
{
if (string.IsNullOrEmpty(filePath)) return null;
if (string.IsNullOrEmpty(fileName)) return null;
// ReSharper disable once SuspiciousTypeConversion.Global
// if (!filePath[filePath.Length - 1].Equals(@"\")) filePath += @"\";
filePath = CleanPath(filePath);
return AssetDatabase.LoadAssetAtPath<Texture2D>(filePath + fileName + fileExtension);
}
#endif
}
}
using System;
using System.IO;
using UnityEngine;
#if UNITY_EDITOR
using System.Collections.Generic;
using UnityEditor;
#endif
namespace MYp0ZVTT2QSDK
{
public static class AssetUtils
{
/// <summary>
/// Returns a reference to a scriptable object of type T with the given fileName at the relative resourcesPath.
/// <para/> If the asset is not found, one will get created automatically (in the Editor only)
/// </summary>
/// <param name="fileName"></param>
/// <param name="resourcesPath"></param>
/// <param name="saveAssetDatabase"></param>
/// <param name="refreshAssetDatabase"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T GetScriptableObject<T>(string fileName,
string resourcesPath,
bool saveAssetDatabase,
bool refreshAssetDatabase)
where T : ScriptableObject
{
if (string.IsNullOrEmpty(resourcesPath)) return null;
if (string.IsNullOrEmpty(fileName)) return null;
// ReSharper disable once SuspiciousTypeConversion.Global
// if (!resourcesPath[resourcesPath.Length - 1].Equals(@"\")) resourcesPath += @"\";
// resourcesPath = resourcesPath.Replace(@"\", "/");
resourcesPath = CleanPath(resourcesPath);
var obj = (T)Resources.Load(fileName, typeof(T));
if (obj == null)
{
string simpleResourcesPath = resourcesPath.Replace(resourcesPath.Substring(0, resourcesPath.LastIndexOf("Resources", StringComparison.Ordinal)), "");
simpleResourcesPath = simpleResourcesPath.Replace("Resources", "").Remove(0, 1);
obj = (T)Resources.Load(Path.Combine(simpleResourcesPath, fileName), typeof(T));
}
#if UNITY_EDITOR
if (obj != null) return obj;
if (!Directory.Exists("Assets/Resources"))
{
Directory.CreateDirectory("Assets/Resources");
}
obj = CreateAsset<T>(resourcesPath, fileName, ".asset", saveAssetDatabase, refreshAssetDatabase);
#endif
return obj;
}
public static T GetResource<T>(string resourcesPath, string fileName) where T : ScriptableObject
{
if (string.IsNullOrEmpty(resourcesPath)) return null;
if (string.IsNullOrEmpty(fileName)) return null;
resourcesPath = CleanPath(resourcesPath);
// ReSharper disable once SuspiciousTypeConversion.Global
// if (!resourcesPath[resourcesPath.Length - 1].Equals(@"\")) resourcesPath += @"\";
// resourcesPath = resourcesPath.Replace(@"\", "/");
return (T)Resources.Load(resourcesPath + fileName, typeof(T));
}
public static string CleanPath(string path)
{
// ReSharper disable once SuspiciousTypeConversion.Global
if (!path[path.Length - 1].Equals(@"\")) path += @"\";
path = path.Replace(@"\\", @"\");
path = path.Replace(@"\", "/");
return path;
}
#if UNITY_EDITOR
public static T CreateAsset<T>(string relativePath,
string fileName,
string extension = ".asset",
bool saveAssetDatabase = true,
bool refreshAssetDatabase = true)
where T : ScriptableObject
{
if (string.IsNullOrEmpty(relativePath)) return null;
if (string.IsNullOrEmpty(fileName)) return null;
relativePath = CleanPath(relativePath);
// ReSharper disable once SuspiciousTypeConversion.Global
// if (!relativePath[relativePath.Length - 1].Equals(@"\")) relativePath += @"\";
// relativePath = relativePath.Replace(@"\\", @"\");
var asset = ScriptableObject.CreateInstance<T>();
AssetDatabase.CreateAsset(asset, relativePath + fileName + extension);
EditorUtility.SetDirty(asset);
if (saveAssetDatabase) AssetDatabase.SaveAssets();
if (refreshAssetDatabase) AssetDatabase.Refresh();
return asset;
}
public static List<T> GetAssets<T>() where T : ScriptableObject
{
var list = new List<T>();
string[] guids = AssetDatabase.FindAssets("t:" + typeof(T).Name);
foreach (string guid in guids)
{
var asset = AssetDatabase.LoadAssetAtPath<T>(AssetDatabase.GUIDToAssetPath(guid));
if (asset == null) continue;
list.Add(asset);
}
return list;
}
public static void MoveAssetToTrash(string relativePath, string fileName, bool saveAssetDatabase = true,
bool refreshAssetDatabase = true, bool printDebugMessage = true)
{
if (string.IsNullOrEmpty(relativePath)) return;
if (string.IsNullOrEmpty(fileName)) return;
// ReSharper disable once SuspiciousTypeConversion.Global
// if (!relativePath[relativePath.Length - 1].Equals(@"\")) relativePath += @"\";
relativePath = CleanPath(relativePath);
if (!AssetDatabase.MoveAssetToTrash(relativePath + fileName + ".asset")) return;
if (printDebugMessage) Debug.Log("The " + fileName + ".asset file has been moved to trash.");
if (saveAssetDatabase) AssetDatabase.SaveAssets();
if (refreshAssetDatabase) AssetDatabase.Refresh();
}
public static Texture GetTexture(string filePath, string fileName, string fileExtension = ".png")
{
if (string.IsNullOrEmpty(filePath)) return null;
if (string.IsNullOrEmpty(fileName)) return null;
// ReSharper disable once SuspiciousTypeConversion.Global
// if (!filePath[filePath.Length - 1].Equals(@"\")) filePath += @"\";
filePath = CleanPath(filePath);
return AssetDatabase.LoadAssetAtPath<Texture>(filePath + fileName + fileExtension);
}
public static Texture2D GetTexture2D(string filePath, string fileName, string fileExtension = ".png")
{
if (string.IsNullOrEmpty(filePath)) return null;
if (string.IsNullOrEmpty(fileName)) return null;
// ReSharper disable once SuspiciousTypeConversion.Global
// if (!filePath[filePath.Length - 1].Equals(@"\")) filePath += @"\";
filePath = CleanPath(filePath);
return AssetDatabase.LoadAssetAtPath<Texture2D>(filePath + fileName + fileExtension);
}
#endif
}
}
View File
+3 -3
View File
@@ -1,3 +1,3 @@
{
"name": "BigoAds"
}
{
"name": "BigoAds"
}
View File
+106 -106
View File
@@ -1,106 +1,106 @@
package sg.bigo.ads;
import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import sg.bigo.ads.api.AdOptionsView;
import sg.bigo.ads.api.AdTag;
import sg.bigo.ads.api.MediaView;
import sg.bigo.ads.api.NativeAd;
public class AdHelper {
public static void postToAndroidMainThread(Runnable runnable) {
new Handler(Looper.getMainLooper()).post(runnable);
}
public static void addAdView(Activity activity, View adView, int position) {
if (adView == null) return;
ViewGroup contentView = activity.findViewById(android.R.id.content);
String tag = "ad_container";
ViewGroup adContainer = contentView.findViewWithTag(tag);
if (adContainer == null) {
adContainer = new FrameLayout(activity);
adContainer.setTag(tag);
}
contentView.removeView(adContainer);
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, position);
contentView.addView(adContainer, layoutParams);
adContainer.removeAllViews();
adContainer.addView(adView);
}
public static void removeAdView(Activity activity)
{
ViewGroup contentView = activity.findViewById(android.R.id.content);
String tag = "ad_container";
ViewGroup adContainer = contentView.findViewWithTag(tag);
if (adContainer == null) return;
adContainer.removeAllViews();
}
public static int getLayoutIdByResName(Activity activity, String resName) {
return activity.getResources().getIdentifier(resName, "layout", activity.getPackageName());
}
public static int getDrawableIdByResName(Activity activity, String resName) {
return activity.getResources().getIdentifier(resName, "drawable", activity.getPackageName());
}
public static View renderNativeAdView(Activity activity, NativeAd nativeAd, String layoutResName) {
int layoutId = getLayoutIdByResName(activity, layoutResName);
if (layoutId <= 0) {
Log.w("BigoAds-Unity", "Invalid res name: " + layoutResName);
return null;
}
View view = LayoutInflater.from(activity).inflate(layoutId, null, false);
if (!(view instanceof ViewGroup)) {
return view;
}
ViewGroup nativeView = (ViewGroup) view;
TextView titleView = findViewByIdName(nativeView, "native_title");
TextView descriptionView = findViewByIdName(nativeView, "native_description");
TextView warningView = findViewByIdName(nativeView, "native_warning");
Button ctaButton = findViewByIdName(nativeView, "native_cta");
MediaView mediaView = findViewByIdName(nativeView, "native_media_view");
ImageView iconView = findViewByIdName(nativeView, "native_icon_view");
AdOptionsView optionsView = findViewByIdName(nativeView, "native_option_view");
titleView.setTag(AdTag.TITLE);
descriptionView.setTag(AdTag.DESCRIPTION);
warningView.setTag(AdTag.WARNING);
ctaButton.setTag(AdTag.CALL_TO_ACTION);
titleView.setText(nativeAd.getTitle());
descriptionView.setText(nativeAd.getDescription());
warningView.setText(nativeAd.getWarning());
ctaButton.setText(nativeAd.getCallToAction());
List<View> clickableViews = new ArrayList<>();
clickableViews.add(titleView);
clickableViews.add(descriptionView);
clickableViews.add(ctaButton);
nativeAd.registerViewForInteraction(nativeView, mediaView, iconView, optionsView, clickableViews);
return nativeView;
}
private static <T extends View> T findViewByIdName(ViewGroup parent, String name) {
Context context = parent.getContext();
int id = context.getResources().getIdentifier(name, "id", context.getPackageName());
return parent.findViewById(id);
}
}
package sg.bigo.ads;
import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import sg.bigo.ads.api.AdOptionsView;
import sg.bigo.ads.api.AdTag;
import sg.bigo.ads.api.MediaView;
import sg.bigo.ads.api.NativeAd;
public class AdHelper {
public static void postToAndroidMainThread(Runnable runnable) {
new Handler(Looper.getMainLooper()).post(runnable);
}
public static void addAdView(Activity activity, View adView, int position) {
if (adView == null) return;
ViewGroup contentView = activity.findViewById(android.R.id.content);
String tag = "ad_container";
ViewGroup adContainer = contentView.findViewWithTag(tag);
if (adContainer == null) {
adContainer = new FrameLayout(activity);
adContainer.setTag(tag);
}
contentView.removeView(adContainer);
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, position);
contentView.addView(adContainer, layoutParams);
adContainer.removeAllViews();
adContainer.addView(adView);
}
public static void removeAdView(Activity activity)
{
ViewGroup contentView = activity.findViewById(android.R.id.content);
String tag = "ad_container";
ViewGroup adContainer = contentView.findViewWithTag(tag);
if (adContainer == null) return;
adContainer.removeAllViews();
}
public static int getLayoutIdByResName(Activity activity, String resName) {
return activity.getResources().getIdentifier(resName, "layout", activity.getPackageName());
}
public static int getDrawableIdByResName(Activity activity, String resName) {
return activity.getResources().getIdentifier(resName, "drawable", activity.getPackageName());
}
public static View renderNativeAdView(Activity activity, NativeAd nativeAd, String layoutResName) {
int layoutId = getLayoutIdByResName(activity, layoutResName);
if (layoutId <= 0) {
Log.w("BigoAds-Unity", "Invalid res name: " + layoutResName);
return null;
}
View view = LayoutInflater.from(activity).inflate(layoutId, null, false);
if (!(view instanceof ViewGroup)) {
return view;
}
ViewGroup nativeView = (ViewGroup) view;
TextView titleView = findViewByIdName(nativeView, "native_title");
TextView descriptionView = findViewByIdName(nativeView, "native_description");
TextView warningView = findViewByIdName(nativeView, "native_warning");
Button ctaButton = findViewByIdName(nativeView, "native_cta");
MediaView mediaView = findViewByIdName(nativeView, "native_media_view");
ImageView iconView = findViewByIdName(nativeView, "native_icon_view");
AdOptionsView optionsView = findViewByIdName(nativeView, "native_option_view");
titleView.setTag(AdTag.TITLE);
descriptionView.setTag(AdTag.DESCRIPTION);
warningView.setTag(AdTag.WARNING);
ctaButton.setTag(AdTag.CALL_TO_ACTION);
titleView.setText(nativeAd.getTitle());
descriptionView.setText(nativeAd.getDescription());
warningView.setText(nativeAd.getWarning());
ctaButton.setText(nativeAd.getCallToAction());
List<View> clickableViews = new ArrayList<>();
clickableViews.add(titleView);
clickableViews.add(descriptionView);
clickableViews.add(ctaButton);
nativeAd.registerViewForInteraction(nativeView, mediaView, iconView, optionsView, clickableViews);
return nativeView;
}
private static <T extends View> T findViewByIdName(ViewGroup parent, String name) {
Context context = parent.getContext();
int id = context.getResources().getIdentifier(name, "id", context.getPackageName());
return parent.findViewById(id);
}
}
+13 -13
View File
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<dependencies>
<iosPods>
<iosPod name="BigoADS" version="5.1.2"/>
</iosPods>
<androidPackages>
<androidPackage spec="com.bigossp:bigo-ads:5.3.0">
<repositories>
<repository>https://repo1.maven.org/maven2/</repository>
</repositories>
</androidPackage>
</androidPackages>
</dependencies>
<?xml version="1.0" encoding="utf-8"?>
<dependencies>
<iosPods>
<iosPod name="BigoADS" version="5.1.2"/>
</iosPods>
<androidPackages>
<androidPackage spec="com.bigossp:bigo-ads:5.3.0">
<repositories>
<repository>https://repo1.maven.org/maven2/</repository>
</repositories>
</androidPackage>
</androidPackages>
</dependencies>
View File
+104 -104
View File
@@ -1,104 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<sg.bigo.ads.api.NativeAdView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/native_ad_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:padding="8dp"
tools:ignore="ContentDescription">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/native_ad_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:text="Ad" />
<sg.bigo.ads.api.MediaView
android:id="@+id/native_media_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/native_ad_label"
android:layout_centerVertical="true"
android:layout_marginTop="4dp" />
<ImageView
android:id="@+id/native_icon_view"
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_below="@id/native_media_view"
android:layout_marginTop="8dp" />
<TextView
android:id="@+id/native_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/native_icon_view"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:layout_toEndOf="@id/native_icon_view"
android:ellipsize="end"
android:fontFamily="sans-serif-medium"
android:maxLines="1"
android:text=""
android:textColor="@android:color/darker_gray"
android:textSize="14sp" />
<TextView
android:id="@+id/native_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/native_title"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
android:layout_toEndOf="@id/native_icon_view"
android:ellipsize="end"
android:maxLines="1"
android:text=""
android:textColor="@android:color/darker_gray"
android:textSize="12sp" />
<Button
android:id="@+id/native_cta"
android:layout_width="240dp"
android:layout_height="44dp"
android:layout_below="@id/native_icon_view"
android:layout_marginTop="8dp"
android:backgroundTint="@android:color/holo_blue_light"
android:ellipsize="end"
android:maxLines="2"
android:textAllCaps="false"
android:textColor="@android:color/white"
android:textSize="16sp"
tools:ignore="ObsoleteLayoutParam" />
<sg.bigo.ads.api.AdOptionsView
android:id="@+id/native_option_view"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignTop="@id/native_icon_view"
android:layout_alignParentEnd="true"
android:layout_marginEnd="8dp" />
<TextView
android:id="@+id/native_warning"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/native_ad_label"
android:layout_alignBottom="@id/native_ad_label"
android:layout_marginStart="8dp"
android:layout_toEndOf="@id/native_ad_label"
android:ellipsize="end"
android:maxLines="2"
android:text=""
android:textColor="@android:color/darker_gray"
android:textSize="10sp" />
</RelativeLayout>
</sg.bigo.ads.api.NativeAdView>
<?xml version="1.0" encoding="utf-8"?>
<sg.bigo.ads.api.NativeAdView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/native_ad_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:padding="8dp"
tools:ignore="ContentDescription">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/native_ad_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:text="Ad" />
<sg.bigo.ads.api.MediaView
android:id="@+id/native_media_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/native_ad_label"
android:layout_centerVertical="true"
android:layout_marginTop="4dp" />
<ImageView
android:id="@+id/native_icon_view"
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_below="@id/native_media_view"
android:layout_marginTop="8dp" />
<TextView
android:id="@+id/native_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/native_icon_view"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:layout_toEndOf="@id/native_icon_view"
android:ellipsize="end"
android:fontFamily="sans-serif-medium"
android:maxLines="1"
android:text=""
android:textColor="@android:color/darker_gray"
android:textSize="14sp" />
<TextView
android:id="@+id/native_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/native_title"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
android:layout_toEndOf="@id/native_icon_view"
android:ellipsize="end"
android:maxLines="1"
android:text=""
android:textColor="@android:color/darker_gray"
android:textSize="12sp" />
<Button
android:id="@+id/native_cta"
android:layout_width="240dp"
android:layout_height="44dp"
android:layout_below="@id/native_icon_view"
android:layout_marginTop="8dp"
android:backgroundTint="@android:color/holo_blue_light"
android:ellipsize="end"
android:maxLines="2"
android:textAllCaps="false"
android:textColor="@android:color/white"
android:textSize="16sp"
tools:ignore="ObsoleteLayoutParam" />
<sg.bigo.ads.api.AdOptionsView
android:id="@+id/native_option_view"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignTop="@id/native_icon_view"
android:layout_alignParentEnd="true"
android:layout_marginEnd="8dp" />
<TextView
android:id="@+id/native_warning"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/native_ad_label"
android:layout_alignBottom="@id/native_ad_label"
android:layout_marginStart="8dp"
android:layout_toEndOf="@id/native_ad_label"
android:ellipsize="end"
android:maxLines="2"
android:text=""
android:textColor="@android:color/darker_gray"
android:textSize="10sp" />
</RelativeLayout>
</sg.bigo.ads.api.NativeAdView>
+11 -11
View File
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<dependencies>
<androidPackages>
<androidPackage spec="androidx.media3:media3-exoplayer:1.0.0-alpha01" />
<androidPackage spec="androidx.appcompat:appcompat:1.2.0"/>
<androidPackage spec="com.google.android.material:material:1.2.1"/>
<androidPackage spec="androidx.annotation:annotation:1.2.0"/>
<androidPackage spec="org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.10"/>
<androidPackage spec="com.google.android.gms:play-services-ads-identifier:18.0.1"/>
</androidPackages>
</dependencies>
<?xml version="1.0" encoding="utf-8"?>
<dependencies>
<androidPackages>
<androidPackage spec="androidx.media3:media3-exoplayer:1.0.0-alpha01" />
<androidPackage spec="androidx.appcompat:appcompat:1.2.0"/>
<androidPackage spec="com.google.android.material:material:1.2.1"/>
<androidPackage spec="androidx.annotation:annotation:1.2.0"/>
<androidPackage spec="org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.10"/>
<androidPackage spec="com.google.android.gms:play-services-ads-identifier:18.0.1"/>
</androidPackages>
</dependencies>
View File
+1 -1
View File
@@ -1,4 +1,4 @@
using System;
using System;
using KwaiAds.Scripts.Common;
namespace KwaiAds.Scripts.Api
View File
+21 -21
View File
@@ -1,21 +1,21 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public interface IKwaiAdListener
{
void OnLoaded(string unitId, string price);
void OnLoadFailed(string unitId, int code, string msg);
void OnShow();
void OnShowFailed(int code, string msg);
void OnClick();
void OnClosed();
void OnReward();
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public interface IKwaiAdListener
{
void OnLoaded(string unitId, string price);
void OnLoadFailed(string unitId, int code, string msg);
void OnShow();
void OnShowFailed(int code, string msg);
void OnClick();
void OnClosed();
void OnReward();
}
View File
+3 -3
View File
@@ -1,3 +1,3 @@
{
"name": "KwaiAds"
}
{
"name": "KwaiAds"
}
View File
+66 -66
View File
@@ -1,66 +1,66 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class KwaiAdsMgr
{
public static void Init(string appId, string token, bool isDebug, Action<bool, int, string> initCallBack)
{
bool debug = isDebug; // Whether in debug mode. Plsease set to false when in release build.
var kwaiAdConfig = new KwaiAds.Scripts.Api.KwaiAdConfig.Builder()
.SetAppId(appId) // ±ØÌî
.SetToken(token) // ±ØÌî
.SetAppName("")
.SetAppDomain("")
.SetAppStoreUrl("")
.SetDebugLog(debug)
.Build();
KwaiAds.Scripts.Api.KwaiAdsSdk.Initialize(kwaiAdConfig, new InitResultCallbackImpl(initCallBack));
}
class InitResultCallbackImpl : KwaiAds.Scripts.Api.InitResultCallback
{
private Action<bool, int, string> _initCallBack;
public InitResultCallbackImpl(Action<bool, int, string> callBack)
{
_initCallBack = callBack;
}
public void OnFail(int code, string msg)
{
_initCallBack?.Invoke(false, code, msg);
KwaiLog.Error($"#Kwai InitResultCallback code:{code}, msg: {msg}");
}
public void OnSuccess()
{
_initCallBack?.Invoke(true, 0, "");
KwaiLog.Log($"#Kwai InitResultCallback OnSuccess.");
}
}
}
public class KwaiLog
{
public static bool isShow = true;
public static void Log(string msg)
{
if (isShow)
{
Debug.Log(msg);
}
}
public static void Error(string msg)
{
if (isShow)
{
Debug.LogError(msg);
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class KwaiAdsMgr
{
public static void Init(string appId, string token, bool isDebug, Action<bool, int, string> initCallBack)
{
bool debug = isDebug; // Whether in debug mode. Plsease set to false when in release build.
var kwaiAdConfig = new KwaiAds.Scripts.Api.KwaiAdConfig.Builder()
.SetAppId(appId) // ±ØÌî
.SetToken(token) // ±ØÌî
.SetAppName("")
.SetAppDomain("")
.SetAppStoreUrl("")
.SetDebugLog(debug)
.Build();
KwaiAds.Scripts.Api.KwaiAdsSdk.Initialize(kwaiAdConfig, new InitResultCallbackImpl(initCallBack));
}
class InitResultCallbackImpl : KwaiAds.Scripts.Api.InitResultCallback
{
private Action<bool, int, string> _initCallBack;
public InitResultCallbackImpl(Action<bool, int, string> callBack)
{
_initCallBack = callBack;
}
public void OnFail(int code, string msg)
{
_initCallBack?.Invoke(false, code, msg);
KwaiLog.Error($"#Kwai InitResultCallback code:{code}, msg: {msg}");
}
public void OnSuccess()
{
_initCallBack?.Invoke(true, 0, "");
KwaiLog.Log($"#Kwai InitResultCallback OnSuccess.");
}
}
}
public class KwaiLog
{
public static bool isShow = true;
public static void Log(string msg)
{
if (isShow)
{
Debug.Log(msg);
}
}
public static void Error(string msg)
{
if (isShow)
{
Debug.LogError(msg);
}
}
}
View File
+133 -133
View File
@@ -1,133 +1,133 @@
using System.Collections;
using System.Collections.Generic;
using KwaiAds.Scripts.Api;
using KwaiAds.Scripts.Api.Interstitial;
using UnityEngine;
public class KwaiInterAd
{
private IInterstitialAdController _kwaiInter;
private string _unitId;
private IKwaiAdListener _kwaiAdListener;
public IKwaiAdListener KwaiAdListener => _kwaiAdListener;
public KwaiInterAd(string unitId, IKwaiAdListener adListener)
{
_unitId = unitId;
_kwaiAdListener = adListener;
}
public void Load(string ecpmPrice = "0.01")
{
// 获取每次load都需要获取新的KwaiInterstitialAdController
if (_kwaiInter != null)
{
_kwaiInter.Destroy();
_kwaiInter = null;
}
_kwaiInter = KwaiAds.Scripts.Api.KwaiAdsSdk.SDK.getInterstitialAdController();
// 构建KwaiInterstitialAdRequest
KwaiInterstitialAdRequest interstitialRewardAdRequest = new KwaiInterstitialAdRequest(_unitId); // tagId必填
// 选填, 可以设置低价 单位是$(美元,ecpm)
interstitialRewardAdRequest.ExtParams[Constants.Request.BID_FLOOR_PRICE] = ecpmPrice;
// 加载过程接受三个参数,
// - KwaiInterstitialAdRequest 配置请求参数
// - IInterstitialAdListener 回调为插页点击、曝光状态
// - IInterstitialAdLoadListener 回调为插页加载状态
_kwaiInter.Load(interstitialRewardAdRequest, new InterstitialAdListener(this), new InterstitialAdLoadListener(this));
}
public void Show()
{
if (IsReady())
{
_kwaiInter.Show();
}
}
public bool IsReady()
{
return _kwaiInter != null && _kwaiInter.IsReady();
}
public void NotifyWin(string minWinPrice)
{
//_kwaiInter?.NotifyWin();//报错暂时屏蔽
_kwaiInter?.NotifyWin(minWinPrice);
}
public void NotifyLoss(string winPrice)
{
//_kwaiInter?.NotifyLoss();
_kwaiInter?.NotifyLoss(winPrice);
}
private class InterstitialAdListener : IInterstitialAdListener
{
private KwaiInterAd _kwaiInterAd;
public InterstitialAdListener(KwaiInterAd interAd)
{
_kwaiInterAd = interAd;
}
public void OnAdClick()
{
KwaiLog.Log($"#Kwai OnAdClick");
_kwaiInterAd?.KwaiAdListener?.OnClick();
}
public void OnAdClose()
{
KwaiLog.Log($"#Kwai OnAdClose");
_kwaiInterAd?.KwaiAdListener?.OnClosed();
}
public void OnAdPlayComplete()
{
KwaiLog.Log($"#Kwai OnAdPlayComplete");
}
public void OnAdShow()
{
KwaiLog.Log($"#Kwai OnAdShow");
_kwaiInterAd?.KwaiAdListener?.OnShow();
}
public void OnAdShowFailed(int code, string msg)
{
KwaiLog.Log($"#Kwai OnAdShowFailed code = {code}, msg = {msg}");
_kwaiInterAd?.KwaiAdListener?.OnShowFailed(code, msg);
}
}
private class InterstitialAdLoadListener : IInterstitialAdLoadListener
{
private KwaiInterAd _kwaiInterAd;
public InterstitialAdLoadListener(KwaiInterAd interAd)
{
_kwaiInterAd = interAd;
}
public void OnAdLoadFailed(string trackId, int code, string msg)
{
KwaiLog.Log($"#Kwai OnAdLoadFailed trackId = {trackId}, code = {code}, msg = {msg}");
_kwaiInterAd?.KwaiAdListener?.OnLoadFailed(trackId, code, msg);
}
public void OnAdLoadStart(string trackId)
{
KwaiLog.Log($"#Kwai OnAdLoadStart trackId = {trackId}");
}
public void OnAdLoadSuccess(string trackId, string price)
{
KwaiLog.Log($"#Kwai OnAdLoadSuccess trackId = {trackId}, price = {price}");
_kwaiInterAd?.KwaiAdListener?.OnLoaded(trackId, price);
}
}
}
using System.Collections;
using System.Collections.Generic;
using KwaiAds.Scripts.Api;
using KwaiAds.Scripts.Api.Interstitial;
using UnityEngine;
public class KwaiInterAd
{
private IInterstitialAdController _kwaiInter;
private string _unitId;
private IKwaiAdListener _kwaiAdListener;
public IKwaiAdListener KwaiAdListener => _kwaiAdListener;
public KwaiInterAd(string unitId, IKwaiAdListener adListener)
{
_unitId = unitId;
_kwaiAdListener = adListener;
}
public void Load(string ecpmPrice = "0.01")
{
// 获取每次load都需要获取新的KwaiInterstitialAdController
if (_kwaiInter != null)
{
_kwaiInter.Destroy();
_kwaiInter = null;
}
_kwaiInter = KwaiAds.Scripts.Api.KwaiAdsSdk.SDK.getInterstitialAdController();
// 构建KwaiInterstitialAdRequest
KwaiInterstitialAdRequest interstitialRewardAdRequest = new KwaiInterstitialAdRequest(_unitId); // tagId必填
// 选填, 可以设置低价 单位是$(美元,ecpm)
interstitialRewardAdRequest.ExtParams[Constants.Request.BID_FLOOR_PRICE] = ecpmPrice;
// 加载过程接受三个参数,
// - KwaiInterstitialAdRequest 配置请求参数
// - IInterstitialAdListener 回调为插页点击、曝光状态
// - IInterstitialAdLoadListener 回调为插页加载状态
_kwaiInter.Load(interstitialRewardAdRequest, new InterstitialAdListener(this), new InterstitialAdLoadListener(this));
}
public void Show()
{
if (IsReady())
{
_kwaiInter.Show();
}
}
public bool IsReady()
{
return _kwaiInter != null && _kwaiInter.IsReady();
}
public void NotifyWin(string minWinPrice)
{
//_kwaiInter?.NotifyWin();//报错暂时屏蔽
_kwaiInter?.NotifyWin(minWinPrice);
}
public void NotifyLoss(string winPrice)
{
//_kwaiInter?.NotifyLoss();
_kwaiInter?.NotifyLoss(winPrice);
}
private class InterstitialAdListener : IInterstitialAdListener
{
private KwaiInterAd _kwaiInterAd;
public InterstitialAdListener(KwaiInterAd interAd)
{
_kwaiInterAd = interAd;
}
public void OnAdClick()
{
KwaiLog.Log($"#Kwai OnAdClick");
_kwaiInterAd?.KwaiAdListener?.OnClick();
}
public void OnAdClose()
{
KwaiLog.Log($"#Kwai OnAdClose");
_kwaiInterAd?.KwaiAdListener?.OnClosed();
}
public void OnAdPlayComplete()
{
KwaiLog.Log($"#Kwai OnAdPlayComplete");
}
public void OnAdShow()
{
KwaiLog.Log($"#Kwai OnAdShow");
_kwaiInterAd?.KwaiAdListener?.OnShow();
}
public void OnAdShowFailed(int code, string msg)
{
KwaiLog.Log($"#Kwai OnAdShowFailed code = {code}, msg = {msg}");
_kwaiInterAd?.KwaiAdListener?.OnShowFailed(code, msg);
}
}
private class InterstitialAdLoadListener : IInterstitialAdLoadListener
{
private KwaiInterAd _kwaiInterAd;
public InterstitialAdLoadListener(KwaiInterAd interAd)
{
_kwaiInterAd = interAd;
}
public void OnAdLoadFailed(string trackId, int code, string msg)
{
KwaiLog.Log($"#Kwai OnAdLoadFailed trackId = {trackId}, code = {code}, msg = {msg}");
_kwaiInterAd?.KwaiAdListener?.OnLoadFailed(trackId, code, msg);
}
public void OnAdLoadStart(string trackId)
{
KwaiLog.Log($"#Kwai OnAdLoadStart trackId = {trackId}");
}
public void OnAdLoadSuccess(string trackId, string price)
{
KwaiLog.Log($"#Kwai OnAdLoadSuccess trackId = {trackId}, price = {price}");
_kwaiInterAd?.KwaiAdListener?.OnLoaded(trackId, price);
}
}
}
View File
+139 -139
View File
@@ -1,139 +1,139 @@
using System.Collections;
using System.Collections.Generic;
using KwaiAds.Scripts.Api.Reward;
using KwaiAds.Scripts.Api;
using UnityEngine;
public class KwaiVideoAd
{
private KwaiAds.Scripts.Api.Reward.IRewardAdController _kwaiReward;
private string _unitId;
private IKwaiAdListener _kwaiAdListener;
public IKwaiAdListener KwaiAdListener => _kwaiAdListener;
public KwaiVideoAd(string unitId, IKwaiAdListener adListener)
{
_unitId = unitId;
_kwaiAdListener = adListener;
}
public void Load(string ecpmPrice = "0.01")
{
if(_kwaiReward != null)
{
_kwaiReward.Destroy();
_kwaiReward = null;
}
_kwaiReward = KwaiAds.Scripts.Api.KwaiAdsSdk.SDK.getRewardAdController();
// 构建KwaiRewardAdRequest
KwaiRewardAdRequest kwaiRewardAdRequest = new KwaiRewardAdRequest(_unitId);
// 选填, 可以设置低价 单位是$(美元,ecpm)
kwaiRewardAdRequest.ExtParams[Constants.Request.BID_FLOOR_PRICE] = ecpmPrice;
// 加载过程接受三个参数,
// - KwaiRewardAdRequest 配置请求参数
// - IRewardAdListener实现类,回调为激励
_kwaiReward.Load(kwaiRewardAdRequest, new RewardAdListener(this), new RewardAdLoadListener(this));
}
public void Show()
{
if(IsReady())
{
_kwaiReward.Show();
}
}
public bool IsReady()
{
return _kwaiReward != null && _kwaiReward.IsReady();
}
public void NotifyWin(string minWinPrice)
{
//_kwaiReward?.NotifyWin(); //报错暂时屏蔽
_kwaiReward?.NotifyWin(minWinPrice);
}
public void NotifyLoss(string winPrice)
{
//_kwaiReward?.NotifyLoss();
_kwaiReward?.NotifyLoss(winPrice);
}
private class RewardAdListener : IRewardAdListener
{
private KwaiVideoAd _kwaiVideoAd;
public RewardAdListener(KwaiVideoAd videoAd)
{
_kwaiVideoAd = videoAd;
}
public void OnAdClick()
{
KwaiLog.Log($"#Kwai OnAdClick");
_kwaiVideoAd.KwaiAdListener.OnClick();
}
public void OnAdClose()
{
KwaiLog.Log($"#Kwai OnAdClose");
_kwaiVideoAd.KwaiAdListener.OnClosed();
}
public void OnAdPlayComplete()
{
KwaiLog.Log($"#Kwai OnAdPlayComplete");
}
public void OnAdShow()
{
KwaiLog.Log($"#Kwai OnAdShow");
_kwaiVideoAd.KwaiAdListener.OnShow();
}
public void OnAdShowFailed(int code, string msg)
{
KwaiLog.Log($"#Kwai OnAdShowFailed, code = {code}, msg = {msg}");
_kwaiVideoAd.KwaiAdListener.OnShowFailed(code, msg);
}
public void OnRewardEarned()
{
KwaiLog.Log($"#Kwai OnRewardEarned");
_kwaiVideoAd.KwaiAdListener.OnReward();
}
}
private class RewardAdLoadListener : IRewardAdLoadListener
{
private KwaiVideoAd _kwaiVideoAd;
public RewardAdLoadListener(KwaiVideoAd videoAd)
{
_kwaiVideoAd = videoAd;
}
public void OnAdLoadFailed(string trackId, int code, string msg)
{
KwaiLog.Log($"#Kwai OnAdLoadFailed, trackId = {trackId}, code = {code}, msg = {msg}");
_kwaiVideoAd.KwaiAdListener.OnLoadFailed(trackId, code, msg);
}
public void OnAdLoadStart(string trackId)
{
KwaiLog.Log($"#Kwai OnAdLoadStart, trackId = {trackId}");
}
public void OnAdLoadSuccess(string trackId, string price)
{
KwaiLog.Log($"#Kwai OnAdLoadSuccess, trackId = {trackId}, price = {price}");
_kwaiVideoAd.KwaiAdListener.OnLoaded(trackId, price);
}
}
}
using System.Collections;
using System.Collections.Generic;
using KwaiAds.Scripts.Api.Reward;
using KwaiAds.Scripts.Api;
using UnityEngine;
public class KwaiVideoAd
{
private KwaiAds.Scripts.Api.Reward.IRewardAdController _kwaiReward;
private string _unitId;
private IKwaiAdListener _kwaiAdListener;
public IKwaiAdListener KwaiAdListener => _kwaiAdListener;
public KwaiVideoAd(string unitId, IKwaiAdListener adListener)
{
_unitId = unitId;
_kwaiAdListener = adListener;
}
public void Load(string ecpmPrice = "0.01")
{
if(_kwaiReward != null)
{
_kwaiReward.Destroy();
_kwaiReward = null;
}
_kwaiReward = KwaiAds.Scripts.Api.KwaiAdsSdk.SDK.getRewardAdController();
// 构建KwaiRewardAdRequest
KwaiRewardAdRequest kwaiRewardAdRequest = new KwaiRewardAdRequest(_unitId);
// 选填, 可以设置低价 单位是$(美元,ecpm)
kwaiRewardAdRequest.ExtParams[Constants.Request.BID_FLOOR_PRICE] = ecpmPrice;
// 加载过程接受三个参数,
// - KwaiRewardAdRequest 配置请求参数
// - IRewardAdListener实现类,回调为激励
_kwaiReward.Load(kwaiRewardAdRequest, new RewardAdListener(this), new RewardAdLoadListener(this));
}
public void Show()
{
if(IsReady())
{
_kwaiReward.Show();
}
}
public bool IsReady()
{
return _kwaiReward != null && _kwaiReward.IsReady();
}
public void NotifyWin(string minWinPrice)
{
//_kwaiReward?.NotifyWin(); //报错暂时屏蔽
_kwaiReward?.NotifyWin(minWinPrice);
}
public void NotifyLoss(string winPrice)
{
//_kwaiReward?.NotifyLoss();
_kwaiReward?.NotifyLoss(winPrice);
}
private class RewardAdListener : IRewardAdListener
{
private KwaiVideoAd _kwaiVideoAd;
public RewardAdListener(KwaiVideoAd videoAd)
{
_kwaiVideoAd = videoAd;
}
public void OnAdClick()
{
KwaiLog.Log($"#Kwai OnAdClick");
_kwaiVideoAd.KwaiAdListener.OnClick();
}
public void OnAdClose()
{
KwaiLog.Log($"#Kwai OnAdClose");
_kwaiVideoAd.KwaiAdListener.OnClosed();
}
public void OnAdPlayComplete()
{
KwaiLog.Log($"#Kwai OnAdPlayComplete");
}
public void OnAdShow()
{
KwaiLog.Log($"#Kwai OnAdShow");
_kwaiVideoAd.KwaiAdListener.OnShow();
}
public void OnAdShowFailed(int code, string msg)
{
KwaiLog.Log($"#Kwai OnAdShowFailed, code = {code}, msg = {msg}");
_kwaiVideoAd.KwaiAdListener.OnShowFailed(code, msg);
}
public void OnRewardEarned()
{
KwaiLog.Log($"#Kwai OnRewardEarned");
_kwaiVideoAd.KwaiAdListener.OnReward();
}
}
private class RewardAdLoadListener : IRewardAdLoadListener
{
private KwaiVideoAd _kwaiVideoAd;
public RewardAdLoadListener(KwaiVideoAd videoAd)
{
_kwaiVideoAd = videoAd;
}
public void OnAdLoadFailed(string trackId, int code, string msg)
{
KwaiLog.Log($"#Kwai OnAdLoadFailed, trackId = {trackId}, code = {code}, msg = {msg}");
_kwaiVideoAd.KwaiAdListener.OnLoadFailed(trackId, code, msg);
}
public void OnAdLoadStart(string trackId)
{
KwaiLog.Log($"#Kwai OnAdLoadStart, trackId = {trackId}");
}
public void OnAdLoadSuccess(string trackId, string price)
{
KwaiLog.Log($"#Kwai OnAdLoadSuccess, trackId = {trackId}, price = {price}");
_kwaiVideoAd.KwaiAdListener.OnLoaded(trackId, price);
}
}
}
View File
@@ -113,7 +113,7 @@ namespace KwaiAds.Scripts.Platforms.Android
public void NotifyLoss(string winPrice)
{
if (_KwaiInterstitialAd != null)
{
{
//_KwaiInterstitialAd.Call("getBidController", "sendBidLose");
AndroidJavaObject bidController = _KwaiInterstitialAd.Call<AndroidJavaObject>("getBidController");
bidController?.Call("sendBidLose", "101", winPrice);
@@ -123,7 +123,7 @@ namespace KwaiAds.Scripts.Platforms.Android
public void NotifyWin(string minWinPrice)
{
if (_KwaiInterstitialAd != null)
{
{
//_KwaiInterstitialAd.Call("getBidController", "sendBidWin");
AndroidJavaObject bidController = _KwaiInterstitialAd.Call<AndroidJavaObject>("getBidController");
bidController?.Call("sendBidWin", minWinPrice);
+2 -2
View File
@@ -113,7 +113,7 @@ namespace KwaiAds.Scripts.Platforms.Android
public void NotifyLoss(string winPrice)
{
if (_KwaiRewardAd != null)
{
{
//_KwaiRewardAd.Call("getBidController", "sendBidLose");
AndroidJavaObject bidController = _KwaiRewardAd.Call<AndroidJavaObject>("getBidController");
bidController?.Call("sendBidLose", "101", winPrice);
@@ -123,7 +123,7 @@ namespace KwaiAds.Scripts.Platforms.Android
public void NotifyWin(string minWinPrice)
{
if (_KwaiRewardAd != null)
{
{
//_KwaiRewardAd.Call("getBidController", "sendBidWin");
AndroidJavaObject bidController = _KwaiRewardAd.Call<AndroidJavaObject>("getBidController");
bidController?.Call("sendBidWin", minWinPrice);
+124 -124
View File
@@ -1,125 +1,125 @@
#if UNITY_ANDROID
using System.IO;
using System.Text.RegularExpressions;
using System.Xml;
using UnityEditor;
using UnityEditor.Android;
using UnityEngine;
public class BuildPostProcessorVoSdk : IPostGenerateGradleAndroidProject
{
public int callbackOrder => 0;
public void OnPostGenerateGradleAndroidProject(string path)
{
Debug.Log("AndroidBuildPostProcessor running after gradle project generation");
// 添加AndroidManifest权限
AddManifestPermissions(path);
}
private void AddManifestPermissions(string gradleProjectPath)
{
string manifestPath = Path.Combine(gradleProjectPath, "src/main/AndroidManifest.xml");
if (!File.Exists(manifestPath))
{
Debug.LogError("AndroidManifest.xml not found at: " + manifestPath);
return;
}
XmlDocument doc = new XmlDocument();
doc.Load(manifestPath);
// 更可靠的方式查找 manifest 节点
XmlNode manifestNode = doc.SelectSingleNode("//manifest");
if (manifestNode == null)
{
Debug.LogError("No manifest node found in AndroidManifest.xml");
Debug.Log("Trying to parse document element as manifest...");
manifestNode = doc.DocumentElement;
if (manifestNode == null || manifestNode.Name != "manifest")
{
Debug.LogError("Failed to find manifest node, document element is: " +
(manifestNode?.Name ?? "null"));
return;
}
}
// 要添加的权限列表
string[] permissions = new string[]
{
"android.permission.INTERNET",
"android.permission.ACCESS_NETWORK_STATE",
"android.permission.ACCESS_WIFI_STATE",
"android.permission.WAKE_LOCK",
//"android.permission.WRITE_EXTERNAL_STORAGE",
//"android.permission.READ_PHONE_STATE",
};
// 添加权限
foreach (var permission in permissions)
{
if (!PermissionExists(doc, permission))
{
XmlElement element = doc.CreateElement("uses-permission");
element.SetAttribute("name", "http://schemas.android.com/apk/res/android", permission);
manifestNode.AppendChild(element);
Debug.Log("Added permission: " + permission);
}
}
// 添加queries
AddQueriesIfNeeded(doc, manifestNode);
// 保存修改
doc.Save(manifestPath);
Debug.Log("Successfully updated AndroidManifest.xml");
}
private bool PermissionExists(XmlDocument doc, string permissionName)
{
XmlNodeList nodes = doc.GetElementsByTagName("uses-permission");
foreach (XmlNode node in nodes)
{
var nameAttr = node.Attributes?["android:name"];
if (nameAttr != null && nameAttr.Value == permissionName)
return true;
}
return false;
}
private void AddQueriesIfNeeded(XmlDocument doc, XmlNode manifestNode)
{
// 检查是否已存在queries节点
XmlNode queriesNode = doc.SelectSingleNode("//queries");
if (queriesNode != null) return;
// 创建queries节点
queriesNode = doc.CreateElement("queries");
// 添加package节点
string[] packages = { "com.android.vending", "com.google.android.gms" };
foreach (var package in packages)
{
XmlElement packageElement = doc.CreateElement("package");
packageElement.SetAttribute("name", "http://schemas.android.com/apk/res/android", package);
queriesNode.AppendChild(packageElement);
}
// 将queries节点添加到manifest中(application节点之前)
XmlNode applicationNode = doc.SelectSingleNode("//application");
if (applicationNode != null)
{
manifestNode.InsertBefore(queriesNode, applicationNode);
}
else
{
manifestNode.AppendChild(queriesNode);
}
Debug.Log("Added queries section to AndroidManifest.xml");
}
}
#if UNITY_ANDROID
using System.IO;
using System.Text.RegularExpressions;
using System.Xml;
using UnityEditor;
using UnityEditor.Android;
using UnityEngine;
public class BuildPostProcessorVoSdk : IPostGenerateGradleAndroidProject
{
public int callbackOrder => 0;
public void OnPostGenerateGradleAndroidProject(string path)
{
Debug.Log("AndroidBuildPostProcessor running after gradle project generation");
// 添加AndroidManifest权限
AddManifestPermissions(path);
}
private void AddManifestPermissions(string gradleProjectPath)
{
string manifestPath = Path.Combine(gradleProjectPath, "src/main/AndroidManifest.xml");
if (!File.Exists(manifestPath))
{
Debug.LogError("AndroidManifest.xml not found at: " + manifestPath);
return;
}
XmlDocument doc = new XmlDocument();
doc.Load(manifestPath);
// 更可靠的方式查找 manifest 节点
XmlNode manifestNode = doc.SelectSingleNode("//manifest");
if (manifestNode == null)
{
Debug.LogError("No manifest node found in AndroidManifest.xml");
Debug.Log("Trying to parse document element as manifest...");
manifestNode = doc.DocumentElement;
if (manifestNode == null || manifestNode.Name != "manifest")
{
Debug.LogError("Failed to find manifest node, document element is: " +
(manifestNode?.Name ?? "null"));
return;
}
}
// 要添加的权限列表
string[] permissions = new string[]
{
"android.permission.INTERNET",
"android.permission.ACCESS_NETWORK_STATE",
"android.permission.ACCESS_WIFI_STATE",
"android.permission.WAKE_LOCK",
//"android.permission.WRITE_EXTERNAL_STORAGE",
//"android.permission.READ_PHONE_STATE",
};
// 添加权限
foreach (var permission in permissions)
{
if (!PermissionExists(doc, permission))
{
XmlElement element = doc.CreateElement("uses-permission");
element.SetAttribute("name", "http://schemas.android.com/apk/res/android", permission);
manifestNode.AppendChild(element);
Debug.Log("Added permission: " + permission);
}
}
// 添加queries
AddQueriesIfNeeded(doc, manifestNode);
// 保存修改
doc.Save(manifestPath);
Debug.Log("Successfully updated AndroidManifest.xml");
}
private bool PermissionExists(XmlDocument doc, string permissionName)
{
XmlNodeList nodes = doc.GetElementsByTagName("uses-permission");
foreach (XmlNode node in nodes)
{
var nameAttr = node.Attributes?["android:name"];
if (nameAttr != null && nameAttr.Value == permissionName)
return true;
}
return false;
}
private void AddQueriesIfNeeded(XmlDocument doc, XmlNode manifestNode)
{
// 检查是否已存在queries节点
XmlNode queriesNode = doc.SelectSingleNode("//queries");
if (queriesNode != null) return;
// 创建queries节点
queriesNode = doc.CreateElement("queries");
// 添加package节点
string[] packages = { "com.android.vending", "com.google.android.gms" };
foreach (var package in packages)
{
XmlElement packageElement = doc.CreateElement("package");
packageElement.SetAttribute("name", "http://schemas.android.com/apk/res/android", package);
queriesNode.AppendChild(packageElement);
}
// 将queries节点添加到manifest中(application节点之前)
XmlNode applicationNode = doc.SelectSingleNode("//application");
if (applicationNode != null)
{
manifestNode.InsertBefore(queriesNode, applicationNode);
}
else
{
manifestNode.AppendChild(queriesNode);
}
Debug.Log("Added queries section to AndroidManifest.xml");
}
}
#endif
View File
+20 -20
View File
@@ -1,20 +1,20 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace AD.VosacoSDK
{
// ISDKInitCallback.cs
public class ISDKInitCallback : AndroidJavaProxy
{
public Action<bool, string> onInitResult;
public ISDKInitCallback() : base("com.rixengine.unity_plugin.ISDKInit") { }
public void initResult(bool success, string message)
{
onInitResult?.Invoke(success, message);
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace AD.VosacoSDK
{
// ISDKInitCallback.cs
public class ISDKInitCallback : AndroidJavaProxy
{
public Action<bool, string> onInitResult;
public ISDKInitCallback() : base("com.rixengine.unity_plugin.ISDKInit") { }
public void initResult(bool success, string message)
{
onInitResult?.Invoke(success, message);
}
}
}
View File
+80 -80
View File
@@ -1,80 +1,80 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace AD.VosacoSDK
{
public class VosacoAdSDK
{
private static AndroidJavaClass _adClass;
// 初始化SDK
public static void Initialize(string host, string token, string sid, string appId, Action<bool, string> callback)
{
if (Application.platform != RuntimePlatform.Android)
{
LogD("SDK only works on Android platform");
return;
}
try
{
// 创建Java回调对象
var initCallback = new ISDKInitCallback
{
onInitResult = callback
};
// 调用Java方法
GetAdClass().CallStatic("init", host, token, sid, appId, initCallback);
}
catch (Exception e)
{
LogE($"Initialize failed: {e.Message}");
}
}
// 其他接口封装
public static void SetDebug(bool enable) => GetAdClass().CallStatic("setDebug", enable);
public static void SetGDPRConsent(bool consent) => GetAdClass().CallStatic("setSubjectToGDPR", consent);
public static void SetUserConsent(string consent) => GetAdClass().CallStatic("setUserConsent", consent);
public static void SetUSPrivacy(string privacy) => GetAdClass().CallStatic("subjectToUSPrivacy", privacy);
public static void SetExtraParameters(Dictionary<string, object> parameters)
{
using AndroidJavaObject map = new AndroidJavaObject("java.util.HashMap");
foreach (var kv in parameters)
{
map.Call<AndroidJavaObject>("put", kv.Key, kv.Value);
}
GetAdClass().CallStatic("setExtraParameters", map);
}
// 获取网络信息
public static string GetNetworkName() => GetAdClass().CallStatic<string>("getNetWorkName");
public static string GetNetworkVersion() => GetAdClass().CallStatic<string>("getNetWorkVersion");
public static void LogD(string msg)
{
GetAdClass().CallStatic("LogD", msg);
}
public static void LogE(string msg)
{
GetAdClass().CallStatic("LogE", msg);
}
private static AndroidJavaClass GetAdClass()
{
if (_adClass == null)
{
_adClass = new AndroidJavaClass("com.rixengine.unity_plugin.RiEngineAd");
}
return _adClass;
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace AD.VosacoSDK
{
public class VosacoAdSDK
{
private static AndroidJavaClass _adClass;
// 初始化SDK
public static void Initialize(string host, string token, string sid, string appId, Action<bool, string> callback)
{
if (Application.platform != RuntimePlatform.Android)
{
LogD("SDK only works on Android platform");
return;
}
try
{
// 创建Java回调对象
var initCallback = new ISDKInitCallback
{
onInitResult = callback
};
// 调用Java方法
GetAdClass().CallStatic("init", host, token, sid, appId, initCallback);
}
catch (Exception e)
{
LogE($"Initialize failed: {e.Message}");
}
}
// 其他接口封装
public static void SetDebug(bool enable) => GetAdClass().CallStatic("setDebug", enable);
public static void SetGDPRConsent(bool consent) => GetAdClass().CallStatic("setSubjectToGDPR", consent);
public static void SetUserConsent(string consent) => GetAdClass().CallStatic("setUserConsent", consent);
public static void SetUSPrivacy(string privacy) => GetAdClass().CallStatic("subjectToUSPrivacy", privacy);
public static void SetExtraParameters(Dictionary<string, object> parameters)
{
using AndroidJavaObject map = new AndroidJavaObject("java.util.HashMap");
foreach (var kv in parameters)
{
map.Call<AndroidJavaObject>("put", kv.Key, kv.Value);
}
GetAdClass().CallStatic("setExtraParameters", map);
}
// 获取网络信息
public static string GetNetworkName() => GetAdClass().CallStatic<string>("getNetWorkName");
public static string GetNetworkVersion() => GetAdClass().CallStatic<string>("getNetWorkVersion");
public static void LogD(string msg)
{
GetAdClass().CallStatic("LogD", msg);
}
public static void LogE(string msg)
{
GetAdClass().CallStatic("LogE", msg);
}
private static AndroidJavaClass GetAdClass()
{
if (_adClass == null)
{
_adClass = new AndroidJavaClass("com.rixengine.unity_plugin.RiEngineAd");
}
return _adClass;
}
}
}
View File
+157 -157
View File
@@ -1,157 +1,157 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace AD.VosacoSDK
{
public class VosacoInterAd
{
private AndroidJavaObject _interAd;
private VosacoInterAdListenerProxy _listenerProxy;
public VosacoInterAd(string unitId)
{
if (Application.platform != RuntimePlatform.Android)
return;
try
{
// 创建Java插屏广告对象
_interAd = new AndroidJavaObject("com.rixengine.unity_plugin.InterAd", unitId);
// 创建并设置监听器
_listenerProxy = new VosacoInterAdListenerProxy();
_interAd.Call("SetListener", _listenerProxy);
}
catch (Exception e)
{
VosacoAdSDK.LogE($"InterAd creation failed: {e.Message}");
}
}
// 加载广告
public void LoadAd()
{
if (!IsValid()) return;
try
{
_interAd.Call("Load");
}
catch (Exception e)
{
VosacoAdSDK.LogE($"LoadAd failed: {e.Message}");
}
}
// 显示广告
public void ShowAd()
{
if (!IsValid()) return;
try
{
_interAd.Call("Show");
}
catch (Exception e)
{
VosacoAdSDK.LogE($"ShowAd failed: {e.Message}");
}
}
// 检查广告是否就绪
public bool IsAdReady()
{
if (!IsValid()) return false;
try
{
return _interAd.Call<bool>("IsReady");
}
catch (Exception e)
{
VosacoAdSDK.LogE($"IsAdReady error :{e.Message}" );
}
return false;
}
// 获取广告价格
public double GetAdPrice()
{
if (!IsValid()) return 0;
try
{
return _interAd.Call<double>("GetPrice");
}
catch (Exception e)
{
VosacoAdSDK.LogE($"GetAdPrice error :{e.Message}");
}
return 0;
}
// 销毁广告对象
public void Destroy()
{
if (!IsValid()) return;
try
{
_interAd.Call("Destroy");
_interAd?.Dispose();
_interAd = null;
}
catch (Exception e)
{
VosacoAdSDK.LogE($"Destroy error :{e.Message}");
}
}
// 注册事件监听器
public void AddLoadedListener(Action callback)
=> _listenerProxy.OnLoaded += callback;
public void AddLoadFailedListener(Action callback)
=> _listenerProxy.OnLoadFailed += callback;
public void AddClickedListener(Action callback)
=> _listenerProxy.OnClicked += callback;
public void AddShowListener(Action callback)
=> _listenerProxy.OnShow += callback;
public void AddCloseListener(Action callback)
=> _listenerProxy.OnClose += callback;
public void AddVideoStartListener(Action callback)
=> _listenerProxy.OnVideoStart += callback;
public void AddVideoEndListener(Action callback)
=> _listenerProxy.OnVideoEnd += callback;
public void AddVideoErrorListener(Action callback)
=> _listenerProxy.OnVideoError += callback;
private bool IsValid()
{
if (Application.platform != RuntimePlatform.Android)
{
VosacoAdSDK.LogD("Interstitial ads only supported on Android");
return false;
}
if (_interAd == null)
{
VosacoAdSDK.LogE("Interstitial ad not initialized");
return false;
}
return true;
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace AD.VosacoSDK
{
public class VosacoInterAd
{
private AndroidJavaObject _interAd;
private VosacoInterAdListenerProxy _listenerProxy;
public VosacoInterAd(string unitId)
{
if (Application.platform != RuntimePlatform.Android)
return;
try
{
// 创建Java插屏广告对象
_interAd = new AndroidJavaObject("com.rixengine.unity_plugin.InterAd", unitId);
// 创建并设置监听器
_listenerProxy = new VosacoInterAdListenerProxy();
_interAd.Call("SetListener", _listenerProxy);
}
catch (Exception e)
{
VosacoAdSDK.LogE($"InterAd creation failed: {e.Message}");
}
}
// 加载广告
public void LoadAd()
{
if (!IsValid()) return;
try
{
_interAd.Call("Load");
}
catch (Exception e)
{
VosacoAdSDK.LogE($"LoadAd failed: {e.Message}");
}
}
// 显示广告
public void ShowAd()
{
if (!IsValid()) return;
try
{
_interAd.Call("Show");
}
catch (Exception e)
{
VosacoAdSDK.LogE($"ShowAd failed: {e.Message}");
}
}
// 检查广告是否就绪
public bool IsAdReady()
{
if (!IsValid()) return false;
try
{
return _interAd.Call<bool>("IsReady");
}
catch (Exception e)
{
VosacoAdSDK.LogE($"IsAdReady error :{e.Message}" );
}
return false;
}
// 获取广告价格
public double GetAdPrice()
{
if (!IsValid()) return 0;
try
{
return _interAd.Call<double>("GetPrice");
}
catch (Exception e)
{
VosacoAdSDK.LogE($"GetAdPrice error :{e.Message}");
}
return 0;
}
// 销毁广告对象
public void Destroy()
{
if (!IsValid()) return;
try
{
_interAd.Call("Destroy");
_interAd?.Dispose();
_interAd = null;
}
catch (Exception e)
{
VosacoAdSDK.LogE($"Destroy error :{e.Message}");
}
}
// 注册事件监听器
public void AddLoadedListener(Action callback)
=> _listenerProxy.OnLoaded += callback;
public void AddLoadFailedListener(Action callback)
=> _listenerProxy.OnLoadFailed += callback;
public void AddClickedListener(Action callback)
=> _listenerProxy.OnClicked += callback;
public void AddShowListener(Action callback)
=> _listenerProxy.OnShow += callback;
public void AddCloseListener(Action callback)
=> _listenerProxy.OnClose += callback;
public void AddVideoStartListener(Action callback)
=> _listenerProxy.OnVideoStart += callback;
public void AddVideoEndListener(Action callback)
=> _listenerProxy.OnVideoEnd += callback;
public void AddVideoErrorListener(Action callback)
=> _listenerProxy.OnVideoError += callback;
private bool IsValid()
{
if (Application.platform != RuntimePlatform.Android)
{
VosacoAdSDK.LogD("Interstitial ads only supported on Android");
return false;
}
if (_interAd == null)
{
VosacoAdSDK.LogE("Interstitial ad not initialized");
return false;
}
return true;
}
}
}
View File
+71 -71
View File
@@ -1,71 +1,71 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace AD.VosacoSDK
{
public class VosacoInterAdListenerProxy : AndroidJavaProxy
{
public event Action OnLoaded;
public event Action OnLoadFailed;
public event Action OnClicked;
public event Action OnShow;
public event Action OnClose;
public event Action OnVideoStart;
public event Action OnVideoEnd;
public event Action OnVideoError;
public VosacoInterAdListenerProxy()
: base("com.rixengine.unity_plugin.IInterAdListener") { }
public void onLoaded()
{
VosacoAdSDK.LogD($"UNITY INTER Call : onLoaded");
OnLoaded?.Invoke();
}
public void onLoadFailed()
{
VosacoAdSDK.LogD($"UNITY INTER Call : onLoadFailed");
OnLoadFailed?.Invoke();
}
public void onClicked()
{
VosacoAdSDK.LogD($"UNITY INTER Call : onClicked");
OnClicked?.Invoke();
}
public void onShow()
{
VosacoAdSDK.LogD($"UNITY INTER Call : onShow");
OnShow?.Invoke();
}
public void onClose()
{
VosacoAdSDK.LogD($"UNITY INTER Call : onClose");
OnClose?.Invoke();
}
public void onVideoStart()
{
VosacoAdSDK.LogD($"UNITY INTER Call : onVideoStart");
OnVideoStart?.Invoke();
}
public void onVideoEnd()
{
VosacoAdSDK.LogD($"UNITY INTER Call : onVideoEnd");
OnVideoEnd?.Invoke();
}
public void onVideoError()
{
VosacoAdSDK.LogD($"UNITY INTER Call : onVideoError");
OnVideoError?.Invoke();
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace AD.VosacoSDK
{
public class VosacoInterAdListenerProxy : AndroidJavaProxy
{
public event Action OnLoaded;
public event Action OnLoadFailed;
public event Action OnClicked;
public event Action OnShow;
public event Action OnClose;
public event Action OnVideoStart;
public event Action OnVideoEnd;
public event Action OnVideoError;
public VosacoInterAdListenerProxy()
: base("com.rixengine.unity_plugin.IInterAdListener") { }
public void onLoaded()
{
VosacoAdSDK.LogD($"UNITY INTER Call : onLoaded");
OnLoaded?.Invoke();
}
public void onLoadFailed()
{
VosacoAdSDK.LogD($"UNITY INTER Call : onLoadFailed");
OnLoadFailed?.Invoke();
}
public void onClicked()
{
VosacoAdSDK.LogD($"UNITY INTER Call : onClicked");
OnClicked?.Invoke();
}
public void onShow()
{
VosacoAdSDK.LogD($"UNITY INTER Call : onShow");
OnShow?.Invoke();
}
public void onClose()
{
VosacoAdSDK.LogD($"UNITY INTER Call : onClose");
OnClose?.Invoke();
}
public void onVideoStart()
{
VosacoAdSDK.LogD($"UNITY INTER Call : onVideoStart");
OnVideoStart?.Invoke();
}
public void onVideoEnd()
{
VosacoAdSDK.LogD($"UNITY INTER Call : onVideoEnd");
OnVideoEnd?.Invoke();
}
public void onVideoError()
{
VosacoAdSDK.LogD($"UNITY INTER Call : onVideoError");
OnVideoError?.Invoke();
}
}
}
+155 -155
View File
@@ -1,155 +1,155 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace AD.VosacoSDK
{
public class VosacoRewardAd
{
private AndroidJavaObject _rewardAd;
private VosacoRewardAdListenerProxy _listenerProxy;
public VosacoRewardAd(string unitId)
{
if (Application.platform != RuntimePlatform.Android)
return;
try
{
// 创建Java插屏广告对象
_rewardAd = new AndroidJavaObject("com.rixengine.unity_plugin.RewardAd", unitId);
// 创建并设置监听器
_listenerProxy = new VosacoRewardAdListenerProxy();
_rewardAd.Call("SetListener", _listenerProxy);
}
catch (Exception e)
{
VosacoAdSDK.LogE($"RewardAd creation failed: {e.Message}");
}
}
// 加载广告
public void LoadAd()
{
if (!IsValid()) return;
try
{
_rewardAd.Call("Load");
}
catch (Exception e)
{
VosacoAdSDK.LogE($"LoadAd failed: {e.Message}");
}
}
// 显示广告
public void ShowAd()
{
if (!IsValid()) return;
try
{
_rewardAd.Call("Show");
}
catch (Exception e)
{
VosacoAdSDK.LogE($"ShowAd failed: {e.Message}");
}
}
// 检查广告是否就绪
public bool IsAdReady()
{
if (!IsValid()) return false;
try
{
return _rewardAd.Call<bool>("IsReady");
}
catch (Exception e)
{
VosacoAdSDK.LogE($"IsAdReady error :{e.Message}");
}
return false;
}
// 获取广告价格
public double GetAdPrice()
{
if (!IsValid()) return 0;
try
{
return _rewardAd.Call<double>("GetPrice");
}
catch (Exception e)
{
VosacoAdSDK.LogE($"GetAdPrice error :{e.Message}");
}
return 0;
}
// 销毁广告对象
public void Destroy()
{
if (!IsValid()) return;
try
{
_rewardAd.Call("Destroy");
_rewardAd?.Dispose();
_rewardAd = null;
}
catch (Exception e)
{
VosacoAdSDK.LogE($"Destroy error :{e.Message}");
}
}
// 注册事件监听器
public void AddLoadedListener(Action callback)
=> _listenerProxy.OnLoaded += callback;
public void AddLoadFailedListener(Action callback)
=> _listenerProxy.OnLoadFailed += callback;
public void AddClickedListener(Action callback)
=> _listenerProxy.OnClicked += callback;
public void AddRewardListener(Action callback)
=> _listenerProxy.OnReward += callback;
public void AddCloseListener(Action callback)
=> _listenerProxy.OnClose += callback;
public void AddVideoStartListener(Action callback)
=> _listenerProxy.OnVideoStart += callback;
public void AddVideoEndListener(Action callback)
=> _listenerProxy.OnVideoEnd += callback;
public void AddVideoErrorListener(Action callback)
=> _listenerProxy.OnVideoError += callback;
private bool IsValid()
{
if (Application.platform != RuntimePlatform.Android)
{
VosacoAdSDK.LogD("Interstitial ads only supported on Android");
return false;
}
if (_rewardAd == null)
{
VosacoAdSDK.LogE("Interstitial ad not initialized");
return false;
}
return true;
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace AD.VosacoSDK
{
public class VosacoRewardAd
{
private AndroidJavaObject _rewardAd;
private VosacoRewardAdListenerProxy _listenerProxy;
public VosacoRewardAd(string unitId)
{
if (Application.platform != RuntimePlatform.Android)
return;
try
{
// 创建Java插屏广告对象
_rewardAd = new AndroidJavaObject("com.rixengine.unity_plugin.RewardAd", unitId);
// 创建并设置监听器
_listenerProxy = new VosacoRewardAdListenerProxy();
_rewardAd.Call("SetListener", _listenerProxy);
}
catch (Exception e)
{
VosacoAdSDK.LogE($"RewardAd creation failed: {e.Message}");
}
}
// 加载广告
public void LoadAd()
{
if (!IsValid()) return;
try
{
_rewardAd.Call("Load");
}
catch (Exception e)
{
VosacoAdSDK.LogE($"LoadAd failed: {e.Message}");
}
}
// 显示广告
public void ShowAd()
{
if (!IsValid()) return;
try
{
_rewardAd.Call("Show");
}
catch (Exception e)
{
VosacoAdSDK.LogE($"ShowAd failed: {e.Message}");
}
}
// 检查广告是否就绪
public bool IsAdReady()
{
if (!IsValid()) return false;
try
{
return _rewardAd.Call<bool>("IsReady");
}
catch (Exception e)
{
VosacoAdSDK.LogE($"IsAdReady error :{e.Message}");
}
return false;
}
// 获取广告价格
public double GetAdPrice()
{
if (!IsValid()) return 0;
try
{
return _rewardAd.Call<double>("GetPrice");
}
catch (Exception e)
{
VosacoAdSDK.LogE($"GetAdPrice error :{e.Message}");
}
return 0;
}
// 销毁广告对象
public void Destroy()
{
if (!IsValid()) return;
try
{
_rewardAd.Call("Destroy");
_rewardAd?.Dispose();
_rewardAd = null;
}
catch (Exception e)
{
VosacoAdSDK.LogE($"Destroy error :{e.Message}");
}
}
// 注册事件监听器
public void AddLoadedListener(Action callback)
=> _listenerProxy.OnLoaded += callback;
public void AddLoadFailedListener(Action callback)
=> _listenerProxy.OnLoadFailed += callback;
public void AddClickedListener(Action callback)
=> _listenerProxy.OnClicked += callback;
public void AddRewardListener(Action callback)
=> _listenerProxy.OnReward += callback;
public void AddCloseListener(Action callback)
=> _listenerProxy.OnClose += callback;
public void AddVideoStartListener(Action callback)
=> _listenerProxy.OnVideoStart += callback;
public void AddVideoEndListener(Action callback)
=> _listenerProxy.OnVideoEnd += callback;
public void AddVideoErrorListener(Action callback)
=> _listenerProxy.OnVideoError += callback;
private bool IsValid()
{
if (Application.platform != RuntimePlatform.Android)
{
VosacoAdSDK.LogD("Interstitial ads only supported on Android");
return false;
}
if (_rewardAd == null)
{
VosacoAdSDK.LogE("Interstitial ad not initialized");
return false;
}
return true;
}
}
}
View File
+73 -73
View File
@@ -1,73 +1,73 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace AD.VosacoSDK
{
public class VosacoRewardAdListenerProxy : AndroidJavaProxy
{
public event Action OnLoaded;
public event Action OnLoadFailed;
public event Action OnClicked;
public event Action OnReward;
public event Action OnClose;
public event Action OnVideoStart;
public event Action OnVideoEnd;
public event Action OnVideoError;
public VosacoRewardAdListenerProxy()
: base("com.rixengine.unity_plugin.IRewardListener")
{
}
public void onLoaded()
{
VosacoAdSDK.LogD($"UNITY Reward Call : onLoaded");
OnLoaded?.Invoke();
}
public void onLoadFailed()
{
VosacoAdSDK.LogD($"UNITY Reward Call : onLoadFailed");
OnLoadFailed?.Invoke();
}
public void onRewardPlayStart()
{
VosacoAdSDK.LogD($"UNITY Reward Call : onRewardPlayStart");
OnVideoStart?.Invoke();
}
public void onRewardPlayEnd()
{
VosacoAdSDK.LogD($"UNITY Reward Call : onRewardPlayEnd");
OnVideoEnd?.Invoke();
}
public void onRewardPlayFailed()
{
VosacoAdSDK.LogD($"UNITY Reward Call : onRewardPlayFailed");
OnVideoError?.Invoke();
}
public void onRewardClosed()
{
VosacoAdSDK.LogD($"UNITY Reward Call : onRewardClosed");
OnClose?.Invoke();
}
public void onRewardClicked()
{
VosacoAdSDK.LogD($"UNITY Reward Call : onRewardClicked");
OnClicked?.Invoke();
}
public void onReward()
{
VosacoAdSDK.LogD($"UNITY Reward Call : onReward");
OnReward?.Invoke();
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace AD.VosacoSDK
{
public class VosacoRewardAdListenerProxy : AndroidJavaProxy
{
public event Action OnLoaded;
public event Action OnLoadFailed;
public event Action OnClicked;
public event Action OnReward;
public event Action OnClose;
public event Action OnVideoStart;
public event Action OnVideoEnd;
public event Action OnVideoError;
public VosacoRewardAdListenerProxy()
: base("com.rixengine.unity_plugin.IRewardListener")
{
}
public void onLoaded()
{
VosacoAdSDK.LogD($"UNITY Reward Call : onLoaded");
OnLoaded?.Invoke();
}
public void onLoadFailed()
{
VosacoAdSDK.LogD($"UNITY Reward Call : onLoadFailed");
OnLoadFailed?.Invoke();
}
public void onRewardPlayStart()
{
VosacoAdSDK.LogD($"UNITY Reward Call : onRewardPlayStart");
OnVideoStart?.Invoke();
}
public void onRewardPlayEnd()
{
VosacoAdSDK.LogD($"UNITY Reward Call : onRewardPlayEnd");
OnVideoEnd?.Invoke();
}
public void onRewardPlayFailed()
{
VosacoAdSDK.LogD($"UNITY Reward Call : onRewardPlayFailed");
OnVideoError?.Invoke();
}
public void onRewardClosed()
{
VosacoAdSDK.LogD($"UNITY Reward Call : onRewardClosed");
OnClose?.Invoke();
}
public void onRewardClicked()
{
VosacoAdSDK.LogD($"UNITY Reward Call : onRewardClicked");
OnClicked?.Invoke();
}
public void onReward()
{
VosacoAdSDK.LogD($"UNITY Reward Call : onReward");
OnReward?.Invoke();
}
}
}
+3 -3
View File
@@ -1,3 +1,3 @@
{
"name": "WebView"
}
{
"name": "WebView"
}
View File
+31
View File
@@ -0,0 +1,31 @@
# Changelog
All notable changes to this package will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [1.2.0] - 2021-09-21
Do not show Context Screen for iOS versions below 14.5
Use NSInvocation instead of performSelector for SkAdNetwork methods
Expose RequestTrackingAuthorization callback
## [1.0.0] - 2021-04-22
First Stable Release
Updates to the Context Screen sample and the README
## [0.2.0-preview.3] - 2021-04-19
Added Context Screen Sample
## [0.1.0-preview.3] - 2021-04-12
Fixed a typo in updateConversionValue
## [0.1.0-preview.2] - 2020-12-04
Fix an issue that caused a warning on some metafiles in Unity 2018.4
## [0.1.0-preview.1] - 2020-12-04
### This is the first release of com.unity.ads.ios-support package
Add Support for SKADID Spec (Postbuild process automatically adding SKAdNetwork Ids to Info.plsit)
Add Support for App Tracking Transparency API's (introduced in ios14)
Add Support for SKAdNetwork API's (introduced in ios14)
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2dc7a87feb07749a9855db38a51426d3
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8fbdef3bbd2c4402f9fb8749b4be0cbc
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,37 @@
//
// Copyright 2020
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("Unity.Advertisement.IosSupport.Editor")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Unity Technologies")]
[assembly: AssemblyProduct("Monetization")]
[assembly: AssemblyCopyright("Copyright © Unity Technologies 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("0.1.0")]
[assembly: InternalsVisibleTo("Unity.Advertisement.IosSupport.Editor.Tests")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fe609725aa1304d10bd0232f8a727830
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 607c1fecf0d392648963a0725308d841
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,127 @@
#if UNITY_IOS
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
using System.IO;
using System.Collections.Generic;
using UnityEngine;
public class ConfigurableLocalizationPostProcess
{
[PostProcessBuild(500)]
public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject)
{
if (target != BuildTarget.iOS) return;
// 加载配置
IOSLocalizationSettings settings = AssetDatabase.LoadAssetAtPath<IOSLocalizationSettings>("Assets/Editor/LocalizationSettings.asset");
if (settings == null)
{
UnityEngine.Debug.LogWarning("未找到LocalizationSettings配置,使用默认多语言设置");
settings = ScriptableObject.CreateInstance<IOSLocalizationSettings>();
}
// 处理主Info.plist
string plistPath = Path.Combine(pathToBuiltProject, "Info.plist");
if (!File.Exists(plistPath))
{
UnityEngine.Debug.LogWarning("Info.plist文件未找到: " + plistPath);
return;
}
PlistDocument plist = new PlistDocument();
plist.ReadFromFile(plistPath);
PlistElementDict rootDict = plist.root;
// 查找英语描述或使用第一个描述作为默认
string defaultDescription = settings.languageDescriptions[0].trackingDescription;
foreach (var desc in settings.languageDescriptions)
{
if (desc.languageCode == "en")
{
defaultDescription = desc.trackingDescription;
break;
}
}
rootDict.SetString("NSUserTrackingUsageDescription", defaultDescription);
plist.WriteToFile(plistPath);
// 为每种语言创建本地化文件
foreach (var langDesc in settings.languageDescriptions)
{
if (langDesc.languageCode == "en") continue;
string lprojPath = Path.Combine(pathToBuiltProject, $"{langDesc.languageCode}.lproj");
if (!Directory.Exists(lprojPath))
{
Directory.CreateDirectory(lprojPath);
}
string stringsPath = Path.Combine(lprojPath, "InfoPlist.strings");
using (StreamWriter writer = new StreamWriter(stringsPath, false, System.Text.Encoding.UTF8))
{
writer.WriteLine($"\"NSUserTrackingUsageDescription\" = \"{langDesc.trackingDescription}\";");
}
}
// 更新Xcode项目
UpdateXcodeProject(pathToBuiltProject, settings);
UnityEngine.Debug.Log("多语言隐私描述已成功添加到Xcode项目。");
}
private static void UpdateXcodeProject(string pathToBuiltProject, IOSLocalizationSettings settings)
{
string pbxProjectPath = PBXProject.GetPBXProjectPath(pathToBuiltProject);
PBXProject pbxProject = new PBXProject();
pbxProject.ReadFromFile(pbxProjectPath);
string targetGuid = pbxProject.GetUnityMainTargetGuid();
foreach (var langDesc in settings.languageDescriptions)
{
if (langDesc.languageCode == "en") continue;
string lprojPath = $"{langDesc.languageCode}.lproj";
string stringsPath = Path.Combine(lprojPath, "InfoPlist.strings");
string fileGuid = pbxProject.AddFile(stringsPath, stringsPath, PBXSourceTree.Source);
pbxProject.AddFileToBuild(targetGuid, fileGuid);
}
pbxProject.WriteToFile(pbxProjectPath);
}
}
// 创建配置文件的编辑器菜单
public class LocalizationSettingsCreator
{
[MenuItem("Tools/IOS Localization Settings")]
public static void CreateLocalizationSettings()
{
IOSLocalizationSettings asset = ScriptableObject.CreateInstance<IOSLocalizationSettings>();
string path = AssetDatabase.GetAssetPath(Selection.activeObject);
if (string.IsNullOrEmpty(path))
{
path = "Assets";
}
else if (!string.IsNullOrEmpty(Path.GetExtension(path)))
{
path = path.Replace(Path.GetFileName(AssetDatabase.GetAssetPath(Selection.activeObject)), "");
}
string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath(path + "/LocalizationSettings.asset");
AssetDatabase.CreateAsset(asset, assetPathAndName);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
EditorUtility.FocusProjectWindow();
Selection.activeObject = asset;
}
}
#endif
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dd5e9ca7b91cb6f42bf881e421a76f78
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,26 @@
#if UNITY_IOS
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 可配置的多语言描述ScriptableObject
public class IOSLocalizationSettings : ScriptableObject
{
[System.Serializable]
public class LanguageDescription
{
public string languageCode;
public string trackingDescription;
}
public List<LanguageDescription> languageDescriptions = new List<LanguageDescription>
{
new LanguageDescription { languageCode = "en", trackingDescription = "Allow tracking to reduce irrelevant ads and keep the app free." },
new LanguageDescription { languageCode = "ja", trackingDescription = "トラッキングを許可すると、無関係な広告を減らしてアプリを無料で利用できます。" },
new LanguageDescription { languageCode = "fr", trackingDescription = "Autoriser le suivi pour réduire les publicités non pertinentes et garder lapplication gratuite" },
new LanguageDescription { languageCode = "pt", trackingDescription = "Permitir rastreamento para reduzir anúncios irrelevantes e manter o app gratuito." }
};
}
#endif
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bc4ec6cde9a2a4941ada2f568bf230d8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7c12ab5a1ea52495bbfe2f28879f608e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,11 @@
using System.Collections.Generic;
using UnityEngine;
namespace Unity.Advertisement.IosSupport.Editor
{
internal interface ISkAdNetworkParser
{
string GetExtension();
HashSet<string> ParseSource(ISkAdNetworkSource source);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 97e0c61e3aa704af086868b25f08f85a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,9 @@
namespace Unity.Advertisement.IosSupport.Editor
{
public static class SkAdNetworkFileExtension
{
public const string XML = "xml";
public const string JSON = "json";
public const string NONE = "";
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e496c38bf001040ecbe70e444a0542fb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
namespace Unity.Advertisement.IosSupport.Editor
{
internal class SkAdNetworkJsonParser : ISkAdNetworkParser
{
[Serializable]
public class SkAdNetworkIdArray
{
public List<SkAdNetworkInfo> skadnetwork_ids;
}
[Serializable]
public class SkAdNetworkInfo
{
public string skadnetwork_id;
}
public string GetExtension()
{
return SkAdNetworkFileExtension.JSON;
}
public HashSet<string> ParseSource(ISkAdNetworkSource source)
{
var foundIds = new HashSet<string>();
try
{
string jsonData;
using (var stream = source.Open())
{
if (stream == null)
{
Debug.LogWarning($"[Unity SKAdNetwork Parser] Unable to parse SKAdNetwork file: {source.Path}");
return foundIds;
}
jsonData = new StreamReader(stream).ReadToEnd();
}
SkAdNetworkIdArray skAdNetworkCompanyInfo = null;
try
{
skAdNetworkCompanyInfo = JsonUtility.FromJson<SkAdNetworkIdArray>(jsonData);
}
catch (Exception) {}
//Fallback to try and see if this is a JSONObject which contains an array element called skadnetwork_ids instead of the expected JSONArray
if (skAdNetworkCompanyInfo?.skadnetwork_ids == null || skAdNetworkCompanyInfo.skadnetwork_ids.Count == 0)
{
var updatedJson = "{\"skadnetwork_ids\":" + jsonData + "}";
skAdNetworkCompanyInfo = JsonUtility.FromJson<SkAdNetworkIdArray>(updatedJson);
}
if (skAdNetworkCompanyInfo?.skadnetwork_ids == null)
{
Debug.LogWarning($"[Unity SKAdNetwork Parser] Unable to parse SKAdNetwork file: {source.Path}");
return foundIds;
}
foundIds.UnionWith(skAdNetworkCompanyInfo.skadnetwork_ids.Select(t => t.skadnetwork_id).Where(t => t != null));
}
catch (Exception)
{
Debug.LogWarning($"[Unity SKAdNetwork Parser] Unable to parse SKAdNetwork file: {source.Path}");
}
return foundIds;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9840479aaa6504c9ea96572abd23249c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
namespace Unity.Advertisement.IosSupport.Editor
{
internal static class SkAdNetworkParser
{
private static Dictionary<string, ISkAdNetworkParser> s_Parsers;
static SkAdNetworkParser()
{
s_Parsers = new Dictionary<string, ISkAdNetworkParser>
{
{ SkAdNetworkFileExtension.XML, new SkAdNetworkXmlParser() },
{ SkAdNetworkFileExtension.JSON, new SkAdNetworkJsonParser() },
{ SkAdNetworkFileExtension.NONE, new SkAdNetworkUrlParser() }
};
}
public static ISkAdNetworkParser GetParser(string parserType)
{
try
{
s_Parsers.TryGetValue(parserType, out var parser);
return parser;
}
catch (Exception) {}
return null;
}
public static IEnumerable<ISkAdNetworkParser> GetAllParsers()
{
return s_Parsers.Values;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f70ff3726241b4d2b8d0ea012c80e706
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
namespace Unity.Advertisement.IosSupport.Editor
{
internal class SkAdNetworkUrlParser : ISkAdNetworkParser
{
public string GetExtension()
{
return SkAdNetworkFileExtension.NONE;
}
public HashSet<string> ParseSource(ISkAdNetworkSource source)
{
var foundIds = new HashSet<string>();
try
{
string[] lines;
using (var reader = new StreamReader(source.Open()))
{
lines = reader.ReadToEnd().Split(Environment.NewLine.ToCharArray());
}
lines.Where(url => !string.IsNullOrEmpty(url))
.Where(url => Uri.IsWellFormedUriString(url, UriKind.Absolute))
.ToList().ForEach(url => {
ISkAdNetworkParser parser = null;
switch (GetExtensionFromPath(url))
{
case SkAdNetworkFileExtension.XML:
parser = SkAdNetworkParser.GetParser(SkAdNetworkFileExtension.XML);
break;
case SkAdNetworkFileExtension.JSON:
parser = SkAdNetworkParser.GetParser(SkAdNetworkFileExtension.JSON);
break;
}
if (parser == null)
{
Debug.LogWarning($"[Unity SKAdNetwork Parser] Unsupported file extension, No parser available to parse SKAdNetwork file: {source.Path} ");
return;
}
foundIds.UnionWith(parser.ParseSource(new SkAdNetworkRemoteSource(url)));
});
}
catch (Exception)
{
Debug.LogWarning($"[Unity SKAdNetwork Parser] Unable to parse SKAdNetwork file: {source.Path}");
}
return foundIds;
}
/// <summary>
/// Gets the extension for a filepath string
/// </summary>
private static string GetExtensionFromPath(string filepath)
{
var extension = Path.GetExtension(filepath);
return string.IsNullOrEmpty(extension) ? "" : extension.Substring(1).ToLower();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 95e1f9f2b229246a08a2354f8c702ae9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Xml;
using UnityEngine;
namespace Unity.Advertisement.IosSupport.Editor
{
internal class SkAdNetworkXmlParser : ISkAdNetworkParser
{
private const string k_SkAdNetworkIdentifier = "SKAdNetworkIdentifier";
public string GetExtension()
{
return SkAdNetworkFileExtension.XML;
}
public HashSet<string> ParseSource(ISkAdNetworkSource source)
{
var foundIds = new HashSet<string>();
try
{
var xmlDocument = new XmlDocument();
using (var stream = source.Open())
{
if (stream == null)
{
Debug.LogWarning("[Unity SKAdNetwork Parser] Unable to parse SKAdNetwork file: {source.Path}");
return foundIds;
}
xmlDocument.Load(stream);
}
var items = xmlDocument.GetElementsByTagName("key");
for (var x = 0; x < items.Count; x++)
{
if (items[x].InnerText == k_SkAdNetworkIdentifier)
{
var nextSibling = items[x]?.NextSibling;
if (nextSibling != null)
{
foundIds.Add(nextSibling.InnerText);
}
}
}
}
catch (Exception)
{
Debug.LogWarning($"[Unity SKAdNetwork Parser] Unable to parse SKAdNetwork file: {source.Path}");
}
return foundIds;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b62c9c75b6cf84b3db11f5bb9f036169
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,118 @@
#if UNITY_2018_1_OR_NEWER && UNITY_IOS
using System;
using System.IO;
using UnityEngine;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.iOS.Xcode;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.Build.Reporting;
namespace Unity.Advertisement.IosSupport.Editor
{
internal class PostProcessBuildPlist : IPostprocessBuildWithReport
{
public int callbackOrder => 0;
private const string k_SkAdNetworkIdentifier = "SKAdNetworkIdentifier";
private const string k_SkAdNetworkItems = "SKAdNetworkItems";
private const string k_SkAdNetworksFileName = "SKAdNetworks";
public void OnPostprocessBuild(BuildReport report)
{
if (report.summary.platform != BuildTarget.iOS)
{
return;
}
UpdateInfoPlistWithSkAdNetworkIds(report.summary.outputPath);
}
internal static void UpdateInfoPlistWithSkAdNetworkIds(string pathToPlistFile)
{
var provider = new SkAdNetworkLocalSourceProvider();
var ids = new HashSet<string>();
try
{
SkAdNetworkParser.GetAllParsers().ToList().ForEach(parser => {
provider.GetSources(k_SkAdNetworksFileName, parser.GetExtension()).ToList().ForEach(source => {
ids.UnionWith(parser.ParseSource(source));
});
});
}
catch (Exception e)
{
Debug.LogError($"Failed to parse SKAdNetwork files due to following reason: {e.Message}");
}
try
{
WriteSkAdNetworkIdsToInfoPlist(ids, pathToPlistFile);
}
catch (Exception e)
{
Debug.LogError($"Failed to update info.plist file due to following reason: {e.Message}");
}
}
/// <summary>
/// Write all plistValues to an existing Info.plist file
/// </summary>
internal static void WriteSkAdNetworkIdsToInfoPlist(HashSet<string> skAdNetworkIds, string outputPath)
{
var infoPlistPath = outputPath + "/Info.plist";
var plist = new PlistDocument();
plist.ReadFromString(File.ReadAllText(infoPlistPath));
var root = plist.root;
if (root == null)
{
Debug.LogWarning("[Unity SKAdNetwork Parser] Unable to parse info.plist. Unable to add SkAdNetwork Identifiers.");
return;
}
if (!root.values?.ContainsKey(k_SkAdNetworkItems) ?? false)
{
root.CreateArray(k_SkAdNetworkItems);
}
var adNetworkItems = root[k_SkAdNetworkItems].AsArray();
if (adNetworkItems == null)
{
Debug.LogWarning("[Unity SKAdNetwork Parser] Unable to modify existing info.plist. Unable to add SkAdNetwork Identifiers.");
return;
}
foreach (var adNetworkId in skAdNetworkIds)
{
if (!PlistContainsAdNetworkId(adNetworkItems, adNetworkId))
{
adNetworkItems.AddDict().SetString(k_SkAdNetworkIdentifier, adNetworkId);
}
}
File.WriteAllText(infoPlistPath, plist.WriteToString());
}
/// <summary>
/// Check if the value is already contained in the plist
/// </summary>
internal static bool PlistContainsAdNetworkId(PlistElementArray adNetworkItems, string adNetworkId)
{
foreach (var adNetworkItem in adNetworkItems.values)
{
var item = adNetworkItem.AsDict();
if (item.values.TryGetValue(k_SkAdNetworkIdentifier, out var value))
{
if (value.AsString() == adNetworkId)
{
return true;
}
}
}
return false;
}
}
}
#endif //UNITY_2018_1_OR_NEWER
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e7bc5a6e424ec49089ca10bdb43d4c42
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b2b15b7af045b42dabe70a3914e67cba
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,11 @@
using System.IO;
using UnityEngine;
namespace Unity.Advertisement.IosSupport.Editor
{
internal interface ISkAdNetworkSource
{
string Path { get; }
Stream Open();
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b3b688cb4385c4ed287404f01d47d2cf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,21 @@
using System;
using System.IO;
using UnityEngine;
namespace Unity.Advertisement.IosSupport.Editor
{
internal class SkAdNetworkLocalSource : ISkAdNetworkSource
{
public string Path { get; }
public SkAdNetworkLocalSource(string path)
{
Path = path;
}
public Stream Open()
{
return new FileStream(Path, FileMode.Open);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bc26fb3115fcd455f8d1d7b9739bc0f5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
namespace Unity.Advertisement.IosSupport.Editor
{
/// <summary>
/// Responsible for finding all SkAdNetwork files on the local filesystem by searching through the users project directory and all includes packages.
/// </summary>
internal class SkAdNetworkLocalSourceProvider
{
private const int k_MaxPackageLookupTimeoutInSeconds = 30;
private string[] m_PackagePaths;
public SkAdNetworkLocalSourceProvider()
{
m_PackagePaths = GetAllPackagePaths();
}
public IEnumerable<SkAdNetworkLocalSource> GetSources(string filename, string extension)
{
return GetLocalFilePaths(filename, extension).Select(x => new SkAdNetworkLocalSource(x)).ToArray();
}
/// <summary>
/// Finds a file on the local filesystem by looking the project directory, and all package directories
/// </summary>
/// <param name="filename">the filename to look for</param>
/// <param name="fileExtension">the filename extension to look for</param>
/// <returns>a full path to the file</returns>
private IEnumerable<string> GetLocalFilePaths(string filename, string fileExtension)
{
return m_PackagePaths
.Prepend(Directory.GetCurrentDirectory())
.SelectMany(path => Directory.GetFiles(path, string.IsNullOrEmpty(fileExtension) ? filename : $"{filename}.{fileExtension}" , SearchOption.AllDirectories))
.ToList();
}
/// <summary>
/// Returns a list of paths to the root folder of each package included in the users project.
/// These may be in different locations on disk depending on where the package is being stored/cached.
/// </summary>
private static string[] GetAllPackagePaths(bool offlineMode = true)
{
var list = UnityEditor.PackageManager.Client.List(offlineMode);
if (list == null)
{
return Array.Empty<string>();
}
var timeSpan = TimeSpan.FromSeconds(k_MaxPackageLookupTimeoutInSeconds);
var startTime = DateTime.Now;
while (!list.IsCompleted && (DateTime.Now - startTime) < timeSpan)
{
Thread.Sleep(10);
}
if (list.Error != null)
{
return Array.Empty<string>();
}
return list.Result.Select(packageInfo => packageInfo.assetPath).ToArray();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5d925f4b6523544bbbfa58d11df1ac49
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,21 @@
using System.IO;
using System.Net;
using UnityEngine;
namespace Unity.Advertisement.IosSupport.Editor
{
internal class SkAdNetworkRemoteSource : ISkAdNetworkSource
{
public string Path { get; }
public SkAdNetworkRemoteSource(string path)
{
Path = path;
}
public Stream Open()
{
return new WebClient().OpenRead(Path);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fc886aae4a1fc42b48e8b6deccb67ab5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,15 @@
{
"name": "Unity.Advertisement.IosSupport.Editor",
"references": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 782c39a29bdf44a569029c0fc1c6d458
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+201
View File
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2020 Unity Technologies
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Some files were not shown because too many files have changed in this diff Show More