android
This commit is contained in:
parent
6ef7de12af
commit
eb10c29940
@ -18,7 +18,7 @@ namespace BFEditor.Build
|
||||
private static int VersionCodeRU = 12;
|
||||
private static string VersionNameRU = "0.4.9";
|
||||
BFPlatformOptions platform = BFPlatformOptions.AndroidDev;
|
||||
const string ANDROID_GP_PACKAGE_NAME = "com.c1.dev.android";
|
||||
const string ANDROID_GP_PACKAGE_NAME = "com.fortune.td.game.global";
|
||||
|
||||
public BuildProjectWindow()
|
||||
{
|
||||
|
||||
@ -42,7 +42,7 @@ namespace BF
|
||||
// 渠道对应的语言配置
|
||||
public static Dictionary<string, BFLanguageInfo> languageInfos = new Dictionary<string, BFLanguageInfo>()
|
||||
{
|
||||
{"com.c1.dev.android", new BFLanguageInfo(new List<string>{"en", "cn", "zh", "th", "ru", "id", "vi"})},
|
||||
{"com.fortune.td.game.global", new BFLanguageInfo(new List<string>{"en", "cn", "zh", "th", "ru", "id", "vi"})},
|
||||
{"com.juzu.b6.dev.android", new BFLanguageInfo(new List<string>{"en", "cn", "zh", "th", "ru", "id", "vi"})},
|
||||
{"com.juzu.b6.dev.ios", new BFLanguageInfo(new List<string>{"en", "cn"})},
|
||||
{"com.juzu.b6.release.android", new BFLanguageInfo(new List<string>{"en"})},
|
||||
|
||||
2
BFVersions/android/dz_dev/build.gradle
Normal file → Executable file
2
BFVersions/android/dz_dev/build.gradle
Normal file → Executable file
@ -8,7 +8,7 @@ buildscript {
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.0.1'
|
||||
// classpath 'com.google.gms:google-services:4.3.13'
|
||||
classpath 'com.google.gms:google-services:4.3.13'
|
||||
// classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.1'
|
||||
}
|
||||
}
|
||||
|
||||
0
BFVersions/android/dz_dev/gradle.properties
Normal file → Executable file
0
BFVersions/android/dz_dev/gradle.properties
Normal file → Executable file
54
BFVersions/android/dz_dev/unityLibrary/build.gradle
Normal file → Executable file
54
BFVersions/android/dz_dev/unityLibrary/build.gradle
Normal file → Executable file
@ -10,16 +10,10 @@ apply plugin: 'com.android.library'
|
||||
url "https://maven.google.com"
|
||||
}
|
||||
maven {
|
||||
url "https://android-sdk.is.com/" // Assets/IronSource/Editor/IronSourceSDKDependencies.xml:9, Assets/IronSource/Editor/ISAdColonyAdapterDependencies.xml:16, Assets/IronSource/Editor/ISAdMobAdapterDependencies.xml:16, Assets/IronSource/Editor/ISAppLovinAdapterDependencies.xml:8, Assets/IronSource/Editor/ISChartboostAdapterDependencies.xml:8, Assets/IronSource/Editor/ISFacebookAdapterDependencies.xml:16, Assets/IronSource/Editor/ISLiftoffAdapterDependencies.xml:16, Assets/IronSource/Editor/ISPangleAdapterDependencies.xml:8, Assets/IronSource/Editor/ISTapJoyAdapterDependencies.xml:8, Assets/IronSource/Editor/ISUnityAdsAdapterDependencies.xml:8
|
||||
url "https://android-sdk.is.com/" // Assets/IronSource/Editor/IronSourceSDKDependencies.xml:9, Assets/IronSource/Editor/ISAdMobAdapterDependencies.xml:16, Assets/IronSource/Editor/ISAppLovinAdapterDependencies.xml:8, Assets/IronSource/Editor/ISFacebookAdapterDependencies.xml:16, Assets/IronSource/Editor/ISUnityAdsAdapterDependencies.xml:8
|
||||
}
|
||||
maven {
|
||||
url "https://maven.google.com/" // Assets/IronSource/Editor/IronSourceSDKDependencies.xml:17, Assets/IronSource/Editor/IronSourceSDKDependencies.xml:25, Assets/IronSource/Editor/ISAdColonyAdapterDependencies.xml:8, Assets/IronSource/Editor/ISAdMobAdapterDependencies.xml:8, Assets/IronSource/Editor/ISAppLovinAdapterDependencies.xml:15, Assets/IronSource/Editor/ISChartboostAdapterDependencies.xml:15, Assets/IronSource/Editor/ISFacebookAdapterDependencies.xml:8, Assets/IronSource/Editor/ISLiftoffAdapterDependencies.xml:8, Assets/IronSource/Editor/ISUnityAdsAdapterDependencies.xml:15
|
||||
}
|
||||
maven {
|
||||
url "https://artifact.bytedance.com/repository/pangle/" // Assets/IronSource/Editor/ISPangleAdapterDependencies.xml:15
|
||||
}
|
||||
maven {
|
||||
url "https://sdk.tapjoy.com/" // Assets/IronSource/Editor/ISTapJoyAdapterDependencies.xml:15
|
||||
url "https://maven.google.com/" // Assets/IronSource/Editor/IronSourceSDKDependencies.xml:17, Assets/IronSource/Editor/IronSourceSDKDependencies.xml:25, Assets/IronSource/Editor/ISAdMobAdapterDependencies.xml:8, Assets/IronSource/Editor/ISAppLovinAdapterDependencies.xml:15, Assets/IronSource/Editor/ISFacebookAdapterDependencies.xml:8, Assets/IronSource/Editor/ISUnityAdsAdapterDependencies.xml:15
|
||||
}
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
@ -38,47 +32,31 @@ dependencies {
|
||||
implementation(name: 'facebook-android-wrapper-11.0.0', ext:'aar')
|
||||
implementation 'com.google.android.gms:play-services-auth:20.1.0'
|
||||
implementation "com.android.billingclient:billing:5.0.0"
|
||||
|
||||
// firebase
|
||||
// implementation 'com.google.firebase:firebase-analytics:21.1.0'
|
||||
// implementation 'com.google.firebase:firebase-crashlytics:18.2.12'
|
||||
// implementation 'com.google.firebase:firebase-messaging:23.0.8'
|
||||
|
||||
// Android Resolver Dependencies Start
|
||||
implementation 'com.adcolony:sdk:4.8.0' // Assets/IronSource/Editor/ISAdColonyAdapterDependencies.xml:8
|
||||
// Android Resolver Dependencies Start
|
||||
implementation 'com.android.installreferrer:installreferrer:2.1' // Assets/ThirdParty/AppsFlyer/Editor/AppsFlyerDependencies.xml:10
|
||||
implementation 'com.android.support:appcompat-v7:25.3.1' // Facebook.Unity.Editor.AndroidSupportLibraryResolver.addSupportLibraryDependency
|
||||
implementation 'com.android.support:cardview-v7:25.3.1' // Facebook.Unity.Editor.AndroidSupportLibraryResolver.addSupportLibraryDependency
|
||||
implementation 'com.android.support:customtabs:25.3.1' // Facebook.Unity.Editor.AndroidSupportLibraryResolver.addSupportLibraryDependency
|
||||
implementation 'com.android.support:support-v4:25.3.1' // Facebook.Unity.Editor.AndroidSupportLibraryResolver.addSupportLibraryDependency
|
||||
implementation 'com.applovin:applovin-sdk:11.7.1' // Assets/IronSource/Editor/ISAppLovinAdapterDependencies.xml:15
|
||||
implementation 'com.applovin:applovin-sdk:11.5.5' // Assets/IronSource/Editor/ISAppLovinAdapterDependencies.xml:15
|
||||
implementation 'com.appsflyer:af-android-sdk:6.4.1' // Assets/ThirdParty/AppsFlyer/Editor/AppsFlyerDependencies.xml:6
|
||||
implementation 'com.appsflyer:unity-wrapper:6.4.1' // Assets/ThirdParty/AppsFlyer/Editor/AppsFlyerDependencies.xml:8
|
||||
implementation 'com.chartboost:chartboost-sdk:9.2.0' // Assets/IronSource/Editor/ISChartboostAdapterDependencies.xml:15
|
||||
implementation 'com.facebook.android:audience-network-sdk:6.12.0' // Assets/IronSource/Editor/ISFacebookAdapterDependencies.xml:8
|
||||
implementation 'com.facebook.android:facebook-applinks:[15.1,16)' // Assets/ThirdParty/FacebookSDK/Plugins/Editor/Dependencies.xml:6
|
||||
implementation 'com.facebook.android:facebook-core:[15.1,16)' // Assets/ThirdParty/FacebookSDK/Plugins/Editor/Dependencies.xml:5
|
||||
implementation 'com.facebook.android:facebook-gamingservices:[15.1,16)' // Assets/ThirdParty/FacebookSDK/Plugins/Editor/Dependencies.xml:9
|
||||
implementation 'com.facebook.android:facebook-login:[15.1,16)' // Assets/ThirdParty/FacebookSDK/Plugins/Editor/Dependencies.xml:7
|
||||
implementation 'com.facebook.android:facebook-share:[15.1,16)' // Assets/ThirdParty/FacebookSDK/Plugins/Editor/Dependencies.xml:8
|
||||
implementation 'com.google.android.gms:play-services-ads:21.5.0' // Assets/IronSource/Editor/ISAdMobAdapterDependencies.xml:8
|
||||
implementation 'com.facebook.android:facebook-applinks:[11.0, 12)' // Assets/ThirdParty/FacebookSDK/Plugins/Editor/Dependencies.xml:6
|
||||
implementation 'com.facebook.android:facebook-core:[11.0, 12)' // Assets/ThirdParty/FacebookSDK/Plugins/Editor/Dependencies.xml:5
|
||||
implementation 'com.facebook.android:facebook-gamingservices:[11.0, 12)' // Assets/ThirdParty/FacebookSDK/Plugins/Editor/Dependencies.xml:9
|
||||
implementation 'com.facebook.android:facebook-login:[11.0, 12)' // Assets/ThirdParty/FacebookSDK/Plugins/Editor/Dependencies.xml:7
|
||||
implementation 'com.facebook.android:facebook-share:[11.0, 12)' // Assets/ThirdParty/FacebookSDK/Plugins/Editor/Dependencies.xml:8
|
||||
implementation 'com.google.android.gms:play-services-ads:21.3.0' // Assets/IronSource/Editor/ISAdMobAdapterDependencies.xml:8
|
||||
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1' // Assets/IronSource/Editor/IronSourceSDKDependencies.xml:17
|
||||
implementation 'com.google.android.gms:play-services-basement:18.1.0' // Assets/IronSource/Editor/IronSourceSDKDependencies.xml:25
|
||||
implementation 'com.ironsource.adapters:adcolonyadapter:4.3.14' // Assets/IronSource/Editor/ISAdColonyAdapterDependencies.xml:16
|
||||
implementation 'com.ironsource.adapters:admobadapter:4.3.35' // Assets/IronSource/Editor/ISAdMobAdapterDependencies.xml:16
|
||||
implementation 'com.ironsource.adapters:applovinadapter:4.3.37' // Assets/IronSource/Editor/ISAppLovinAdapterDependencies.xml:8
|
||||
implementation 'com.ironsource.adapters:chartboostadapter:4.3.11' // Assets/IronSource/Editor/ISChartboostAdapterDependencies.xml:8
|
||||
implementation 'com.ironsource.adapters:facebookadapter:4.3.39' // Assets/IronSource/Editor/ISFacebookAdapterDependencies.xml:16
|
||||
implementation 'com.ironsource.adapters:liftoffadapter:4.3.5' // Assets/IronSource/Editor/ISLiftoffAdapterDependencies.xml:16
|
||||
implementation 'com.ironsource.adapters:pangleadapter:4.3.17' // Assets/IronSource/Editor/ISPangleAdapterDependencies.xml:8
|
||||
implementation 'com.ironsource.adapters:tapjoyadapter:4.1.24' // Assets/IronSource/Editor/ISTapJoyAdapterDependencies.xml:8
|
||||
implementation 'com.ironsource.adapters:unityadsadapter:4.3.26' // Assets/IronSource/Editor/ISUnityAdsAdapterDependencies.xml:8
|
||||
implementation 'com.ironsource.sdk:mediationsdk:7.3.0' // Assets/IronSource/Editor/IronSourceSDKDependencies.xml:9
|
||||
implementation 'com.pangle.global:ads-sdk:5.0.0.8' // Assets/IronSource/Editor/ISPangleAdapterDependencies.xml:15
|
||||
implementation 'com.ironsource.adapters:admobadapter:4.3.33' // Assets/IronSource/Editor/ISAdMobAdapterDependencies.xml:16
|
||||
implementation 'com.ironsource.adapters:applovinadapter:4.3.35' // Assets/IronSource/Editor/ISAppLovinAdapterDependencies.xml:8
|
||||
implementation 'com.ironsource.adapters:facebookadapter:4.3.38' // Assets/IronSource/Editor/ISFacebookAdapterDependencies.xml:16
|
||||
implementation 'com.ironsource.adapters:unityadsadapter:4.3.24' // Assets/IronSource/Editor/ISUnityAdsAdapterDependencies.xml:8
|
||||
implementation 'com.ironsource.sdk:mediationsdk:7.2.6' // Assets/IronSource/Editor/IronSourceSDKDependencies.xml:9
|
||||
implementation 'com.parse.bolts:bolts-android:1.4.0' // Assets/ThirdParty/FacebookSDK/Plugins/Editor/Dependencies.xml:4
|
||||
implementation 'com.tapjoy:tapjoy-android-sdk:12.11.1' // Assets/IronSource/Editor/ISTapJoyAdapterDependencies.xml:15
|
||||
implementation 'com.unity3d.ads:unity-ads:4.6.0' // Assets/IronSource/Editor/ISUnityAdsAdapterDependencies.xml:15
|
||||
implementation 'io.liftoff:liftoffads:1.9.1' // Assets/IronSource/Editor/ISLiftoffAdapterDependencies.xml:8
|
||||
implementation 'com.unity3d.ads:unity-ads:4.4.1' // Assets/IronSource/Editor/ISUnityAdsAdapterDependencies.xml:15
|
||||
// Android Resolver Dependencies End
|
||||
}
|
||||
|
||||
|
||||
15
BFVersions/android/dz_dev/unityLibrary/src/main/AndroidManifest.xml
Normal file → Executable file
15
BFVersions/android/dz_dev/unityLibrary/src/main/AndroidManifest.xml
Normal file → Executable file
@ -31,13 +31,7 @@
|
||||
<!-- Sample AdMob App ID: ca-app-pub-3940256099942544~3347511713 -->
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.ads.APPLICATION_ID"
|
||||
android:value="ca-app-pub-8252390069143459~7841203986"/>
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.ads.flag.OPTIMIZE_INITIALIZATION"
|
||||
android:value="true"/>
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.ads.flag.OPTIMIZE_AD_LOADING"
|
||||
android:value="true"/>
|
||||
android:value="ca-app-pub-1136292565368915~8864142088"/>
|
||||
<!-- <meta-data android:name="unity.build-id" android:value="49055670-6ef7-4715-954e-f4b0917c17e3" /> -->
|
||||
<!-- 每次打包需要替换unity.build-id !-->
|
||||
REPLACE_BUILD_ID
|
||||
@ -51,10 +45,15 @@
|
||||
<uses-feature android:name="android.hardware.vulkan.version" android:required="false" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK”"/>
|
||||
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.location" android:required="false" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.camera.front" android:required="false" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-feature android:name="android.hardware.microphone" android:required="false" />
|
||||
|
||||
17
BFVersions/android/dz_dev/unityLibrary/src/main/java/com/unity3d/player/UnityPlayerActivity.java
Normal file → Executable file
17
BFVersions/android/dz_dev/unityLibrary/src/main/java/com/unity3d/player/UnityPlayerActivity.java
Normal file → Executable file
@ -12,11 +12,10 @@ import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.os.Process;
|
||||
// import android.os.Build;
|
||||
|
||||
// import com.chartboost.sdk.Chartboost;
|
||||
import com.juzu.dz.third.GooglePlugin;
|
||||
import com.ironsource.mediationsdk.IronSource;
|
||||
// import com.ironsource.mediationsdk.IronSource;
|
||||
|
||||
public class UnityPlayerActivity extends Activity implements IUnityPlayerLifecycleEvents
|
||||
{
|
||||
@ -115,7 +114,7 @@ public class UnityPlayerActivity extends Activity implements IUnityPlayerLifecyc
|
||||
return;
|
||||
|
||||
mUnityPlayer.pause();
|
||||
IronSource.onPause(this);
|
||||
// IronSource.onPause(this);
|
||||
}
|
||||
|
||||
// Resume Unity
|
||||
@ -127,17 +126,7 @@ public class UnityPlayerActivity extends Activity implements IUnityPlayerLifecyc
|
||||
return;
|
||||
|
||||
mUnityPlayer.resume();
|
||||
IronSource.onResume(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
// If an interstitial is on screen, close it.
|
||||
// if (Chartboost.onBackPressed()) {
|
||||
// return;
|
||||
// } else {
|
||||
// super.onBackPressed();
|
||||
// }
|
||||
// IronSource.onResume(this);
|
||||
}
|
||||
|
||||
// Low Memory Unity
|
||||
|
||||
0
BFVersions/android/dz_dev/unityLibrary/src/main/res/xml/network_security_config.xml
Normal file → Executable file
0
BFVersions/android/dz_dev/unityLibrary/src/main/res/xml/network_security_config.xml
Normal file → Executable file
0
BFVersions/android/dz_google_abb/build.gradle
Normal file → Executable file
0
BFVersions/android/dz_google_abb/build.gradle
Normal file → Executable file
0
BFVersions/android/dz_google_abb/gradle.properties
Normal file → Executable file
0
BFVersions/android/dz_google_abb/gradle.properties
Normal file → Executable file
0
BFVersions/android/dz_google_abb/install_time_pack/build.gradle
Normal file → Executable file
0
BFVersions/android/dz_google_abb/install_time_pack/build.gradle
Normal file → Executable file
0
BFVersions/android/dz_google_abb/launcher/build.gradle
Normal file → Executable file
0
BFVersions/android/dz_google_abb/launcher/build.gradle
Normal file → Executable file
0
BFVersions/android/dz_google_abb/launcher/src/main/AndroidManifest.xml
Normal file → Executable file
0
BFVersions/android/dz_google_abb/launcher/src/main/AndroidManifest.xml
Normal file → Executable file
0
BFVersions/android/dz_google_abb/launcher/src/main/res/drawable/firebase_icon.png
Normal file → Executable file
0
BFVersions/android/dz_google_abb/launcher/src/main/res/drawable/firebase_icon.png
Normal file → Executable file
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
2
BFVersions/android/dz_google_abb/unityLibrary/build.gradle
Normal file → Executable file
2
BFVersions/android/dz_google_abb/unityLibrary/build.gradle
Normal file → Executable file
@ -30,7 +30,7 @@ dependencies {
|
||||
implementation(name: 'ThinkingSDK', ext:'aar')
|
||||
implementation(name: 'UnityUtils-release', ext:'aar')
|
||||
implementation 'com.google.android.gms:play-services-auth:20.1.0'
|
||||
implementation "com.android.billingclient:billing:5.0.0"
|
||||
implementation "com.android.billingclient:billing:4.0.0"
|
||||
implementation platform('com.google.firebase:firebase-bom:29.2.1')
|
||||
implementation 'com.google.firebase:firebase-analytics:21.1.0'
|
||||
implementation 'com.google.firebase:firebase-messaging'
|
||||
|
||||
19
BFVersions/android/dz_google_abb/unityLibrary/src/main/AndroidManifest.xml
Normal file → Executable file
19
BFVersions/android/dz_google_abb/unityLibrary/src/main/AndroidManifest.xml
Normal file → Executable file
@ -21,10 +21,10 @@
|
||||
<activity android:name="com.facebook.unity.FBUnityGameRequestActivity" />
|
||||
<activity android:name="com.facebook.unity.FBUnityCreateGameGroupActivity" />
|
||||
<activity android:name="com.facebook.unity.FBUnityJoinGameGroupActivity" />
|
||||
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="fb277827051329111" />
|
||||
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="fb491773936518549" />
|
||||
<meta-data android:name="com.facebook.sdk.AutoLogAppEventsEnabled" android:value="true" />
|
||||
<meta-data android:name="com.facebook.sdk.AdvertiserIDCollectionEnabled" android:value="true" />
|
||||
<provider android:name="com.facebook.FacebookContentProvider" android:authorities="com.facebook.app.FacebookContentProvider277827051329111" android:exported="true" />
|
||||
<provider android:name="com.facebook.FacebookContentProvider" android:authorities="com.facebook.app.FacebookContentProvider491773936518549" android:exported="true" />
|
||||
<!-- <uses-permission android:name="com.google.android.gms.permission.AD_ID" /> -->
|
||||
<meta-data android:name="unity.splash-mode" android:value="0" />
|
||||
<meta-data android:name="unity.splash-enable" android:value="True" />
|
||||
@ -32,13 +32,7 @@
|
||||
<!-- Sample AdMob App ID: ca-app-pub-3940256099942544~3347511713 -->
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.ads.APPLICATION_ID"
|
||||
android:value="ca-app-pub-8252390069143459~7841203986"/>
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.ads.flag.OPTIMIZE_INITIALIZATION"
|
||||
android:value="true"/>
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.ads.flag.OPTIMIZE_AD_LOADING"
|
||||
android:value="true"/>
|
||||
android:value="ca-app-pub-1136292565368915~8864142088"/>
|
||||
<!-- <meta-data android:name="unity.build-id" android:value="49055670-6ef7-4715-954e-f4b0917c17e3" /> -->
|
||||
<!-- 每次打包需要替换unity.build-id !-->
|
||||
REPLACE_BUILD_ID
|
||||
@ -52,10 +46,15 @@
|
||||
<uses-feature android:name="android.hardware.vulkan.version" android:required="false" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK”"/>
|
||||
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.location" android:required="false" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.camera.front" android:required="false" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-feature android:name="android.hardware.microphone" android:required="false" />
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
package com.juzu.dz.message;
|
||||
|
||||
/**
|
||||
* 管理和前端的通信消息以及json字段
|
||||
* */
|
||||
public class BFMessage {
|
||||
// Google登录
|
||||
public static final int GOOGLE_LOGIN_SUCCESS = 1;
|
||||
public static final int GOOGLE_LOGIN_FAILED = 2;
|
||||
// Google登出成功
|
||||
public static final int GOOGLE_LOGOUT_SUCCESS = 3;
|
||||
// Google支付
|
||||
public static final int GOOGLE_PAY_SUCCESS = 4;
|
||||
public static final int GOOGLE_PAY_FAILED = 5;
|
||||
public static final int GOOGLE_PAY_CANCEL = 6;
|
||||
public static final int GOOGLE_CONNECT_SUCCESS = 7;
|
||||
public static final int GOOGLE_CONNECT_FAILED = 8;
|
||||
public static final int QUERY_PRODUCT_SUCCESS = 9;
|
||||
public static final int QUERY_PRODUCT_FAILED = 10;
|
||||
public static final int QUERY_UNCOMPLETE_ORDER_FINISH = 11;
|
||||
// Google消耗
|
||||
public static final int GOOGLE_CONSUME_SUCCESS = 12;
|
||||
public static final int GOOGLE_CONSUME_FAILED = 13;
|
||||
// Google登出失败
|
||||
public static final int GOOGLE_LOGOUT_FAILED = 14;
|
||||
// fireBaseToken
|
||||
public static final int FIREBASE_TOKEN = 15;
|
||||
// Google订阅
|
||||
public static final int QUERY_SUBSCRIBE_FINISH = 16;
|
||||
}
|
||||
@ -0,0 +1,459 @@
|
||||
package com.juzu.dz.third;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.billingclient.api.AccountIdentifiers;
|
||||
import com.android.billingclient.api.AcknowledgePurchaseParams;
|
||||
import com.android.billingclient.api.AcknowledgePurchaseResponseListener;
|
||||
import com.android.billingclient.api.BillingClient;
|
||||
import com.android.billingclient.api.BillingClientStateListener;
|
||||
import com.android.billingclient.api.BillingFlowParams;
|
||||
import com.android.billingclient.api.BillingResult;
|
||||
import com.android.billingclient.api.ConsumeParams;
|
||||
import com.android.billingclient.api.ConsumeResponseListener;
|
||||
import com.android.billingclient.api.Purchase;
|
||||
import com.android.billingclient.api.PurchasesUpdatedListener;
|
||||
import com.android.billingclient.api.SkuDetails;
|
||||
import com.android.billingclient.api.SkuDetailsParams;
|
||||
import com.android.billingclient.api.SkuDetailsResponseListener;
|
||||
import com.juzu.dz.message.BFMessage;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class GoogleBilling {
|
||||
private static volatile GoogleBilling sInstance;
|
||||
private static final String LOG_TAG = "GoogleBilling";
|
||||
private static BillingClient mGoogleBillingClient;
|
||||
private Map<String, Purchase> mPurchase = new HashMap<String, Purchase>();
|
||||
private List<SkuDetails> mSubList = new ArrayList<SkuDetails>();
|
||||
private List<SkuDetails> mInAppList = new ArrayList<SkuDetails>();
|
||||
final private static String BASE_64_ENCODED_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm2Vcz26Jz82oYAkr8Wsk0z0hgwBLDRbmnQyARqusiSaJWOt9vEaTgLtLaWYYIiWIeWXUaKq35xDHjC5Xh+KI/pp5N7ck1yB5+lyaSsVD0ESFC/qjDWgElaxxL9QvOyLEHd23q9TmlF1aWziSc6ryFX9HVEGLJT2bTjVEz/bk/WpfN41HZafqQTCIWh8+vRgr0CXa/JEqysjDYRpbaBViPE9F7aTo8lCv/VQpE1ycFiOoaf768aispY5cXb0qP00li95HAI+fEaYgxOuRmN0oc5BFpNRNYTMmRX1Oi5F2vknw+u3+mh+a6GkbwD6FCK+fWIo8hZAWnkULgrxa1ReobQIDAQAB";
|
||||
|
||||
public static GoogleBilling getInstance()
|
||||
{
|
||||
if (sInstance == null) {
|
||||
synchronized (GoogleBilling.class) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new GoogleBilling();
|
||||
}
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
public void init(Activity activity){
|
||||
mGoogleBillingClient = BillingClient.newBuilder(activity).setListener(payListener).enablePendingPurchases().build();
|
||||
connectGoogleStore();
|
||||
}
|
||||
|
||||
public void connectGoogleStore(){
|
||||
mGoogleBillingClient.startConnection(new BillingClientStateListener() {
|
||||
@Override
|
||||
public void onBillingSetupFinished(BillingResult billingResult) {
|
||||
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_CONNECT_SUCCESS, "");
|
||||
}else{
|
||||
String msg = billingResult.getDebugMessage();
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_CONNECT_FAILED, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBillingServiceDisconnected() {
|
||||
String msg = "disconnected";
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_CONNECT_FAILED, msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 查询商品信息,本地化用
|
||||
public void queryProductsInfo(String payType, String productInfoJson){
|
||||
Log.d(LOG_TAG, "google queryProductsInfo info from unity:" + productInfoJson);
|
||||
try {
|
||||
JSONArray array = new JSONArray(productInfoJson);
|
||||
String[] proList = new String[array.length()];
|
||||
for (int i = 0; i < array.length(); i++){
|
||||
proList[i] = (String)array.get(i);
|
||||
}
|
||||
queryProducts(payType, proList);
|
||||
} catch (JSONException e) {
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.QUERY_PRODUCT_FAILED, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
//通过商品id查询商品详情
|
||||
private void queryProducts(String payType, String [] products){
|
||||
List<String> pList = Arrays.asList(products);
|
||||
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
|
||||
params.setSkusList(pList).setType(payType);
|
||||
mGoogleBillingClient.querySkuDetailsAsync(params.build(), new SkuDetailsResponseListener() {
|
||||
@Override
|
||||
public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> list) {
|
||||
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && list != null){
|
||||
Log.d(LOG_TAG, "queryProducts success count:" + list.size());
|
||||
if (list.size() == 0){
|
||||
String msg = "未查询到商品信息,请检查传入的商品id,或者配置是否生效";
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.QUERY_PRODUCT_FAILED, msg);
|
||||
return;
|
||||
}
|
||||
JSONArray array = new JSONArray();
|
||||
List<SkuDetails> mList = new ArrayList<SkuDetails>();
|
||||
for (SkuDetails skuDetails : list) {
|
||||
mList.add(skuDetails);
|
||||
String sku = skuDetails.getSku();
|
||||
String price = skuDetails.getPrice();//实际价格
|
||||
String originPrice = skuDetails.getOriginalPrice();//原价,如果没折扣,原价=实际价格
|
||||
String description = skuDetails.getDescription();
|
||||
String originalJson = skuDetails.getOriginalJson();
|
||||
String title = skuDetails.getTitle();
|
||||
String priceAmountMicros = String.valueOf(skuDetails.getPriceAmountMicros());
|
||||
String currencyCode = skuDetails.getPriceCurrencyCode();
|
||||
JSONObject info = new JSONObject();
|
||||
try {
|
||||
info.put("sku", sku);
|
||||
info.put("price", price);
|
||||
info.put("originPrice", originPrice);
|
||||
info.put("description", description);
|
||||
info.put("originalJson", originalJson);
|
||||
info.put("title", title);
|
||||
info.put("priceCurrencyCode", currencyCode);
|
||||
info.put("priceAmountMicros", priceAmountMicros);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
array.put(info);
|
||||
}
|
||||
if(payType.equals(BillingClient.SkuType.INAPP)){
|
||||
mInAppList = mList;
|
||||
}
|
||||
if(payType.equals(BillingClient.SkuType.SUBS)){
|
||||
mSubList = mList;
|
||||
}
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.QUERY_PRODUCT_SUCCESS, array.toString());
|
||||
}else{
|
||||
String msg = "queryProducts error:" + billingResult.getResponseCode();
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.QUERY_PRODUCT_FAILED, msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 支付
|
||||
public void pay(Activity activity, String payType, String productId, String customMsg){
|
||||
List<SkuDetails> skuList = null;
|
||||
if(payType.equals(BillingClient.SkuType.INAPP)){
|
||||
skuList = mInAppList;
|
||||
}
|
||||
if(payType.equals(BillingClient.SkuType.SUBS)){
|
||||
skuList = mSubList;
|
||||
}
|
||||
if (skuList == null || skuList.size() == 0){
|
||||
String msg = "no sku";
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_PAY_FAILED, msg);
|
||||
return ;
|
||||
}
|
||||
SkuDetails paySku = null;
|
||||
for (SkuDetails details:skuList){
|
||||
if (TextUtils.equals(productId, details.getSku())){
|
||||
paySku = details;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (paySku == null){
|
||||
String msg = "sku not found! please contact developer";
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_PAY_FAILED, msg);
|
||||
return;
|
||||
}
|
||||
// Retrieve a value for "skuDetails" by calling querySkuDetailsAsync().
|
||||
BillingFlowParams flowParams = BillingFlowParams.newBuilder()
|
||||
.setSkuDetails(paySku)
|
||||
.setObfuscatedAccountId(customMsg)
|
||||
.build();
|
||||
BillingResult result = mGoogleBillingClient.launchBillingFlow(activity, flowParams);
|
||||
if (result.getResponseCode() != BillingClient.BillingResponseCode.OK){
|
||||
String msg = "Billing failed: + " + result.getDebugMessage();
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_PAY_FAILED, msg);
|
||||
}
|
||||
}
|
||||
|
||||
private PurchasesUpdatedListener payListener = new PurchasesUpdatedListener() {
|
||||
@Override
|
||||
public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> purchases) {
|
||||
switch (billingResult.getResponseCode()) {
|
||||
case BillingClient.BillingResponseCode.OK:
|
||||
if (null != purchases) {
|
||||
for (Purchase purchase : purchases) {
|
||||
handlePurchase(purchase);
|
||||
}
|
||||
} else {
|
||||
String msg = "Null Purchase List Returned from OK response!";
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_PAY_FAILED, msg);
|
||||
}
|
||||
break;
|
||||
case BillingClient.BillingResponseCode.USER_CANCELED:
|
||||
Log.i(LOG_TAG, "onPurchasesUpdated: User canceled the purchase");
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_PAY_CANCEL, "");
|
||||
break;
|
||||
case BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED:
|
||||
String msg = "onPurchasesUpdated: The user already owns this item";
|
||||
Log.i(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_PAY_FAILED, msg);
|
||||
break;
|
||||
case BillingClient.BillingResponseCode.DEVELOPER_ERROR:
|
||||
String msg2 = "onPurchasesUpdated: Developer error means that Google Play " +
|
||||
"does not recognize the configuration. If you are just getting started, " +
|
||||
"make sure you have configured the application correctly in the " +
|
||||
"Google Play Console. The SKU product ID must match and the APK you " +
|
||||
"are using must be signed with release keys.";
|
||||
|
||||
Log.e(LOG_TAG, msg2);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_PAY_FAILED, msg2);
|
||||
break;
|
||||
default:
|
||||
String msg3 = "BillingResult [" + billingResult.getResponseCode() + "]: " + billingResult.getDebugMessage();
|
||||
Log.d(LOG_TAG, msg3);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_PAY_FAILED, msg3);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private void handlePurchase(Purchase purchase) {
|
||||
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
|
||||
// 支付完成
|
||||
if(!purchase.isAcknowledged()){
|
||||
mPurchase.put(purchase.getPurchaseToken(),purchase);
|
||||
}
|
||||
//验证签名
|
||||
String orderId = purchase.getOrderId();
|
||||
String originalJson = purchase.getOriginalJson();
|
||||
String purchaseToken = purchase.getPurchaseToken();
|
||||
ArrayList<String> skus = purchase.getSkus();
|
||||
String signature = purchase.getSignature();
|
||||
AccountIdentifiers accountIdentifiers = purchase.getAccountIdentifiers();
|
||||
String obfuscatedAccountId = accountIdentifiers.getObfuscatedAccountId();
|
||||
boolean succ = verifyValidSignature(originalJson, signature);
|
||||
JSONObject productInfo = new JSONObject();
|
||||
try {
|
||||
productInfo.put("orderId", orderId);
|
||||
productInfo.put("purchaseToken", purchaseToken);
|
||||
productInfo.put("obfuscatedAccountId", obfuscatedAccountId);
|
||||
productInfo.put("signtureFlag", succ + "");
|
||||
if (skus.size() > 0)
|
||||
{
|
||||
productInfo.put("productId", skus.get(0));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_PAY_SUCCESS, productInfo.toString());
|
||||
}else{
|
||||
//未付款
|
||||
String msg = "purchase.getPurchaseState() != Purchase.PurchaseState.PURCHASED";
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_PAY_FAILED, msg);
|
||||
}
|
||||
}
|
||||
|
||||
//消耗
|
||||
public void consumeAsync(String purchaseToken){
|
||||
Purchase purchase = mPurchase.get(purchaseToken);
|
||||
boolean isSub = false;
|
||||
if(purchase != null){
|
||||
if(mSubList != null){
|
||||
for(SkuDetails Sku:mSubList){
|
||||
for ( String purchaseSku : purchase.getSkus() ) {
|
||||
if (purchaseSku.equals(Sku.getSku())) {
|
||||
isSub = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(isSub){
|
||||
handleSubsPurchase(purchase);
|
||||
}else{
|
||||
final ConsumeParams consumeParams = ConsumeParams.newBuilder().setPurchaseToken(purchaseToken)
|
||||
.build();
|
||||
mGoogleBillingClient.consumeAsync(consumeParams, (billingResult, purchaseToken1) -> {
|
||||
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
|
||||
Log.d(LOG_TAG, "消耗成功...");
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_CONSUME_SUCCESS, "");
|
||||
} else {
|
||||
Log.d(LOG_TAG, "消耗失败...");
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_CONSUME_FAILED, "");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSubsPurchase(Purchase purchase) {
|
||||
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
|
||||
if (!purchase.isAcknowledged()) {
|
||||
AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder().setPurchaseToken(purchase.getPurchaseToken())
|
||||
.build();
|
||||
mGoogleBillingClient.acknowledgePurchase(acknowledgePurchaseParams, new AcknowledgePurchaseResponseListener() {
|
||||
@Override
|
||||
public void onAcknowledgePurchaseResponse(BillingResult billingResult) {
|
||||
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
|
||||
Log.d(LOG_TAG, "订阅成功...");
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_CONSUME_SUCCESS, "");
|
||||
} else {
|
||||
Log.d(LOG_TAG, "订阅失败...");
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_CONSUME_FAILED, "");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//查询缓存的购买交易
|
||||
public void queryUncompleteOrder(String payType){
|
||||
if (mGoogleBillingClient == null){
|
||||
String msg = "queryPurchases billingClient is null";
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.QUERY_UNCOMPLETE_ORDER_FINISH, "");
|
||||
return;
|
||||
}
|
||||
mGoogleBillingClient.queryPurchasesAsync(payType, (billingResult, list) -> {
|
||||
if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
|
||||
Log.d(LOG_TAG, "Billing client was null or result code is:" + billingResult.getDebugMessage());
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.QUERY_UNCOMPLETE_ORDER_FINISH, "");
|
||||
} else {
|
||||
//消耗
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
for (Purchase purchase : list){
|
||||
//商品购买成功,系统还会生成购买令牌,它是一个唯一标识符,表示用户及其所购应用内商品的商品 I
|
||||
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
|
||||
if (!purchase.isAcknowledged()){
|
||||
mPurchase.put(purchase.getPurchaseToken(), purchase);
|
||||
//验证签名
|
||||
String orderId = purchase.getOrderId();
|
||||
String originalJson = purchase.getOriginalJson();
|
||||
String purchaseToken = purchase.getPurchaseToken();
|
||||
ArrayList<String> skus = purchase.getSkus();
|
||||
String signature = purchase.getSignature();
|
||||
AccountIdentifiers accountIdentifiers = purchase.getAccountIdentifiers();
|
||||
String obfuscatedAccountId = accountIdentifiers.getObfuscatedAccountId();
|
||||
JSONObject productInfo = new JSONObject();
|
||||
try {
|
||||
productInfo.put("payType", payType);
|
||||
productInfo.put("orderId", orderId);
|
||||
productInfo.put("purchaseToken", purchaseToken);
|
||||
productInfo.put("obfuscatedAccountId", obfuscatedAccountId);
|
||||
boolean succ = verifyValidSignature(originalJson,signature);
|
||||
productInfo.put("signtureFlag", String.valueOf(succ));
|
||||
productInfo.put("purchaseState", "1");
|
||||
if (skus.size() > 0)
|
||||
{
|
||||
productInfo.put("productId", skus.get(0));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
jsonArray.put(productInfo);
|
||||
}
|
||||
}else if (purchase.getPurchaseState() == Purchase.PurchaseState.PENDING){
|
||||
ArrayList<String> skus = purchase.getSkus();
|
||||
JSONObject productInfo = new JSONObject();
|
||||
try {
|
||||
productInfo.put("purchaseState", "2");
|
||||
if (skus.size() > 0)
|
||||
{
|
||||
productInfo.put("productId", skus.get(0));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
jsonArray.put(productInfo);
|
||||
}
|
||||
}
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.QUERY_UNCOMPLETE_ORDER_FINISH, jsonArray.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//查询缓存的訂閲状态
|
||||
public void querySubscribeOrder(String payType) {
|
||||
if (mGoogleBillingClient == null) {
|
||||
String msg = "queryPurchases billingClient is null";
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.QUERY_SUBSCRIBE_FINISH, "");
|
||||
return;
|
||||
}
|
||||
mGoogleBillingClient.queryPurchasesAsync(payType, (billingResult, list) -> {
|
||||
if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
|
||||
Log.d(LOG_TAG, "Billing client was null or result code is:" + billingResult.getDebugMessage());
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.QUERY_SUBSCRIBE_FINISH, "");
|
||||
} else {
|
||||
//消耗
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
for (Purchase purchase : list){
|
||||
//商品购买成功,系统还会生成购买令牌,它是一个唯一标识符,表示用户及其所购应用内商品的商品 I
|
||||
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
|
||||
String orderId = purchase.getOrderId();
|
||||
String originalJson = purchase.getOriginalJson();
|
||||
String purchaseToken = purchase.getPurchaseToken();
|
||||
ArrayList<String> skus = purchase.getSkus();
|
||||
String signature = purchase.getSignature();
|
||||
AccountIdentifiers accountIdentifiers = purchase.getAccountIdentifiers();
|
||||
String obfuscatedAccountId = accountIdentifiers.getObfuscatedAccountId();
|
||||
JSONObject productInfo = new JSONObject();
|
||||
try {
|
||||
productInfo.put("payType", payType);
|
||||
productInfo.put("orderId", orderId);
|
||||
productInfo.put("purchaseToken", purchaseToken);
|
||||
productInfo.put("obfuscatedAccountId", obfuscatedAccountId);
|
||||
boolean succ = verifyValidSignature(originalJson,signature);
|
||||
productInfo.put("signtureFlag", String.valueOf(succ));
|
||||
productInfo.put("purchaseState", "1");
|
||||
if (skus.size() > 0)
|
||||
{
|
||||
productInfo.put("productId", skus.get(0));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
jsonArray.put(productInfo);
|
||||
}
|
||||
}
|
||||
Log.d(LOG_TAG, "订阅状态查询 " + jsonArray.toString());
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.QUERY_SUBSCRIBE_FINISH, jsonArray.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean verifyValidSignature(String signedData, String signature) {
|
||||
return Security.verifyPurchase(BASE_64_ENCODED_PUBLIC_KEY, signedData, signature);
|
||||
}
|
||||
|
||||
public void onDestroy(){
|
||||
if (mGoogleBillingClient != null && mGoogleBillingClient.isReady()){
|
||||
mGoogleBillingClient.endConnection();
|
||||
mGoogleBillingClient = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,96 @@
|
||||
package com.juzu.dz.third;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignIn;
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
|
||||
import com.google.android.gms.common.Scopes;
|
||||
import com.google.android.gms.common.api.ApiException;
|
||||
import com.google.android.gms.common.api.Scope;
|
||||
import com.google.android.gms.tasks.OnCompleteListener;
|
||||
import com.google.android.gms.tasks.Task;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import com.juzu.dz.message.BFMessage;
|
||||
|
||||
public class GoogleLogin {
|
||||
private static volatile GoogleLogin sInstance;
|
||||
private GoogleSignInClient mGoogleSignInClient;
|
||||
private static final int REQUEST_CODE_GOOGLE_SIGN_IN = 1001; /* unique request id */
|
||||
private static final String server_client_token = "526230333982-j465cnveghnr5el3701rtsc38s3l08cg.apps.googleusercontent.com";
|
||||
|
||||
public static GoogleLogin getInstance()
|
||||
{
|
||||
if (sInstance == null) {
|
||||
synchronized (GoogleLogin.class) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new GoogleLogin();
|
||||
}
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
public void init(Activity activity){
|
||||
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
|
||||
.requestId()
|
||||
.requestIdToken(server_client_token)
|
||||
.requestServerAuthCode(server_client_token)
|
||||
.requestScopes(new Scope(Scopes.PLUS_ME))
|
||||
.build();
|
||||
mGoogleSignInClient = GoogleSignIn.getClient(activity, gso);
|
||||
}
|
||||
|
||||
public void login(Activity activity)
|
||||
{
|
||||
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
|
||||
activity.startActivityForResult(signInIntent, REQUEST_CODE_GOOGLE_SIGN_IN);
|
||||
}
|
||||
|
||||
public void logout(Activity activity)
|
||||
{
|
||||
mGoogleSignInClient.signOut().addOnCompleteListener(activity, new OnCompleteListener<Void>() {
|
||||
@Override
|
||||
public void onComplete(@NonNull Task<Void> task) {
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_LOGOUT_SUCCESS, "");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
if (requestCode == REQUEST_CODE_GOOGLE_SIGN_IN) {
|
||||
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
|
||||
handleSignInResult(task);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
|
||||
try {
|
||||
GoogleSignInAccount account = completedTask.getResult(ApiException.class);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_LOGIN_SUCCESS, createLoginInfo(account));
|
||||
} catch (ApiException e) {
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_LOGIN_FAILED, "google login failed e:" + e.getStatusCode() + " msg:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String createLoginInfo(GoogleSignInAccount account){
|
||||
String idToken = account.getIdToken();
|
||||
String uid = account.getId();
|
||||
JSONObject result = new JSONObject();
|
||||
try {
|
||||
result.put("Token", idToken);
|
||||
result.put("UserId", uid);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,148 @@
|
||||
package com.juzu.dz.third;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.android.gms.tasks.OnCompleteListener;
|
||||
import com.google.android.gms.tasks.Task;
|
||||
// import com.google.firebase.messaging.FirebaseMessaging;
|
||||
import com.juzu.dz.message.BFMessage;
|
||||
import com.unity3d.player.UnityPlayer;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class GooglePlugin {
|
||||
private static final String LOG_TAG = "GooglePlugin";
|
||||
private static GoogleLogin mGoogleLogin = null;
|
||||
private static GoogleBilling mGoogleBilling = null;
|
||||
private static Activity _activity;
|
||||
|
||||
public static void init(Activity activity){
|
||||
_activity = activity;
|
||||
}
|
||||
|
||||
public static void initLogin()
|
||||
{
|
||||
if (mGoogleLogin == null)
|
||||
{
|
||||
mGoogleLogin = GoogleLogin.getInstance();
|
||||
mGoogleLogin.init(_activity);
|
||||
}
|
||||
}
|
||||
|
||||
public static void initBilling()
|
||||
{
|
||||
if (mGoogleBilling == null)
|
||||
{
|
||||
mGoogleBilling = GoogleBilling.getInstance();
|
||||
mGoogleBilling.init(_activity);
|
||||
}
|
||||
}
|
||||
|
||||
// 登录
|
||||
public static void login()
|
||||
{
|
||||
if (mGoogleLogin != null){
|
||||
mGoogleLogin.login(_activity);
|
||||
}else{
|
||||
sendMessageToUnity(BFMessage.GOOGLE_LOGIN_FAILED, "google login failed: not init");
|
||||
}
|
||||
}
|
||||
|
||||
// 登出
|
||||
public static void logout()
|
||||
{
|
||||
if (mGoogleLogin != null){
|
||||
mGoogleLogin.logout(_activity);
|
||||
}else{
|
||||
sendMessageToUnity(BFMessage.GOOGLE_LOGOUT_FAILED, "");
|
||||
}
|
||||
}
|
||||
|
||||
public static void pay(String payType, String productId, String customMsg)
|
||||
{
|
||||
if (mGoogleBilling != null){
|
||||
mGoogleBilling.pay(_activity, payType, productId, customMsg);
|
||||
}else{
|
||||
sendMessageToUnity(BFMessage.GOOGLE_PAY_FAILED, "billing not init");
|
||||
}
|
||||
}
|
||||
|
||||
public static void queryProductsInfo(String payType, String productJson)
|
||||
{
|
||||
if (mGoogleBilling != null){
|
||||
mGoogleBilling.queryProductsInfo(payType, productJson);
|
||||
}else{
|
||||
sendMessageToUnity(BFMessage.QUERY_PRODUCT_FAILED, "billing not init");
|
||||
}
|
||||
}
|
||||
|
||||
public static void consumeAsync(String purchaseToken)
|
||||
{
|
||||
if (mGoogleBilling != null){
|
||||
mGoogleBilling.consumeAsync(purchaseToken);
|
||||
}else{
|
||||
sendMessageToUnity(BFMessage.GOOGLE_CONSUME_FAILED, "billing not init");
|
||||
}
|
||||
}
|
||||
|
||||
public static void connectGoogleStore()
|
||||
{
|
||||
if (mGoogleBilling != null){
|
||||
mGoogleBilling.connectGoogleStore();
|
||||
}else{
|
||||
sendMessageToUnity(BFMessage.GOOGLE_CONNECT_FAILED, "billing not init");
|
||||
}
|
||||
}
|
||||
|
||||
public static void queryUncompleteOrder(String payType)
|
||||
{
|
||||
if (mGoogleBilling != null){
|
||||
mGoogleBilling.queryUncompleteOrder(payType);
|
||||
}else{
|
||||
sendMessageToUnity(BFMessage.QUERY_UNCOMPLETE_ORDER_FINISH, "");
|
||||
}
|
||||
}
|
||||
|
||||
public static void querySubscribeOrder(String payType)
|
||||
{
|
||||
if (mGoogleBilling != null){
|
||||
mGoogleBilling.querySubscribeOrder(payType);
|
||||
}else{
|
||||
sendMessageToUnity(BFMessage.QUERY_SUBSCRIBE_FINISH, "");
|
||||
}
|
||||
}
|
||||
|
||||
public static void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
if (mGoogleLogin != null){
|
||||
mGoogleLogin.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
}
|
||||
|
||||
public static void onDestroy()
|
||||
{
|
||||
if (mGoogleBilling != null){
|
||||
mGoogleBilling.onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
public static void getFirebaseToken()
|
||||
{
|
||||
}
|
||||
|
||||
public static void sendMessageToUnity(int code, String msg){
|
||||
JSONObject data = new JSONObject();
|
||||
try {
|
||||
data.put("head", code);
|
||||
data.put("body", msg);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Log.d(LOG_TAG, code + ":" + msg);
|
||||
UnityPlayer.UnitySendMessage("SDKManager", "MsgFromAndroidOrIOS", data.toString());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package com.juzu.dz.third;
|
||||
/*
|
||||
* This class is an sample of how you can check to make sure your purchases on the device came
|
||||
* from Google Play. Putting code like this on your server will provide additional protection.
|
||||
* <p>
|
||||
* One thing that you may also wish to consider doing is caching purchase IDs to make replay
|
||||
* attacks harder. The reason this code isn't just part of the library is to allow
|
||||
* you to customize it (and rename it!) to make generic patching exploits more difficult.
|
||||
*/
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.Signature;
|
||||
import java.security.SignatureException;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
/**
|
||||
* Security-related methods. For a secure implementation, all of this code should be implemented on
|
||||
* a server that communicates with the application on the device.
|
||||
*/
|
||||
class Security {
|
||||
static final private String TAG = "IABUtil/Security";
|
||||
static final private String KEY_FACTORY_ALGORITHM = "RSA";
|
||||
static final private String SIGNATURE_ALGORITHM = "SHA1withRSA";
|
||||
|
||||
/**
|
||||
* BASE_64_ENCODED_PUBLIC_KEY should be YOUR APPLICATION PUBLIC KEY. You currently get this
|
||||
* from the Google Play developer console under the "Monetization Setup" category in the
|
||||
* Licensing area. This build has been setup so that if you define base64EncodedPublicKey in
|
||||
* your local.properties, it will be echoed into BuildConfig.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Verifies that the data was signed with the given signature
|
||||
*
|
||||
* @param signedData the signed JSON string (signed, not encrypted)
|
||||
* @param signature the signature for the data, signed with the private key
|
||||
*/
|
||||
static public boolean verifyPurchase(String base64PublicKey, String signedData, String signature) {
|
||||
if ((TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey)
|
||||
|| TextUtils.isEmpty(signature))
|
||||
) {
|
||||
Log.w(TAG, "Purchase verification failed: missing data.");
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
PublicKey key = generatePublicKey(base64PublicKey);
|
||||
return verify(key, signedData, signature);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Error generating PublicKey from encoded key: " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a PublicKey instance from a string containing the Base64-encoded public key.
|
||||
*
|
||||
* @param encodedPublicKey Base64-encoded public key
|
||||
* @throws IOException if encoding algorithm is not supported or key specification
|
||||
* is invalid
|
||||
*/
|
||||
static private PublicKey generatePublicKey(String encodedPublicKey) throws IOException {
|
||||
try {
|
||||
byte[] decodedKey = Base64.decode(encodedPublicKey, Base64.DEFAULT);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_FACTORY_ALGORITHM);
|
||||
return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
// "RSA" is guaranteed to be available.
|
||||
throw new RuntimeException(e);
|
||||
} catch (InvalidKeySpecException e) {
|
||||
String msg = "Invalid key specification: " + e;
|
||||
Log.w(TAG, msg);
|
||||
throw new IOException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the signature from the server matches the computed signature on the data.
|
||||
* Returns true if the data is correctly signed.
|
||||
*
|
||||
* @param publicKey public key associated with the developer account
|
||||
* @param signedData signed data from server
|
||||
* @param signature server signature
|
||||
* @return true if the data and signature match
|
||||
*/
|
||||
static private Boolean verify(PublicKey publicKey, String signedData, String signature) {
|
||||
byte[] signatureBytes;
|
||||
try {
|
||||
signatureBytes = Base64.decode(signature, Base64.DEFAULT);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.w(TAG, "Base64 decoding failed.");
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
Signature signatureAlgorithm = Signature.getInstance(SIGNATURE_ALGORITHM);
|
||||
signatureAlgorithm.initVerify(publicKey);
|
||||
signatureAlgorithm.update(signedData.getBytes());
|
||||
if (!signatureAlgorithm.verify(signatureBytes)) {
|
||||
Log.w(TAG, "Signature verification failed...");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
// "RSA" is guaranteed to be available.
|
||||
throw new RuntimeException(e);
|
||||
} catch (InvalidKeyException e) {
|
||||
Log.e(TAG, "Invalid key specification.");
|
||||
} catch (SignatureException e) {
|
||||
Log.e(TAG, "Signature exception.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
0
BFVersions/android/dz_google_abb/unityLibrary/src/main/java/com/unity3d/player/UnityPlayerActivity.java
Normal file → Executable file
0
BFVersions/android/dz_google_abb/unityLibrary/src/main/java/com/unity3d/player/UnityPlayerActivity.java
Normal file → Executable file
0
BFVersions/android/dz_google_abb/unityLibrary/src/main/res/xml/network_security_config.xml
Normal file → Executable file
0
BFVersions/android/dz_google_abb/unityLibrary/src/main/res/xml/network_security_config.xml
Normal file → Executable file
2
BFVersions/android/dz_google_apk/build.gradle
Normal file → Executable file
2
BFVersions/android/dz_google_apk/build.gradle
Normal file → Executable file
@ -5,11 +5,13 @@ buildscript {
|
||||
google()
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
maven { url 'https://artifacts.applovin.com/android'; content { includeGroupByRegex 'com.applovin.*' } }
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.1.3'
|
||||
classpath 'com.google.gms:google-services:4.3.13'
|
||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.1'
|
||||
classpath 'com.applovin.quality:AppLovinQualityServiceGradlePlugin:+'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1
BFVersions/android/dz_google_apk/gradle.properties
Normal file → Executable file
1
BFVersions/android/dz_google_apk/gradle.properties
Normal file → Executable file
@ -3,3 +3,4 @@ org.gradle.parallel=true
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
unityStreamingAssets=.unity3d, .bytes, .ab, UnityServicesProjectConfiguration.json
|
||||
unityTemplateVersion=4
|
||||
5
BFVersions/android/dz_google_apk/gradle/wrapper/gradle-wrapper.properties
vendored
Executable file
5
BFVersions/android/dz_google_apk/gradle/wrapper/gradle-wrapper.properties
vendored
Executable file
@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
||||
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.ironsource.unity">
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<application>
|
||||
<!-- AdMob -->
|
||||
<!--As Requiered By Admob please add your App ID-->
|
||||
<!--<meta-data-->
|
||||
<!--android:name="com.google.android.gms.ads.APPLICATION_ID"-->
|
||||
<!--android:value="YOUR_ADMOB_APP_ID"/>-->
|
||||
</application>
|
||||
</manifest>
|
||||
@ -1,28 +0,0 @@
|
||||
apply plugin: 'android-library'
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'bin', include: ['*.jar'])
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
}
|
||||
|
||||
android {
|
||||
sourceSets {
|
||||
main {
|
||||
manifest.srcFile 'AndroidManifest.xml'
|
||||
//java.srcDirs = ['src']
|
||||
res.srcDirs = ['res']
|
||||
assets.srcDirs = ['assets']
|
||||
jniLibs.srcDirs = ['libs']
|
||||
}
|
||||
}
|
||||
|
||||
compileSdkVersion 34
|
||||
buildToolsVersion '30.0.2'
|
||||
defaultConfig {
|
||||
targetSdkVersion 34
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@ -1,2 +0,0 @@
|
||||
target=android-9
|
||||
android.library=true
|
||||
165
BFVersions/android/dz_google_apk/unityLibrary/build.gradle
Normal file → Executable file
165
BFVersions/android/dz_google_apk/unityLibrary/build.gradle
Normal file → Executable file
@ -11,28 +11,26 @@ apply plugin: 'com.android.library'
|
||||
url "https://maven.google.com"
|
||||
}
|
||||
maven {
|
||||
url "https://android-sdk.is.com/" // Assets/IronSource/Editor/IronSourceSDKDependencies.xml:9, Assets/IronSource/Editor/ISAdColonyAdapterDependencies.xml:16, Assets/IronSource/Editor/ISAdMobAdapterDependencies.xml:16, Assets/IronSource/Editor/ISAppLovinAdapterDependencies.xml:8, Assets/IronSource/Editor/ISChartboostAdapterDependencies.xml:8, Assets/IronSource/Editor/ISFacebookAdapterDependencies.xml:16, Assets/IronSource/Editor/ISFyberAdapterDependencies.xml:16, Assets/IronSource/Editor/ISMintegralAdapterDependencies.xml:48, Assets/IronSource/Editor/ISPangleAdapterDependencies.xml:8, Assets/IronSource/Editor/ISTapJoyAdapterDependencies.xml:8, Assets/IronSource/Editor/ISUnityAdsAdapterDependencies.xml:8, Assets/IronSource/Editor/ISVungleAdapterDependencies.xml:16, Assets/IronSourceAdQuality/Editor/IronSourceAdQualityDependencies.xml:9, Assets/IronSourceAdQuality/Editor/IronSourceAdQualityDependencies.xml:17
|
||||
url "https://verve.jfrog.io/artifactory/verve-gradle-release" // Assets/ThirdParty/MaxSdk/Mediation/Verve/Editor/Dependencies.xml:7
|
||||
}
|
||||
maven {
|
||||
url "https://maven.google.com/" // Assets/IronSource/Editor/IronSourceSDKDependencies.xml:17, Assets/IronSource/Editor/IronSourceSDKDependencies.xml:25, Assets/IronSource/Editor/ISAdColonyAdapterDependencies.xml:8, Assets/IronSource/Editor/ISAdMobAdapterDependencies.xml:8, Assets/IronSource/Editor/ISAppLovinAdapterDependencies.xml:15, Assets/IronSource/Editor/ISFacebookAdapterDependencies.xml:8, Assets/IronSource/Editor/ISMintegralAdapterDependencies.xml:40, Assets/IronSource/Editor/ISUnityAdsAdapterDependencies.xml:15
|
||||
url "https://artifactory.bidmachine.io/bidmachine" // Assets/ThirdParty/MaxSdk/Mediation/BidMachine/Editor/Dependencies.xml:8
|
||||
}
|
||||
maven {
|
||||
url "https://cboost.jfrog.io/artifactory/chartboost-ads/" // Assets/IronSource/Editor/ISChartboostAdapterDependencies.xml:15
|
||||
url "https://cboost.jfrog.io/artifactory/chartboost-ads/" // Assets/ThirdParty/MaxSdk/Mediation/Chartboost/Editor/Dependencies.xml:8
|
||||
}
|
||||
maven {
|
||||
url "https://repo.maven.apache.org/maven2/" // Assets/IronSource/Editor/ISFyberAdapterDependencies.xml:8
|
||||
url "https://android-sdk.is.com/" // Assets/ThirdParty/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml:8
|
||||
}
|
||||
maven {
|
||||
url "https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea/" // Assets/IronSource/Editor/ISMintegralAdapterDependencies.xml:8, Assets/IronSource/Editor/ISMintegralAdapterDependencies.xml:16, Assets/IronSource/Editor/ISMintegralAdapterDependencies.xml:24, Assets/IronSource/Editor/ISMintegralAdapterDependencies.xml:32
|
||||
url "https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea" // Assets/ThirdParty/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:8
|
||||
}
|
||||
maven {
|
||||
url "https://artifact.bytedance.com/repository/pangle/" // Assets/IronSource/Editor/ISPangleAdapterDependencies.xml:15
|
||||
url "https://artifact.bytedance.com/repository/pangle" // Assets/ThirdParty/MaxSdk/Mediation/ByteDance/Editor/Dependencies.xml:8
|
||||
}
|
||||
maven { url "../Upload-TaurusX" }
|
||||
maven {
|
||||
url "https://sdk.tapjoy.com/" // Assets/IronSource/Editor/ISTapJoyAdapterDependencies.xml:15
|
||||
}
|
||||
maven {
|
||||
url "https://jitpack.io/" // Assets/IronSource/Editor/ISVungleAdapterDependencies.xml:8
|
||||
url "https://bitbucket.org/sdkcenter/sdkcenter/raw/release"
|
||||
}
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
@ -44,78 +42,66 @@ apply plugin: 'com.android.library'
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation 'com.android.support:multidex:1.0.3'
|
||||
// IAB TCF Decoder
|
||||
implementation("com.iabtcf:iabtcf-decoder:2.0.10")
|
||||
|
||||
implementation(name: 'screenutils-release', ext:'aar')
|
||||
implementation(name: 'ThinkingSDK', ext:'aar')
|
||||
implementation(name: 'UnityUtils-release', ext:'aar')
|
||||
implementation(name: 'LofeltHaptics', ext:'aar')
|
||||
implementation(name: 'facebook-android-wrapper-15.1.0', ext:'aar')
|
||||
implementation 'com.google.android.gms:play-services-auth:20.1.0'
|
||||
implementation(name: 'applovin-max-unity-plugin', ext:'aar')
|
||||
implementation "com.android.billingclient:billing:6.2.1"
|
||||
implementation 'com.google.android.gms:play-services-auth:20.1.0'
|
||||
implementation 'com.google.android.play:review:2.0.1'
|
||||
|
||||
// firebase
|
||||
implementation 'com.google.firebase:firebase-analytics:21.1.0'
|
||||
implementation 'com.google.firebase:firebase-crashlytics:18.2.12'
|
||||
implementation 'com.google.firebase:firebase-messaging:23.0.8'
|
||||
|
||||
// adjust
|
||||
implementation(name: 'adjust-android-signaturev2-v2.15.10-s2', ext:'aar')
|
||||
|
||||
implementation project('IronSource.androidlib')
|
||||
|
||||
// Android Resolver Dependencies Start
|
||||
implementation 'androidx.recyclerview:recyclerview:1.2.1' // Assets/IronSource/Editor/ISMintegralAdapterDependencies.xml:40
|
||||
implementation 'com.adcolony:sdk:4.8.0' // Assets/IronSource/Editor/ISAdColonyAdapterDependencies.xml:8
|
||||
// Android Resolver Dependencies Start
|
||||
implementation 'com.google.firebase:firebase-analytics:21.4.0'
|
||||
implementation 'com.google.firebase:firebase-crashlytics:18.5.0'
|
||||
implementation 'com.google.firebase:firebase-messaging:23.3.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.2.1' // Assets/ThirdParty/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:9
|
||||
implementation 'com.android.installreferrer:installreferrer:2.1' // Assets/ThirdParty/AppsFlyer/Editor/AppsFlyerDependencies.xml:10
|
||||
implementation 'com.android.support:appcompat-v7:25.3.1' // Facebook.Unity.Editor.AndroidSupportLibraryResolver.addSupportLibraryDependency
|
||||
implementation 'com.android.support:cardview-v7:25.3.1' // Facebook.Unity.Editor.AndroidSupportLibraryResolver.addSupportLibraryDependency
|
||||
implementation 'com.android.support:customtabs:25.3.1' // Facebook.Unity.Editor.AndroidSupportLibraryResolver.addSupportLibraryDependency
|
||||
implementation 'com.android.support:customtabs:28.+' // Assets/ThirdParty/MaxSdk/Mediation/InMobi/Editor/Dependencies.xml:7
|
||||
implementation 'com.android.support:recyclerview-v7:28.+' // Assets/ThirdParty/MaxSdk/Mediation/InMobi/Editor/Dependencies.xml:6
|
||||
implementation 'com.android.support:support-v4:25.3.1' // Facebook.Unity.Editor.AndroidSupportLibraryResolver.addSupportLibraryDependency
|
||||
implementation 'com.applovin:applovin-sdk:11.10.1' // Assets/IronSource/Editor/ISAppLovinAdapterDependencies.xml:15
|
||||
implementation 'com.appsflyer:af-android-sdk:6.4.1' // Assets/ThirdParty/AppsFlyer/Editor/AppsFlyerDependencies.xml:6
|
||||
implementation 'com.appsflyer:unity-wrapper:6.4.1' // Assets/ThirdParty/AppsFlyer/Editor/AppsFlyerDependencies.xml:8
|
||||
implementation 'com.appsflyer:adrevenue:6.5.4' // Assets/ThirdParty/AppsFlyerAdrevenue/Editor/AppsFlyerAdRevenueDependencies.xml:4
|
||||
implementation 'com.appsflyer:unity-adrevenue-generic-wrapper:6.5.4' // Assets/ThirdParty/AppsFlyerAdrevenue/Editor/AppsFlyerAdRevenueDependencies.xml:5
|
||||
implementation 'com.chartboost:chartboost-sdk:9.3.1' // Assets/IronSource/Editor/ISChartboostAdapterDependencies.xml:15
|
||||
implementation 'com.facebook.android:audience-network-sdk:6.16.0' // Assets/ThirdParty/IronSource/Editor/ISFacebookAdapterDependencies.xml:8
|
||||
implementation 'com.applovin.mediation:bidmachine-adapter:3.2.1.0' // Assets/ThirdParty/MaxSdk/Mediation/BidMachine/Editor/Dependencies.xml:8
|
||||
implementation 'com.applovin.mediation:bigoads-adapter:5.2.1.0' // Assets/ThirdParty/MaxSdk/Mediation/BigoAds/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:bytedance-adapter:6.5.0.8.1' // Assets/ThirdParty/MaxSdk/Mediation/ByteDance/Editor/Dependencies.xml:8
|
||||
implementation 'com.applovin.mediation:chartboost-adapter:9.8.3.0' // Assets/ThirdParty/MaxSdk/Mediation/Chartboost/Editor/Dependencies.xml:8
|
||||
implementation 'com.applovin.mediation:facebook-adapter:[6.19.0.2]' // Assets/ThirdParty/MaxSdk/Mediation/Facebook/Editor/Dependencies.xml:8
|
||||
implementation 'com.applovin.mediation:fyber-adapter:8.3.6.1' // Assets/ThirdParty/MaxSdk/Mediation/Fyber/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:google-adapter:[24.2.0.0]' // Assets/ThirdParty/MaxSdk/Mediation/Google/Editor/Dependencies.xml:5
|
||||
implementation 'com.applovin.mediation:google-ad-manager-adapter:[24.2.0.0]' // Assets/ThirdParty/MaxSdk/Mediation/GoogleAdManager/Editor/Dependencies.xml:5
|
||||
implementation 'com.applovin.mediation:inmobi-adapter:10.8.2.0' // Assets/ThirdParty/MaxSdk/Mediation/InMobi/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:ironsource-adapter:8.7.0.0.0' // Assets/ThirdParty/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml:8
|
||||
implementation 'com.applovin.mediation:line-adapter:2025.1.10.1' // Assets/ThirdParty/MaxSdk/Mediation/Line/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:mobilefuse-adapter:1.9.0.0' // Assets/ThirdParty/MaxSdk/Mediation/MobileFuse/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:moloco-adapter:3.8.0.0' // Assets/ThirdParty/MaxSdk/Mediation/Moloco/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:mytarget-adapter:5.27.1.2' // Assets/ThirdParty/MaxSdk/Mediation/MyTarget/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:unityads-adapter:4.14.1.0' // Assets/ThirdParty/MaxSdk/Mediation/UnityAds/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:verve-adapter:3.3.0.0' // Assets/ThirdParty/MaxSdk/Mediation/Verve/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:vungle-adapter:7.4.3.2' // Assets/ThirdParty/MaxSdk/Mediation/Vungle/Editor/Dependencies.xml:4
|
||||
implementation 'com.applovin.mediation:mintegral-adapter:16.9.61.0' // Assets/ThirdParty/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:8
|
||||
implementation 'com.applovin.mediation:yandex-adapter:7.9.0.1' // Assets/ThirdParty/MaxSdk/Mediation/Yandex/Editor/Dependencies.xml:4
|
||||
implementation "com.taurusx.tax:ads:1.5.4" // Assets/ThirdParty/MaxSdk/Mediation/TaurusX/Editor/Dependencies.xml:4
|
||||
implementation "com.applovin.mediation:taurusXAdapters:1.3.0.1"
|
||||
implementation 'com.applovin:applovin-sdk:13.1.0' // Assets/ThirdParty/MaxSdk/AppLovin/Editor/Dependencies.xml:4
|
||||
implementation 'com.appsflyer:adrevenue:6.9.1' // Assets/ThirdParty/AppsFlyer/Editor/AppsFlyerAdRevenueDependencies.xml:4
|
||||
implementation 'com.appsflyer:unity-adrevenue-generic-wrapper:6.9.1' // Assets/ThirdParty/AppsFlyer/Editor/AppsFlyerAdRevenueDependencies.xml:5
|
||||
implementation 'com.appsflyer:af-android-sdk:6.13.0' // Assets/ThirdParty/AppsFlyer/Editor/AppsFlyerDependencies.xml:6
|
||||
implementation 'com.appsflyer:unity-wrapper:6.13.10' // Assets/ThirdParty/AppsFlyer/Editor/AppsFlyerDependencies.xml:8
|
||||
implementation 'com.facebook.android:facebook-applinks:[15.1,16)' // Assets/ThirdParty/FacebookSDK/Plugins/Editor/Dependencies.xml:6
|
||||
implementation 'com.facebook.android:facebook-core:[15.1,16)' // Assets/ThirdParty/FacebookSDK/Plugins/Editor/Dependencies.xml:5
|
||||
implementation 'com.facebook.android:facebook-gamingservices:[15.1,16)' // Assets/ThirdParty/FacebookSDK/Plugins/Editor/Dependencies.xml:9
|
||||
implementation 'com.facebook.android:facebook-login:[15.1,16)' // Assets/ThirdParty/FacebookSDK/Plugins/Editor/Dependencies.xml:7
|
||||
implementation 'com.facebook.android:facebook-share:[15.1,16)' // Assets/ThirdParty/FacebookSDK/Plugins/Editor/Dependencies.xml:8
|
||||
implementation 'com.fyber:marketplace-sdk:8.2.4' // Assets/ThirdParty/IronSource/Editor/ISFyberAdapterDependencies.xml:8
|
||||
implementation 'com.google.android.gms:play-services-ads:22.2.0' // Assets/ThirdParty/IronSource/Editor/ISAdMobAdapterDependencies.xml:8
|
||||
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1' // Assets/ThirdParty/IronSource/Editor/IronSourceSDKDependencies.xml:17
|
||||
implementation 'com.google.android.gms:play-services-basement:18.1.0' // Assets/ThirdParty/IronSource/Editor/IronSourceSDKDependencies.xml:25
|
||||
implementation 'com.ironsource.adapters:adcolonyadapter:4.3.15' // Assets/ThirdParty/IronSource/Editor/ISAdColonyAdapterDependencies.xml:16
|
||||
implementation 'com.ironsource.adapters:admobadapter:4.3.39' // Assets/ThirdParty/IronSource/Editor/ISAdMobAdapterDependencies.xml:16
|
||||
implementation 'com.ironsource.adapters:applovinadapter:4.3.39' // Assets/ThirdParty/IronSource/Editor/ISAppLovinAdapterDependencies.xml:8
|
||||
implementation 'com.ironsource.adapters:chartboostadapter:4.3.12' // Assets/ThirdParty/IronSource/Editor/ISChartboostAdapterDependencies.xml:8
|
||||
implementation 'com.ironsource.adapters:facebookadapter:4.3.45' // Assets/ThirdParty/IronSource/Editor/ISFacebookAdapterDependencies.xml:16
|
||||
implementation 'com.ironsource.adapters:fyberadapter:4.3.28' // Assets/ThirdParty/IronSource/Editor/ISFyberAdapterDependencies.xml:16
|
||||
implementation 'com.ironsource.adapters:mintegraladapter:4.3.19' // Assets/ThirdParty/IronSource/Editor/ISMintegralAdapterDependencies.xml:48
|
||||
implementation 'com.ironsource.adapters:pangleadapter:4.3.22' // Assets/ThirdParty/IronSource/Editor/ISPangleAdapterDependencies.xml:8
|
||||
implementation 'com.ironsource.adapters:tapjoyadapter:4.1.25' // Assets/ThirdParty/IronSource/Editor/ISTapJoyAdapterDependencies.xml:8
|
||||
implementation 'com.ironsource.adapters:unityadsadapter:4.3.33' // Assets/ThirdParty/IronSource/Editor/ISUnityAdsAdapterDependencies.xml:8
|
||||
implementation 'com.ironsource.adapters:vungleadapter:4.3.22' // Assets/ThirdParty/IronSource/Editor/ISVungleAdapterDependencies.xml:16
|
||||
implementation 'com.ironsource.sdk:mediationsdk:7.5.1' // Assets/ThirdParty/IronSource/Editor/IronSourceSDKDependencies.xml:9
|
||||
implementation 'com.mbridge.msdk.oversea:mbbanner:16.5.21' // Assets/ThirdParty/IronSource/Editor/ISMintegralAdapterDependencies.xml:24
|
||||
implementation 'com.mbridge.msdk.oversea:mbbid:16.5.21' // Assets/ThirdParty/IronSource/Editor/ISMintegralAdapterDependencies.xml:32
|
||||
implementation 'com.mbridge.msdk.oversea:newinterstitial:16.5.21' // Assets/ThirdParty/IronSource/Editor/ISMintegralAdapterDependencies.xml:8
|
||||
implementation 'com.mbridge.msdk.oversea:reward:16.5.21' // Assets/ThirdParty/IronSource/Editor/ISMintegralAdapterDependencies.xml:16
|
||||
implementation 'com.pangle.global:ads-sdk:5.5.0.5' // Assets/ThirdParty/IronSource/Editor/ISPangleAdapterDependencies.xml:15
|
||||
implementation 'com.google.android.gms:play-services-base:16.1.0' // Assets/ThirdParty/MaxSdk/Mediation/Chartboost/Editor/Dependencies.xml:9
|
||||
implementation 'com.parse.bolts:bolts-android:1.4.0' // Assets/ThirdParty/FacebookSDK/Plugins/Editor/Dependencies.xml:4
|
||||
implementation 'com.tapjoy:tapjoy-android-sdk:13.0.1' // Assets/ThirdParty/IronSource/Editor/ISTapJoyAdapterDependencies.xml:15
|
||||
implementation 'com.unity3d.ads:unity-ads:4.9.1' // Assets/ThirdParty/IronSource/Editor/ISUnityAdsAdapterDependencies.xml:15
|
||||
implementation 'com.vungle:vungle-ads:7.0.0' // Assets/ThirdParty/IronSource/Editor/ISVungleAdapterDependencies.xml:8
|
||||
implementation 'com.squareup.picasso:picasso:2.71828' // Assets/ThirdParty/MaxSdk/Mediation/InMobi/Editor/Dependencies.xml:5
|
||||
implementation 'com.google.android.ump:user-messaging-platform:2.1.0'
|
||||
// Android Resolver Dependencies End
|
||||
constraints {
|
||||
implementation('androidx.work:work-runtime:2.7.0') {
|
||||
because '''androidx.work:work-runtime:2.1.0 pulled from
|
||||
play-services-ads has a bug using PendingIntent without
|
||||
FLAG_IMMUTABLE or FLAG_MUTABLE and will fail in Apps
|
||||
targeting S+.'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
android {
|
||||
@ -159,34 +145,45 @@ def getSdkDir() {
|
||||
return local.getProperty('sdk.dir')
|
||||
}
|
||||
|
||||
def BuildIl2Cpp(String workingDir, String targetDirectory, String architecture, String abi, String configuration) {
|
||||
def BuildIl2Cpp(String workingDir, String configuration, String architecture, String abi, String[] staticLibraries) {
|
||||
def commandLineArgs = []
|
||||
commandLineArgs.add("--compile-cpp")
|
||||
commandLineArgs.add("--platform=Android")
|
||||
commandLineArgs.add("--architecture=" + architecture)
|
||||
commandLineArgs.add("--outputpath=" + workingDir + "/src/main/jniLibs/" + abi + "/libil2cpp.so")
|
||||
commandLineArgs.add("--libil2cpp-static")
|
||||
commandLineArgs.add("--baselib-directory=" + workingDir + "/src/main/jniStaticLibs/" + abi)
|
||||
commandLineArgs.add("--incremental-g-c-time-slice=3")
|
||||
commandLineArgs.add("--configuration=" + configuration)
|
||||
commandLineArgs.add("--dotnetprofile=unityaot-linux")
|
||||
commandLineArgs.add("--profiler-report")
|
||||
commandLineArgs.add("--profiler-output-file=" + workingDir + "/build/il2cpp_"+ abi + "_" + configuration + "/il2cpp_conv.traceevents")
|
||||
commandLineArgs.add("--print-command-line")
|
||||
commandLineArgs.add("--generatedcppdir=" + workingDir + "/src/main/Il2CppOutputProject/Source/il2cppOutput")
|
||||
commandLineArgs.add("--cachedirectory=" + workingDir + "/build/il2cpp_"+ abi + "_" + configuration + "/il2cpp_cache")
|
||||
commandLineArgs.add("--tool-chain-path=" + android.ndkDirectory)
|
||||
staticLibraries.eachWithIndex {fileName, i->
|
||||
commandLineArgs.add("--additional-libraries=" + workingDir + "/src/main/jniStaticLibs/" + abi + "/" + fileName)
|
||||
}
|
||||
def executableExtension = ""
|
||||
if (org.gradle.internal.os.OperatingSystem.current().isWindows()) {
|
||||
executableExtension = ".exe"
|
||||
commandLineArgs = commandLineArgs*.replace('\"', '\\\"')
|
||||
}
|
||||
exec {
|
||||
commandLine(workingDir + "/src/main/Il2CppOutputProject/IL2CPP/build/deploy/netcoreapp3.1/il2cpp",
|
||||
"--compile-cpp",
|
||||
"--libil2cpp-static",
|
||||
"--platform=Android",
|
||||
"--architecture=" + architecture,
|
||||
"--configuration=" + configuration,
|
||||
"--outputpath=" + workingDir + targetDirectory + abi + "/libil2cpp.so",
|
||||
"--cachedirectory=" + workingDir + "/build/il2cpp_"+ abi + "_" + configuration + "/il2cpp_cache",
|
||||
"--additional-include-directories=" + workingDir + "/src/main/Il2CppOutputProject/IL2CPP/external/bdwgc/include",
|
||||
"--additional-include-directories=" + workingDir + "/src/main/Il2CppOutputProject/IL2CPP/libil2cpp/include",
|
||||
"--tool-chain-path=" + android.ndkDirectory,
|
||||
"--map-file-parser=" + workingDir + "/src/main/Il2CppOutputProject/IL2CPP/MapFileParser/MapFileParser.exe",
|
||||
"--generatedcppdir=" + workingDir + "/src/main/Il2CppOutputProject/Source/il2cppOutput",
|
||||
"--baselib-directory=" + workingDir + "/src/main/jniStaticLibs/" + abi,
|
||||
"--dotnetprofile=unityaot")
|
||||
executable workingDir + "/src/main/Il2CppOutputProject/IL2CPP/build/deploy/il2cpp" + executableExtension
|
||||
args commandLineArgs
|
||||
environment "ANDROID_SDK_ROOT", getSdkDir()
|
||||
}
|
||||
delete workingDir + targetDirectory + abi + "/libil2cpp.sym.so"
|
||||
ant.move(file: workingDir + targetDirectory + abi + "/libil2cpp.dbg.so", tofile: workingDir + "/symbols/" + abi + "/libil2cpp.so")
|
||||
delete workingDir + "/src/main/jniLibs/" + abi + "/libil2cpp.sym.so"
|
||||
ant.move(file: workingDir + "/src/main/jniLibs/" + abi + "/libil2cpp.dbg.so", tofile: workingDir + "/symbols/" + abi + "/libil2cpp.so")
|
||||
}
|
||||
|
||||
android {
|
||||
task BuildIl2CppTask {
|
||||
doLast {
|
||||
BuildIl2Cpp(projectDir.toString().replaceAll('\\\\', '/'), '/src/main/jniLibs/', 'ARMv7', 'armeabi-v7a', 'Release');
|
||||
BuildIl2Cpp(projectDir.toString().replaceAll('\\\\', '/'), '/src/main/jniLibs/', 'ARM64', 'arm64-v8a', 'Release');
|
||||
BuildIl2Cpp(projectDir.toString().replaceAll('\\\\', '/'), 'Release', 'armv7', 'armeabi-v7a', [ ] as String[]);
|
||||
BuildIl2Cpp(projectDir.toString().replaceAll('\\\\', '/'), 'Release', 'arm64', 'arm64-v8a', [ ] as String[]);
|
||||
}
|
||||
}
|
||||
afterEvaluate {
|
||||
|
||||
30
BFVersions/android/dz_google_apk/unityLibrary/src/main/AndroidManifest.xml
Normal file → Executable file
30
BFVersions/android/dz_google_apk/unityLibrary/src/main/AndroidManifest.xml
Normal file → Executable file
@ -3,8 +3,6 @@
|
||||
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
|
||||
<application
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@mipmap/app_icon"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
<activity android:name="com.unity3d.player.UnityPlayerActivity" android:label="@string/app_name" android:screenOrientation="portrait" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density" android:resizeableActivity="false" android:hardwareAccelerated="false" android:exported="true">
|
||||
<intent-filter>
|
||||
@ -14,7 +12,7 @@
|
||||
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
|
||||
</activity>
|
||||
<!-- [START firebase_service] -->
|
||||
<meta-data
|
||||
<!-- <meta-data
|
||||
android:name="com.google.firebase.messaging.default_notification_icon"
|
||||
android:resource="@drawable/firebase_icon" />
|
||||
<service
|
||||
@ -23,7 +21,7 @@
|
||||
<intent-filter>
|
||||
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
</service> -->
|
||||
<!-- [END firebase_service] -->
|
||||
<activity android:name="com.facebook.unity.FBUnityLoginActivity" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
|
||||
<activity android:name="com.facebook.unity.FBUnityDialogsActivity" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
|
||||
@ -33,26 +31,35 @@
|
||||
<activity android:name="com.facebook.unity.FBUnityGameRequestActivity" />
|
||||
<activity android:name="com.facebook.unity.FBUnityCreateGameGroupActivity" />
|
||||
<activity android:name="com.facebook.unity.FBUnityJoinGameGroupActivity" />
|
||||
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="fb277827051329111" />
|
||||
<meta-data android:name="com.facebook.sdk.ClientToken" android:value="cd6be8cc57dff789f3476ee1b25e2410"/>
|
||||
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="fb491773936518549" />
|
||||
<meta-data android:name="com.facebook.sdk.ClientToken" android:value="2d2cb45aeb5ddb18189e8b7378ddcaa5"/>
|
||||
<meta-data android:name="com.facebook.sdk.AutoLogAppEventsEnabled" android:value="true" />
|
||||
<meta-data android:name="com.facebook.sdk.AdvertiserIDCollectionEnabled" android:value="true" />
|
||||
<provider android:name="com.facebook.FacebookContentProvider" android:authorities="com.facebook.app.FacebookContentProvider277827051329111" android:exported="true" />
|
||||
<provider android:name="com.facebook.FacebookContentProvider" android:authorities="com.facebook.app.FacebookContentProvider491773936518549" android:exported="true" />
|
||||
<meta-data android:name="unity.splash-mode" android:value="0" />
|
||||
<meta-data android:name="unity.splash-enable" android:value="True" />
|
||||
<meta-data android:name="unity.allow-resizable-window" android:value="False" />
|
||||
<!--本地推送-->
|
||||
<receiver android:name="com.unity.androidnotifications.UnityNotificationManager" android:exported="false" />
|
||||
<receiver android:name="com.unity.androidnotifications.UnityNotificationRestartOnBootReceiver" android:enabled="false" android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<meta-data android:name="com.unity.androidnotifications.exact_scheduling" android:value="0" />
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.ads.APPLICATION_ID"
|
||||
android:value="ca-app-pub-8252390069143459~7841203986"/>
|
||||
android:value="ca-app-pub-8252390069143459~5042842686"/>
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.ads.flag.OPTIMIZE_INITIALIZATION"
|
||||
android:value="true"/>
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.ads.flag.OPTIMIZE_AD_LOADING"
|
||||
android:value="true"/>
|
||||
<meta-data android:name="applovin.sdk.key" android:value="9uHgeBwag3NXva9MC23ToO3q11Ve59bF1uwg4qGltdGmCQ7OSByFZ_3b1ZF7krMlkHQo5gXzIokVDsvg1rwbr-" />
|
||||
<!-- <meta-data android:name="unity.build-id" android:value="49055670-6ef7-4715-954e-f4b0917c17e3" /> -->
|
||||
<!-- 每次打包需要替换unity.build-id !-->
|
||||
REPLACE_BUILD_ID
|
||||
<!-- REPLACE_BUILD_ID -->
|
||||
<!-- 刘海屏相关 -->
|
||||
<!--华为-->
|
||||
<meta-data android:name="android.notch_support" android:value="true" />
|
||||
@ -64,8 +71,8 @@
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK”"/>
|
||||
<uses-permission android:name='android.permission.POST_NOTIFICATIONS'/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.location" android:required="false" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
@ -76,4 +83,5 @@
|
||||
<uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false" />
|
||||
<uses-permission android:name="com.google.android.gms.permission.AD_ID"/>
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
</manifest>
|
||||
21
BFVersions/android/dz_google_apk/unityLibrary/src/main/java/com/unity3d/player/UnityPlayerActivity.java
Normal file → Executable file
21
BFVersions/android/dz_google_apk/unityLibrary/src/main/java/com/unity3d/player/UnityPlayerActivity.java
Normal file → Executable file
@ -12,11 +12,10 @@ import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.os.Process;
|
||||
// import android.os.Build;
|
||||
|
||||
// import com.chartboost.sdk.Chartboost;
|
||||
import com.juzu.dz.third.GooglePlugin;
|
||||
import com.ironsource.mediationsdk.IronSource;
|
||||
// import com.ironsource.mediationsdk.IronSource;
|
||||
|
||||
public class UnityPlayerActivity extends Activity implements IUnityPlayerLifecycleEvents
|
||||
{
|
||||
@ -111,11 +110,13 @@ public class UnityPlayerActivity extends Activity implements IUnityPlayerLifecyc
|
||||
{
|
||||
super.onPause();
|
||||
|
||||
MultiWindowSupport.saveMultiWindowMode(this);
|
||||
|
||||
if (MultiWindowSupport.getAllowResizableWindow(this))
|
||||
return;
|
||||
|
||||
mUnityPlayer.pause();
|
||||
IronSource.onPause(this);
|
||||
// IronSource.onPause(this);
|
||||
}
|
||||
|
||||
// Resume Unity
|
||||
@ -123,21 +124,11 @@ public class UnityPlayerActivity extends Activity implements IUnityPlayerLifecyc
|
||||
{
|
||||
super.onResume();
|
||||
|
||||
if (MultiWindowSupport.getAllowResizableWindow(this))
|
||||
if (MultiWindowSupport.getAllowResizableWindow(this) && !MultiWindowSupport.isMultiWindowModeChangedToTrue(this))
|
||||
return;
|
||||
|
||||
mUnityPlayer.resume();
|
||||
IronSource.onResume(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
// If an interstitial is on screen, close it.
|
||||
// if (Chartboost.onBackPressed()) {
|
||||
// return;
|
||||
// } else {
|
||||
// super.onBackPressed();
|
||||
// }
|
||||
// IronSource.onResume(this);
|
||||
}
|
||||
|
||||
// Low Memory Unity
|
||||
|
||||
0
BFVersions/android/dz_google_apk/unityLibrary/src/main/res/xml/network_security_config.xml
Normal file → Executable file
0
BFVersions/android/dz_google_apk/unityLibrary/src/main/res/xml/network_security_config.xml
Normal file → Executable file
0
BFVersions/android/dz_release/build.gradle
Normal file → Executable file
0
BFVersions/android/dz_release/build.gradle
Normal file → Executable file
0
BFVersions/android/dz_release/gradle.properties
Normal file → Executable file
0
BFVersions/android/dz_release/gradle.properties
Normal file → Executable file
2
BFVersions/android/dz_release/unityLibrary/build.gradle
Normal file → Executable file
2
BFVersions/android/dz_release/unityLibrary/build.gradle
Normal file → Executable file
@ -30,7 +30,7 @@ dependencies {
|
||||
implementation(name: 'ThinkingSDK', ext:'aar')
|
||||
implementation(name: 'UnityUtils-release', ext:'aar')
|
||||
implementation 'com.google.android.gms:play-services-auth:20.1.0'
|
||||
implementation "com.android.billingclient:billing:5.0.0"
|
||||
implementation "com.android.billingclient:billing:4.0.0"
|
||||
implementation platform('com.google.firebase:firebase-bom:29.2.1')
|
||||
implementation 'com.google.firebase:firebase-analytics:21.1.0'
|
||||
implementation 'com.google.firebase:firebase-messaging'
|
||||
|
||||
15
BFVersions/android/dz_release/unityLibrary/src/main/AndroidManifest.xml
Normal file → Executable file
15
BFVersions/android/dz_release/unityLibrary/src/main/AndroidManifest.xml
Normal file → Executable file
@ -19,13 +19,7 @@
|
||||
<!-- Sample AdMob App ID: ca-app-pub-3940256099942544~3347511713 -->
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.ads.APPLICATION_ID"
|
||||
android:value="ca-app-pub-8252390069143459~7841203986"/>
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.ads.flag.OPTIMIZE_INITIALIZATION"
|
||||
android:value="true"/>
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.ads.flag.OPTIMIZE_AD_LOADING"
|
||||
android:value="true"/>
|
||||
android:value="ca-app-pub-8252390069143459~1801140942"/>
|
||||
<!-- <meta-data android:name="unity.build-id" android:value="49055670-6ef7-4715-954e-f4b0917c17e3" /> -->
|
||||
<!-- 每次打包需要替换unity.build-id !-->
|
||||
REPLACE_BUILD_ID
|
||||
@ -39,10 +33,15 @@
|
||||
<uses-feature android:name="android.hardware.vulkan.version" android:required="false" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK”"/>
|
||||
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.location" android:required="false" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.camera.front" android:required="false" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-feature android:name="android.hardware.microphone" android:required="false" />
|
||||
|
||||
12
BFVersions/android/dz_release/unityLibrary/src/main/java/com/unity3d/player/UnityPlayerActivity.java
Normal file → Executable file
12
BFVersions/android/dz_release/unityLibrary/src/main/java/com/unity3d/player/UnityPlayerActivity.java
Normal file → Executable file
@ -14,7 +14,7 @@ import android.view.WindowManager;
|
||||
import android.os.Process;
|
||||
// import android.os.Build;
|
||||
|
||||
// import com.chartboost.sdk.Chartboost;
|
||||
import com.chartboost.sdk.Chartboost;
|
||||
import com.juzu.dz.third.GooglePlugin;
|
||||
import com.ironsource.mediationsdk.IronSource;
|
||||
|
||||
@ -133,11 +133,11 @@ public class UnityPlayerActivity extends Activity implements IUnityPlayerLifecyc
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
// If an interstitial is on screen, close it.
|
||||
// if (Chartboost.onBackPressed()) {
|
||||
// return;
|
||||
// } else {
|
||||
// super.onBackPressed();
|
||||
// }
|
||||
if (Chartboost.onBackPressed()) {
|
||||
return;
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
// Low Memory Unity
|
||||
|
||||
0
BFVersions/android/dz_release/unityLibrary/src/main/res/xml/network_security_config.xml
Normal file → Executable file
0
BFVersions/android/dz_release/unityLibrary/src/main/res/xml/network_security_config.xml
Normal file → Executable file
25
BFVersions/android/google_common/launcher/build.gradle
Normal file → Executable file
25
BFVersions/android/google_common/launcher/build.gradle
Normal file → Executable file
@ -1,9 +1,15 @@
|
||||
// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'applovin-quality-service'
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
apply plugin: 'com.google.firebase.crashlytics'
|
||||
|
||||
applovin {
|
||||
// NOTE: DO NOT CHANGE - this is NOT your AppLovin MAX SDK key - this is a derived key.
|
||||
apiKey 'c88aa3b89fe7f00054cac82dfdd1621aa02d691dd1d08b9da536e61cccf411fc362937666323b3df646456'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':unityLibrary')
|
||||
|
||||
@ -18,6 +24,16 @@ android {
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
release {
|
||||
storePassword="REPLACE_PASSWORD"
|
||||
keyPassword="REPLACE_PASSWORD"
|
||||
keyAlias="juzu"
|
||||
storeFile=file("../../keystore/dz_keystore.jks")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 24
|
||||
targetSdkVersion 34
|
||||
@ -31,7 +47,7 @@ android {
|
||||
}
|
||||
|
||||
aaptOptions {
|
||||
noCompress = ['.ress', '.resource', '.obb'] + unityStreamingAssets.tokenize(', ')
|
||||
noCompress = ['.unity3d', '.ress', '.resource', '.obb', '.bundle', '.unityexp'] + unityStreamingAssets.tokenize(', ')
|
||||
ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~"
|
||||
}
|
||||
|
||||
@ -43,19 +59,22 @@ android {
|
||||
debug {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt')
|
||||
signingConfig signingConfigs.debug
|
||||
signingConfig signingConfigs.release
|
||||
jniDebuggable true
|
||||
}
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt')
|
||||
signingConfig signingConfigs.debug
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
doNotStrip '*/armeabi-v7a/*.so'
|
||||
doNotStrip '*/arm64-v8a/*.so'
|
||||
jniLibs {
|
||||
useLegacyPackaging = true
|
||||
}
|
||||
}
|
||||
|
||||
bundle {
|
||||
|
||||
50
BFVersions/android/google_common/launcher/google-services.json
Normal file → Executable file
50
BFVersions/android/google_common/launcher/google-services.json
Normal file → Executable file
@ -1,60 +1,26 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "1008416471093",
|
||||
"project_id": "knights-combo",
|
||||
"storage_bucket": "knights-combo.appspot.com"
|
||||
"project_number": "22951947163",
|
||||
"project_id": "pull-pull-pull-heroes",
|
||||
"storage_bucket": "pull-pull-pull-heroes.firebasestorage.app"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:1008416471093:android:121c54160b7045e499d97c",
|
||||
"mobilesdk_app_id": "1:22951947163:android:378ebaf483bc3fb9304f3e",
|
||||
"android_client_info": {
|
||||
"package_name": "com.combo.heroes.puzzle.rpg"
|
||||
"package_name": "com.fortune.td.game.global"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "1008416471093-e1a8gso0q6mpangmi7lltjilfmqeqp6u.apps.googleusercontent.com",
|
||||
"client_type": 1,
|
||||
"android_info": {
|
||||
"package_name": "com.combo.heroes.puzzle.rpg",
|
||||
"certificate_hash": "3d9f0e5ebcb906418204e1a41cd40968a36c71cc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"client_id": "1008416471093-eolgs4t98pog1q3oltg4vh726vpggqbd.apps.googleusercontent.com",
|
||||
"client_type": 1,
|
||||
"android_info": {
|
||||
"package_name": "com.combo.heroes.puzzle.rpg",
|
||||
"certificate_hash": "dd7bea95dbb468b776ad9e979535689371113698"
|
||||
}
|
||||
},
|
||||
{
|
||||
"client_id": "1008416471093-e47s7u8a7v31ulr2f7e9j1mdm9llepum.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"oauth_client": [],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyDtkUzjjkNiAZszdepIDIYss0ioNNbjncA"
|
||||
"current_key": "AIzaSyAmIdtI6ZwxXfCVILmtZEr9y4CP_e9JpFE"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "1008416471093-e47s7u8a7v31ulr2f7e9j1mdm9llepum.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
},
|
||||
{
|
||||
"client_id": "1008416471093-78jluae6d1tdl8l4qkul3hut7lckd1kc.apps.googleusercontent.com",
|
||||
"client_type": 2,
|
||||
"ios_info": {
|
||||
"bundle_id": "com.combo.heroes.puzzle.rpg",
|
||||
"app_store_id": "6450101181"
|
||||
}
|
||||
}
|
||||
]
|
||||
"other_platform_oauth_client": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
0
BFVersions/android/google_common/launcher/src/main/AndroidManifest.xml
Normal file → Executable file
0
BFVersions/android/google_common/launcher/src/main/AndroidManifest.xml
Normal file → Executable file
BIN
BFVersions/android/google_common/launcher/src/main/res/drawable/firebase_icon.png
Normal file → Executable file
BIN
BFVersions/android/google_common/launcher/src/main/res/drawable/firebase_icon.png
Normal file → Executable file
Binary file not shown.
|
Before Width: | Height: | Size: 581 B After Width: | Height: | Size: 710 B |
2
BFVersions/android/google_common/launcher/src/main/res/values-es/strings.xml
Normal file → Executable file
2
BFVersions/android/google_common/launcher/src/main/res/values-es/strings.xml
Normal file → Executable file
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Combo de Jinetes</string>
|
||||
<string name="app_name">Pull Pull Pull Heroes</string>
|
||||
</resources>
|
||||
2
BFVersions/android/google_common/launcher/src/main/res/values-in/strings.xml
Normal file → Executable file
2
BFVersions/android/google_common/launcher/src/main/res/values-in/strings.xml
Normal file → Executable file
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Ksatria Kombo</string>
|
||||
<string name="app_name">Pull Pull Pull Heroes</string>
|
||||
</resources>
|
||||
2
BFVersions/android/google_common/launcher/src/main/res/values-ja/strings.xml
Normal file → Executable file
2
BFVersions/android/google_common/launcher/src/main/res/values-ja/strings.xml
Normal file → Executable file
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">ナイト戦線</string>
|
||||
<string name="app_name">プルせよ!ヒーローズ</string>
|
||||
</resources>
|
||||
2
BFVersions/android/google_common/launcher/src/main/res/values-ko/strings.xml
Normal file → Executable file
2
BFVersions/android/google_common/launcher/src/main/res/values-ko/strings.xml
Normal file → Executable file
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">워리어 콤보</string>
|
||||
<string name="app_name">픽미픽미 영웅</string>
|
||||
</resources>
|
||||
2
BFVersions/android/google_common/launcher/src/main/res/values-pt/strings.xml
Normal file → Executable file
2
BFVersions/android/google_common/launcher/src/main/res/values-pt/strings.xml
Normal file → Executable file
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Cavaleiros do Combo</string>
|
||||
<string name="app_name">Pull Pull Pull Heroes</string>
|
||||
</resources>
|
||||
2
BFVersions/android/google_common/launcher/src/main/res/values-th/strings.xml
Normal file → Executable file
2
BFVersions/android/google_common/launcher/src/main/res/values-th/strings.xml
Normal file → Executable file
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">อัศวินคอมโบ</string>
|
||||
<string name="app_name">Pull Pull Pull Heroes</string>
|
||||
</resources>
|
||||
0
BFVersions/android/google_common/launcher/src/main/res/values-v21/styles.xml
Normal file → Executable file
0
BFVersions/android/google_common/launcher/src/main/res/values-v21/styles.xml
Normal file → Executable file
0
BFVersions/android/google_common/launcher/src/main/res/values-v28/styles.xml
Normal file → Executable file
0
BFVersions/android/google_common/launcher/src/main/res/values-v28/styles.xml
Normal file → Executable file
0
BFVersions/android/google_common/launcher/src/main/res/values-v30/freeformwindow.xml
Normal file → Executable file
0
BFVersions/android/google_common/launcher/src/main/res/values-v30/freeformwindow.xml
Normal file → Executable file
2
BFVersions/android/google_common/launcher/src/main/res/values-vi/strings.xml
Normal file → Executable file
2
BFVersions/android/google_common/launcher/src/main/res/values-vi/strings.xml
Normal file → Executable file
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Kỵ Sĩ Liên Hoàn</string>
|
||||
<string name="app_name">Phiêu Lưu Sinh Tồn - VTC Game</string>
|
||||
</resources>
|
||||
2
BFVersions/android/google_common/launcher/src/main/res/values-zh-rTW/strings.xml
Normal file → Executable file
2
BFVersions/android/google_common/launcher/src/main/res/values-zh-rTW/strings.xml
Normal file → Executable file
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">賽賽軍團</string>
|
||||
<string name="app_name">抽抽抽英雄</string>
|
||||
</resources>
|
||||
2
BFVersions/android/google_common/launcher/src/main/res/values-zh/strings.xml
Normal file → Executable file
2
BFVersions/android/google_common/launcher/src/main/res/values-zh/strings.xml
Normal file → Executable file
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">赛赛军团</string>
|
||||
<string name="app_name">抽抽抽英雄</string>
|
||||
</resources>
|
||||
0
BFVersions/android/google_common/launcher/src/main/res/values/freeformwindow.xml
Normal file → Executable file
0
BFVersions/android/google_common/launcher/src/main/res/values/freeformwindow.xml
Normal file → Executable file
0
BFVersions/android/google_common/launcher/src/main/res/values/ids.xml
Normal file → Executable file
0
BFVersions/android/google_common/launcher/src/main/res/values/ids.xml
Normal file → Executable file
2
BFVersions/android/google_common/launcher/src/main/res/values/strings.xml
Normal file → Executable file
2
BFVersions/android/google_common/launcher/src/main/res/values/strings.xml
Normal file → Executable file
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Knights Combo</string>
|
||||
<string name="app_name">Pull Pull Pull Heroes</string>
|
||||
<string name="game_view_content_description">Game view</string>
|
||||
</resources>
|
||||
0
BFVersions/android/google_common/launcher/src/main/res/values/styles.xml
Normal file → Executable file
0
BFVersions/android/google_common/launcher/src/main/res/values/styles.xml
Normal file → Executable file
0
BFVersions/android/google_common/unityLibrary/src/main/java/com/juzu/dz/message/BFMessage.java
Normal file → Executable file
0
BFVersions/android/google_common/unityLibrary/src/main/java/com/juzu/dz/message/BFMessage.java
Normal file → Executable file
0
BFVersions/android/google_common/unityLibrary/src/main/java/com/juzu/dz/third/BFFirebaseMessagingService.java
Normal file → Executable file
0
BFVersions/android/google_common/unityLibrary/src/main/java/com/juzu/dz/third/BFFirebaseMessagingService.java
Normal file → Executable file
39
BFVersions/android/google_common/unityLibrary/src/main/java/com/juzu/dz/third/GoogleAdmobRewardedVideo.java
Normal file → Executable file
39
BFVersions/android/google_common/unityLibrary/src/main/java/com/juzu/dz/third/GoogleAdmobRewardedVideo.java
Normal file → Executable file
@ -27,13 +27,15 @@
|
||||
// import java.util.Map;
|
||||
|
||||
// public class GoogleAdmobRewardedVideo {
|
||||
// private final String AD_UNIT_ID = "ca-app-pub-1136292565368915/9438857158";
|
||||
// // 这是b2的id,不能直接用
|
||||
// // private final String AD_UNIT_ID = "ca-app-pub-1136292565368915/9438857158";
|
||||
// private final String AD_UNIT_ID = "";
|
||||
// private final String LOG_TAG = "RewardedVideo";
|
||||
// private static volatile GoogleAdmobRewardedVideo sInstance;
|
||||
// private RewardedAd rewardedAd;
|
||||
// private String adPlacement = "";
|
||||
|
||||
// private boolean isLoading = false;
|
||||
// boolean isLoading;
|
||||
|
||||
// public static GoogleAdmobRewardedVideo getInstance()
|
||||
// {
|
||||
@ -64,6 +66,8 @@
|
||||
// });
|
||||
|
||||
// loadRewardedAd(activity);
|
||||
|
||||
// // startGame(activity);
|
||||
// }
|
||||
|
||||
// private void pauseGame() {
|
||||
@ -73,10 +77,6 @@
|
||||
// }
|
||||
|
||||
// private void loadRewardedAd(Activity activity) {
|
||||
// if (isLoading)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// if (rewardedAd == null) {
|
||||
// isLoading = true;
|
||||
// Bundle bundle = new Bundle();
|
||||
@ -94,7 +94,7 @@
|
||||
// @Override
|
||||
// public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
|
||||
// // Handle the error.
|
||||
// Log.w(LOG_TAG, "loadAdError:" + loadAdError.getMessage());
|
||||
// Log.w("RewardedVideo", loadAdError.getMessage());
|
||||
// rewardedAd = null;
|
||||
// isLoading = false;
|
||||
// GooglePlugin.sendMessageToUnity(BFMessage.ADMOB_LOADED_FAILED, "");
|
||||
@ -109,7 +109,7 @@
|
||||
|
||||
// @Override
|
||||
// public void onAdLoaded(@NonNull RewardedAd newRewardedAd) {
|
||||
// Log.w(LOG_TAG, "onAdLoaded");
|
||||
// Log.w("RewardedVideo", "onAdLoaded");
|
||||
// rewardedAd = newRewardedAd;
|
||||
// isLoading = false;
|
||||
// GooglePlugin.sendMessageToUnity(BFMessage.ADMOB_LOADED, "");
|
||||
@ -138,9 +138,19 @@
|
||||
// }
|
||||
// }
|
||||
|
||||
// // private void startGame(Activity activity) {
|
||||
// // Hide the retry button, load the ad, and start the timer.
|
||||
// // if (rewardedAd != null && !isLoading) {
|
||||
// // loadRewardedAd(activity);
|
||||
// // }
|
||||
// // createTimer(COUNTER_TIME);
|
||||
// // gamePaused = false;
|
||||
// // gameOver = false;
|
||||
// // }
|
||||
|
||||
// private void showRewardedVideo(Activity activity) {
|
||||
// if (rewardedAd == null) {
|
||||
// Log.w(LOG_TAG, "The rewarded ad wasn't ready yet.");
|
||||
// Log.w("TAG", "The rewarded ad wasn't ready yet.");
|
||||
// return;
|
||||
// }
|
||||
|
||||
@ -243,11 +253,11 @@
|
||||
// @Override
|
||||
// public void onUserEarnedReward(@NonNull RewardItem rewardItem) {
|
||||
// // Handle the reward.
|
||||
// Log.w(LOG_TAG, "The user earned the reward.");
|
||||
// // int rewardAmount = rewardItem.getAmount();
|
||||
// // String rewardType = rewardItem.getType();
|
||||
// // Log.w(LOG_TAG, "onUserEarnedReward rewardAmount = " + rewardAmount);
|
||||
// // Log.w(LOG_TAG, "onUserEarnedReward rewardType = " + rewardType);
|
||||
// Log.w("TAG", "The user earned the reward.");
|
||||
// int rewardAmount = rewardItem.getAmount();
|
||||
// String rewardType = rewardItem.getType();
|
||||
// Log.w(LOG_TAG, "onUserEarnedReward rewardAmount = " + rewardAmount);
|
||||
// Log.w(LOG_TAG, "onUserEarnedReward rewardType = " + rewardType);
|
||||
// // JSONObject json = new JSONObject();
|
||||
// // json.put("status", 0);
|
||||
// GooglePlugin.sendMessageToUnity(BFMessage.ADMOB_EARNED_REWARD, "");
|
||||
@ -276,6 +286,7 @@
|
||||
// }
|
||||
|
||||
// public void showFullScreenAds(Activity activity) {
|
||||
// Log.w(LOG_TAG, "showFullScreenAds");
|
||||
// showRewardedVideo(activity);
|
||||
// }
|
||||
|
||||
|
||||
2
BFVersions/android/google_common/unityLibrary/src/main/java/com/juzu/dz/third/GoogleBilling.java
Normal file → Executable file
2
BFVersions/android/google_common/unityLibrary/src/main/java/com/juzu/dz/third/GoogleBilling.java
Normal file → Executable file
@ -40,7 +40,7 @@ public class GoogleBilling {
|
||||
private Map<String, Purchase> mPurchase = new HashMap<String, Purchase>();
|
||||
private List<SkuDetails> mSubList = new ArrayList<SkuDetails>();
|
||||
private List<SkuDetails> mInAppList = new ArrayList<SkuDetails>();
|
||||
final private static String BASE_64_ENCODED_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq3fn02CUbrnNkF1PYXk1XHuJdJsnUMsUHXaYR83+ZPE2a3NgGHpVsrVakZK28RARQSz8E2x8qy+4bFPji1TTLq+MRY9CAcGzP4HB5eGKhRmsHABJNnfWgMiXxZ/mmW/yQawTY0zmeDX6Z/GSN3SeZo0PmlpM7ZFJpN42vYO6Fs5zgR05SAUDx3uaPwkhZ0Z2bIIhbWaVyxoMy2pDnCfCL5ym1nwdDa8tRMhZ1yWaDdY4KkJ92W0kbyMntjtL9QWFCGcRTGHVEoir4E2nc2bugaOkw0qegng00L65qWnfZ1GFgPW3uNexWsbEc2A5g//bL2/+yDVQWqiJtkdQMKyIKwIDAQAB";
|
||||
final private static String BASE_64_ENCODED_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtIC/9macCZdKcRamY6XOf+J+ncHwUzrRx18696PPH0kixqIAovJKAISUeZCH28NTBb/t4dwgnPRMjNsviH71BVDOK7ZSm2xkbhi4aQ8lB5afGso9nj0+RaaONQeHMW17sIkqd2DIjiMWlPwt65pdonwXZ4NqQJwNabXMhzHggI9fjHH9mJodqqrKkwwIQtFyDe6OYC9kv6DIHhsVVDTfwKbq5QLJEHnsJKJbhuemI0aN6qwSf8tUxLWRJN+P6g88+tfRo5mI7A+slLdcom8Yf+OSQoXGPQJ6xplrfABTB1V7JymfiZg7JHLql65SwG6zk/GFAD0VcIWTfeogvyElkQIDAQAB";
|
||||
|
||||
public static GoogleBilling getInstance()
|
||||
{
|
||||
|
||||
3
BFVersions/android/google_common/unityLibrary/src/main/java/com/juzu/dz/third/GoogleLogin.java
Normal file → Executable file
3
BFVersions/android/google_common/unityLibrary/src/main/java/com/juzu/dz/third/GoogleLogin.java
Normal file → Executable file
@ -24,7 +24,8 @@ public class GoogleLogin {
|
||||
private static volatile GoogleLogin sInstance;
|
||||
private GoogleSignInClient mGoogleSignInClient;
|
||||
private static final int REQUEST_CODE_GOOGLE_SIGN_IN = 1001; /* unique request id */
|
||||
private static final String server_client_token = "1008416471093-e47s7u8a7v31ulr2f7e9j1mdm9llepum.apps.googleusercontent.com";
|
||||
private static final String server_client_token = "22951947163-20850c0vsdknh7ts3nai4bs6j85dj5gl.apps.googleusercontent.com";
|
||||
|
||||
|
||||
public static GoogleLogin getInstance()
|
||||
{
|
||||
|
||||
212
BFVersions/android/google_common/unityLibrary/src/main/java/com/juzu/dz/third/GooglePlugin.java
Normal file → Executable file
212
BFVersions/android/google_common/unityLibrary/src/main/java/com/juzu/dz/third/GooglePlugin.java
Normal file → Executable file
@ -2,25 +2,51 @@ package com.juzu.dz.third;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.android.gms.tasks.OnCompleteListener;
|
||||
import com.google.android.gms.tasks.Task;
|
||||
import com.google.android.play.core.review.ReviewInfo;
|
||||
import com.google.android.play.core.review.ReviewManager;
|
||||
import com.google.android.play.core.review.ReviewManagerFactory;
|
||||
import com.google.android.play.core.review.testing.FakeReviewManager;
|
||||
import com.google.firebase.messaging.FirebaseMessaging;
|
||||
import com.google.firebase.analytics.FirebaseAnalytics;
|
||||
// import com.google.firebase.crashlytics.FirebaseCrashlytics;
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics;
|
||||
import com.juzu.dz.message.BFMessage;
|
||||
import com.unity3d.player.UnityPlayer;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import static com.google.firebase.crashlytics.internal.Logger.TAG;
|
||||
|
||||
import com.iabtcf.decoder.TCString;
|
||||
|
||||
import com.google.android.ump.ConsentDebugSettings;
|
||||
import com.google.android.ump.ConsentForm.OnConsentFormDismissedListener;
|
||||
import com.google.android.ump.ConsentInformation;
|
||||
import com.google.android.ump.ConsentInformation.PrivacyOptionsRequirementStatus;
|
||||
import com.google.android.ump.ConsentRequestParameters;
|
||||
import com.google.android.ump.FormError;
|
||||
import com.google.android.ump.UserMessagingPlatform;
|
||||
|
||||
public class GooglePlugin {
|
||||
private static final String LOG_TAG = "GooglePlugin";
|
||||
private static GoogleLogin mGoogleLogin = null;
|
||||
@ -30,6 +56,9 @@ public class GooglePlugin {
|
||||
public static FirebaseAnalytics mFirebaseAnalytics;
|
||||
// private FirebaseCrashlytics mFirebaseCrashlytics;
|
||||
|
||||
private static ConsentInformation consentInformation;
|
||||
private final AtomicBoolean isMobileAdsInitializeCalled = new AtomicBoolean(false);
|
||||
|
||||
public static void init(Activity activity){
|
||||
_activity = activity;
|
||||
mFirebaseAnalytics = FirebaseAnalytics.getInstance(_activity);
|
||||
@ -62,6 +91,11 @@ public class GooglePlugin {
|
||||
// }
|
||||
}
|
||||
|
||||
public static void initGDPR()
|
||||
{
|
||||
initConsentInformation(_activity);
|
||||
}
|
||||
|
||||
// 登录
|
||||
public static void login()
|
||||
{
|
||||
@ -197,7 +231,7 @@ public class GooglePlugin {
|
||||
@Override
|
||||
public void onComplete(@NonNull Task<String> task) {
|
||||
if (!task.isSuccessful()) {
|
||||
Log.w(LOG_TAG, "Fetching FCM registration token failed", task.getException());
|
||||
Log.w(TAG, "Fetching FCM registration token failed", task.getException());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -253,10 +287,10 @@ public class GooglePlugin {
|
||||
|
||||
// log crash
|
||||
public static void logCrash(String key, String stack) {
|
||||
// this.mFirebaseCrashlytics = FirebaseCrashlytics.getInstance();
|
||||
// if (this.mFirebaseCrashlytics == null)
|
||||
// return;
|
||||
// this.mFirebaseCrashlytics.setCustomKey(key, stack);
|
||||
// this.mFirebaseCrashlytics = FirebaseCrashlytics.getInstance();
|
||||
// if (this.mFirebaseCrashlytics == null)
|
||||
// return;
|
||||
// this.mFirebaseCrashlytics.setCustomKey(key, stack);
|
||||
}
|
||||
|
||||
// set bundle to type
|
||||
@ -296,4 +330,170 @@ public class GooglePlugin {
|
||||
// mGoogleAdmobRewardedVideo.setAdPlacement(placement);
|
||||
// }
|
||||
}
|
||||
|
||||
private static String getSign(String algorithm) {
|
||||
try {
|
||||
PackageInfo info = _activity.getPackageManager().getPackageInfo(
|
||||
_activity.getPackageName(), PackageManager.GET_SIGNATURES);
|
||||
byte[] cert = info.signatures[0].toByteArray();
|
||||
MessageDigest md = MessageDigest.getInstance(algorithm);
|
||||
byte[] publicKey = md.digest(cert);
|
||||
StringBuffer hexString = new StringBuffer();
|
||||
for (int i = 0; i < publicKey.length; i++) {
|
||||
String appendString = Integer.toHexString(0xFF & publicKey[i])
|
||||
.toUpperCase(Locale.US);
|
||||
if (appendString.length() == 1)
|
||||
hexString.append("0");
|
||||
hexString.append(appendString);
|
||||
hexString.append(":");
|
||||
}
|
||||
String result = hexString.toString();
|
||||
return result.substring(0, result.length() - 1);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 初始化GDPR
|
||||
public static void initConsentInformation(Activity activity)
|
||||
{
|
||||
// ConsentDebugSettings debugSettings = new ConsentDebugSettings.Builder(activity)
|
||||
// .setDebugGeography(ConsentDebugSettings.DebugGeography.DEBUG_GEOGRAPHY_EEA)
|
||||
// .addTestDeviceHashedId("F760B5027ECC69D34A80D3957A9841A9") // mumu:D77B7887E3BC1B47009579C304F39BE4 vivo:F760B5027ECC69D34A80D3957A9841A9
|
||||
// .build();
|
||||
|
||||
// ConsentRequestParameters params = new ConsentRequestParameters
|
||||
// .Builder()
|
||||
// .setConsentDebugSettings(debugSettings)
|
||||
// .build();
|
||||
|
||||
ConsentRequestParameters params = new ConsentRequestParameters
|
||||
.Builder()
|
||||
.setTagForUnderAgeOfConsent(false)
|
||||
.build();
|
||||
|
||||
// Requesting an update to consent information should be called on every app launch.
|
||||
consentInformation = UserMessagingPlatform.getConsentInformation(activity);
|
||||
consentInformation.requestConsentInfoUpdate(
|
||||
activity,
|
||||
params,
|
||||
() -> {
|
||||
UserMessagingPlatform.loadAndShowConsentFormIfRequired(
|
||||
activity,
|
||||
loadAndShowError -> {
|
||||
if (loadAndShowError != null) {
|
||||
// Consent gathering failed.
|
||||
Log.w(TAG, String.format("%s: %s",
|
||||
loadAndShowError.getErrorCode(),
|
||||
loadAndShowError.getMessage()));
|
||||
}
|
||||
// Consent has been gathered.
|
||||
GooglePlugin.monitorConsentString();
|
||||
}
|
||||
);
|
||||
},
|
||||
requestConsentError -> {
|
||||
// Consent gathering failed.
|
||||
Log.w(TAG, String.format("%s: %s",
|
||||
requestConsentError.getErrorCode(),
|
||||
requestConsentError.getMessage()));
|
||||
});
|
||||
|
||||
// Check if you can initialize the Google Mobile Ads SDK in parallel
|
||||
// while checking for new consent information. Consent obtained in
|
||||
// the previous session can be used to request ads.
|
||||
|
||||
// 不管结果,直接初始化广告
|
||||
// init(activity);
|
||||
}
|
||||
|
||||
public static boolean isPrivacyOptionsRequired()
|
||||
{
|
||||
return consentInformation.getPrivacyOptionsRequirementStatus() == PrivacyOptionsRequirementStatus.REQUIRED;
|
||||
}
|
||||
|
||||
public static void showPrivacyOptionsForm()
|
||||
{
|
||||
_activity.runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
UserMessagingPlatform.showPrivacyOptionsForm(
|
||||
_activity,
|
||||
formError -> {
|
||||
if (formError != null) {
|
||||
// Handle the error.
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void resetGDPR()
|
||||
{
|
||||
consentInformation.reset();
|
||||
}
|
||||
|
||||
// GDPR IAB TCF
|
||||
public static void monitorConsentString() {
|
||||
if (mFirebaseAnalytics == null)
|
||||
return;
|
||||
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(UnityPlayer.currentActivity.getApplicationContext());
|
||||
if (sharedPrefs == null)
|
||||
return;
|
||||
String iabKey = "IABTCF_TCString";
|
||||
String tcString = sharedPrefs.getString(iabKey, "");
|
||||
if (tcString == "" || tcString.isEmpty())
|
||||
return;
|
||||
// ad_storage
|
||||
boolean adStorageAllowed = TCString.decode(tcString).getPurposesConsent().contains(1);
|
||||
// Consent toggle in vendor setting (i.e. Google is not blocked from using consented data at vendor level)
|
||||
boolean googleConsent = TCString.decode(tcString).getVendorConsent().contains(755);
|
||||
// Legitimate interest toggle in vendor setting (i.e. Google is not blocked from their legitimate interest)
|
||||
// boolean googleInterest = TCString.decode(tcString).getVendorLegitimateInterest().contains(755);
|
||||
// We are checking if consent for ad_storage was given and that Google as vendor has not been excluded from using consented data
|
||||
FirebaseAnalytics.ConsentStatus consentStatus = adStorageAllowed && googleConsent ? FirebaseAnalytics.ConsentStatus.GRANTED : FirebaseAnalytics.ConsentStatus.DENIED;
|
||||
//
|
||||
// Set consent types.
|
||||
Map<FirebaseAnalytics.ConsentType, FirebaseAnalytics.ConsentStatus> consentMap = new EnumMap<>(FirebaseAnalytics.ConsentType.class);
|
||||
consentMap.put(FirebaseAnalytics.ConsentType.ANALYTICS_STORAGE, consentStatus);
|
||||
consentMap.put(FirebaseAnalytics.ConsentType.AD_STORAGE, consentStatus);
|
||||
consentMap.put(FirebaseAnalytics.ConsentType.AD_USER_DATA, consentStatus);
|
||||
consentMap.put(FirebaseAnalytics.ConsentType.AD_PERSONALIZATION, consentStatus);
|
||||
mFirebaseAnalytics.setConsent(consentMap);
|
||||
}
|
||||
|
||||
public static void requestStoreReview()
|
||||
{
|
||||
Activity activity = UnityPlayer.currentActivity;
|
||||
// 未实例Activity
|
||||
if (activity == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ReviewManager manager = ReviewManagerFactory.create(activity);
|
||||
// ReviewManager manager = new FakeReviewManager(activity); // 使用FakeReviewManager进行测试
|
||||
// 实例 Review Manager 失败
|
||||
if (manager == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Task<ReviewInfo> request = manager.requestReviewFlow();
|
||||
// 实例Review Request失败
|
||||
if (request == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
request.addOnCompleteListener(task -> {
|
||||
if (task.isSuccessful()) {
|
||||
// We can get the ReviewInfo object
|
||||
ReviewInfo reviewInfo = task.getResult();
|
||||
// launch review
|
||||
manager.launchReviewFlow(activity, reviewInfo);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
0
BFVersions/android/google_common/unityLibrary/src/main/java/com/juzu/dz/third/Security.java
Normal file → Executable file
0
BFVersions/android/google_common/unityLibrary/src/main/java/com/juzu/dz/third/Security.java
Normal file → Executable file
@ -0,0 +1,187 @@
|
||||
package com.unity.androidnotifications;
|
||||
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.KEY_ID;
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.TAG_UNITY;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.LinkedTransferQueue;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class UnityNotificationBackgroundThread extends Thread {
|
||||
private static abstract class Task {
|
||||
// returns true if notificationIds was modified (needs to be saved)
|
||||
public abstract boolean run(UnityNotificationManager manager, ConcurrentHashMap<Integer, Notification.Builder> notifications);
|
||||
}
|
||||
|
||||
private static class ScheduleNotificationTask extends Task {
|
||||
private int notificationId;
|
||||
private Notification.Builder notificationBuilder;
|
||||
private boolean isCustomized;
|
||||
private boolean isNew;
|
||||
|
||||
public ScheduleNotificationTask(int id, Notification.Builder builder, boolean customized, boolean addedNew) {
|
||||
notificationId = id;
|
||||
notificationBuilder = builder;
|
||||
isCustomized = customized;
|
||||
isNew = addedNew;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean run(UnityNotificationManager manager, ConcurrentHashMap<Integer, Notification.Builder> notifications) {
|
||||
String id = String.valueOf(notificationId);
|
||||
Integer ID = Integer.valueOf(notificationId);
|
||||
boolean didSchedule = false;
|
||||
try {
|
||||
UnityNotificationManager.mUnityNotificationManager.performNotificationScheduling(notificationId, notificationBuilder, isCustomized);
|
||||
didSchedule = true;
|
||||
} finally {
|
||||
// if failed to schedule or replace, remove
|
||||
if (!didSchedule) {
|
||||
notifications.remove(notificationId);
|
||||
manager.cancelPendingNotificationIntent(notificationId);
|
||||
manager.deleteExpiredNotificationIntent(id);
|
||||
}
|
||||
}
|
||||
|
||||
return isNew;
|
||||
}
|
||||
}
|
||||
|
||||
private static class CancelNotificationTask extends Task {
|
||||
private int notificationId;
|
||||
|
||||
public CancelNotificationTask(int id) {
|
||||
notificationId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean run(UnityNotificationManager manager, ConcurrentHashMap<Integer, Notification.Builder> notifications) {
|
||||
manager.cancelPendingNotificationIntent(notificationId);
|
||||
if (notifications.remove(notificationId) != null) {
|
||||
manager.deleteExpiredNotificationIntent(String.valueOf(notificationId));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static class CancelAllNotificationsTask extends Task {
|
||||
@Override
|
||||
public boolean run(UnityNotificationManager manager, ConcurrentHashMap<Integer, Notification.Builder> notifications) {
|
||||
if (notifications.isEmpty())
|
||||
return false;
|
||||
|
||||
Enumeration<Integer> ids = notifications.keys();
|
||||
while (ids.hasMoreElements()) {
|
||||
Integer notificationId = ids.nextElement();
|
||||
manager.cancelPendingNotificationIntent(notificationId);
|
||||
manager.deleteExpiredNotificationIntent(String.valueOf(notificationId));
|
||||
}
|
||||
|
||||
notifications.clear();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static class HousekeepingTask extends Task {
|
||||
UnityNotificationBackgroundThread thread;
|
||||
|
||||
public HousekeepingTask(UnityNotificationBackgroundThread th) {
|
||||
thread = th;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean run(UnityNotificationManager manager, ConcurrentHashMap<Integer, Notification.Builder> notifications) {
|
||||
HashSet<String> notificationIds = new HashSet<>();
|
||||
Enumeration<Integer> ids = notifications.keys();
|
||||
while (ids.hasMoreElements()) {
|
||||
notificationIds.add(String.valueOf(ids.nextElement()));
|
||||
}
|
||||
thread.performHousekeeping(notificationIds);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static final int TASKS_FOR_HOUSEKEEPING = 50;
|
||||
private LinkedTransferQueue<Task> mTasks = new LinkedTransferQueue();
|
||||
private ConcurrentHashMap<Integer, Notification.Builder> mScheduledNotifications;
|
||||
private UnityNotificationManager mManager;
|
||||
private int mTasksSinceHousekeeping = TASKS_FOR_HOUSEKEEPING; // we want hoursekeeping at the start
|
||||
|
||||
public UnityNotificationBackgroundThread(UnityNotificationManager manager, ConcurrentHashMap<Integer, Notification.Builder> scheduledNotifications) {
|
||||
mManager = manager;
|
||||
mScheduledNotifications = scheduledNotifications;
|
||||
// rescheduling after reboot may have loaded, otherwise load here
|
||||
if (mScheduledNotifications.size() == 0)
|
||||
loadNotifications();
|
||||
}
|
||||
|
||||
public void enqueueNotification(int id, Notification.Builder notificationBuilder, boolean customized, boolean addedNew) {
|
||||
mTasks.add(new UnityNotificationBackgroundThread.ScheduleNotificationTask(id, notificationBuilder, customized, addedNew));
|
||||
}
|
||||
|
||||
public void enqueueCancelNotification(int id) {
|
||||
mTasks.add(new CancelNotificationTask(id));
|
||||
}
|
||||
|
||||
public void enqueueCancelAllNotifications() {
|
||||
mTasks.add(new CancelAllNotificationsTask());
|
||||
}
|
||||
|
||||
private void enqueueHousekeeping() {
|
||||
mTasks.add(new HousekeepingTask(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
boolean haveChanges = false;
|
||||
while (true) {
|
||||
try {
|
||||
Task task = mTasks.take();
|
||||
haveChanges |= executeTask(mManager, task, mScheduledNotifications);
|
||||
if (!(task instanceof HousekeepingTask))
|
||||
++mTasksSinceHousekeeping;
|
||||
if (mTasks.size() == 0 && haveChanges) {
|
||||
haveChanges = false;
|
||||
enqueueHousekeeping();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
if (mTasks.isEmpty())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean executeTask(UnityNotificationManager manager, Task task, ConcurrentHashMap<Integer, Notification.Builder> notifications) {
|
||||
try {
|
||||
return task.run(manager, notifications);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG_UNITY, "Exception executing notification task", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void performHousekeeping(Set<String> notificationIds) {
|
||||
// don't do housekeeping if last task we did was housekeeping (other=1)
|
||||
boolean performHousekeeping = mTasksSinceHousekeeping >= TASKS_FOR_HOUSEKEEPING;
|
||||
mTasksSinceHousekeeping = 0;
|
||||
if (performHousekeeping)
|
||||
mManager.performNotificationHousekeeping(notificationIds);
|
||||
mManager.saveScheduledNotificationIDs(notificationIds);
|
||||
}
|
||||
|
||||
private void loadNotifications() {
|
||||
List<Notification.Builder> notifications = mManager.loadSavedNotifications();
|
||||
for (Notification.Builder builder : notifications) {
|
||||
int id = builder.getExtras().getInt(KEY_ID, -1);
|
||||
mScheduledNotifications.put(id, builder);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,67 @@
|
||||
package com.unity.androidnotifications;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.KEY_FIRE_TIME;
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.KEY_ID;
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.KEY_REPEAT_INTERVAL;
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.TAG_UNITY;
|
||||
|
||||
public class UnityNotificationRestartOnBootReceiver extends BroadcastReceiver {
|
||||
private static final long EXPIRATION_TRESHOLD = 600000; // 10 minutes
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent received_intent) {
|
||||
Log.d(TAG_UNITY, "Rescheduling notifications after restart");
|
||||
if (Intent.ACTION_BOOT_COMPLETED.equals(received_intent.getAction())) {
|
||||
AsyncTask.execute(() -> { rescheduleSavedNotifications(context); });
|
||||
}
|
||||
}
|
||||
|
||||
private static void rescheduleSavedNotifications(Context context) {
|
||||
UnityNotificationManager manager = UnityNotificationManager.getNotificationManagerImpl(context);
|
||||
List<Notification.Builder> saved_notifications = manager.loadSavedNotifications();
|
||||
Date currentDate = Calendar.getInstance().getTime();
|
||||
|
||||
for (Notification.Builder notificationBuilder : saved_notifications) {
|
||||
rescheduleNotification(manager, currentDate, notificationBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean rescheduleNotification(UnityNotificationManager manager, Date currentDate, Notification.Builder notificationBuilder) {
|
||||
try {
|
||||
Bundle extras = notificationBuilder.getExtras();
|
||||
long repeatInterval = extras.getLong(KEY_REPEAT_INTERVAL, 0L);
|
||||
long fireTime = extras.getLong(KEY_FIRE_TIME, 0L);
|
||||
Date fireTimeDate = new Date(fireTime);
|
||||
|
||||
boolean isRepeatable = repeatInterval > 0;
|
||||
|
||||
if (fireTimeDate.after(currentDate) || isRepeatable) {
|
||||
manager.scheduleAlarmWithNotification(notificationBuilder);
|
||||
return true;
|
||||
} else if (currentDate.getTime() - fireTime < EXPIRATION_TRESHOLD) {
|
||||
// notification is in the past, but not by much, send now
|
||||
int id = extras.getInt(KEY_ID);
|
||||
manager.notify(id, notificationBuilder);
|
||||
return true;
|
||||
} else {
|
||||
Log.d(TAG_UNITY, "Notification expired, not rescheduling, ID: " + extras.getInt(KEY_ID, -1));
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG_UNITY, "Failed to reschedule notification", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,654 @@
|
||||
package com.unity.androidnotifications;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.KEY_CHANNEL_ID;
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.KEY_FIRE_TIME;
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.KEY_ID;
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.KEY_INTENT_DATA;
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.KEY_LARGE_ICON;
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.KEY_NOTIFICATION;
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.KEY_REPEAT_INTERVAL;
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.KEY_SMALL_ICON;
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.KEY_SHOW_IN_FOREGROUND;
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.KEY_BIG_LARGE_ICON;
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.KEY_BIG_PICTURE;
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.KEY_BIG_CONTENT_TITLE;
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.KEY_BIG_SUMMARY_TEXT;
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.KEY_BIG_CONTENT_DESCRIPTION;
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.KEY_BIG_SHOW_WHEN_COLLAPSED;
|
||||
import static com.unity.androidnotifications.UnityNotificationManager.TAG_UNITY;
|
||||
|
||||
class UnityNotificationUtilities {
|
||||
/*
|
||||
We serialize notifications and save them to shared prefs, so that if app is killed, we can recreate them.
|
||||
The serialized BLOB starts with a four byte magic number descibing serialization type, followed by an integer version.
|
||||
IMPORTANT: IF YOU DO A CHANGE THAT AFFECTS THE LAYOUT, BUMP THE VERSION, AND ENSURE OLD VERSION STILL DESERIALIZES. ADD TEST.
|
||||
In real life app can get updated having old serialized notifications present, so we should be able to deserialize them.
|
||||
*/
|
||||
// magic stands for "Unity Mobile Notifications Notification"
|
||||
static final byte[] UNITY_MAGIC_NUMBER = new byte[] { 'U', 'M', 'N', 'N'};
|
||||
private static final byte[] UNITY_MAGIC_NUMBER_PARCELLED = new byte[] { 'U', 'M', 'N', 'P'};
|
||||
private static final int NOTIFICATION_SERIALIZATION_VERSION = 3;
|
||||
private static final int INTENT_SERIALIZATION_VERSION = 0;
|
||||
|
||||
static final String SAVED_NOTIFICATION_PRIMARY_KEY = "data";
|
||||
static final String SAVED_NOTIFICATION_FALLBACK_KEY = "fallback.data";
|
||||
|
||||
protected static int findResourceIdInContextByName(Context context, String name) {
|
||||
if (name == null)
|
||||
return 0;
|
||||
|
||||
try {
|
||||
Resources res = context.getResources();
|
||||
if (res != null) {
|
||||
int id = res.getIdentifier(name, "mipmap", context.getPackageName());
|
||||
if (id == 0)
|
||||
return res.getIdentifier(name, "drawable", context.getPackageName());
|
||||
else
|
||||
return id;
|
||||
}
|
||||
return 0;
|
||||
} catch (Resources.NotFoundException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Originally we used to serialize a bundle with predefined list of values.
|
||||
After we exposed entire Notification.Builder to users, this is not sufficient anymore.
|
||||
Unfortunately, while Notification itself is Parcelable and can be marshalled to bytes,
|
||||
it's contents are not guaranteed to be (Binder objects).
|
||||
Hence what we try to do here is:
|
||||
- serialize as is if notification is possibly customized by user
|
||||
- otherwise serialize our stuff, since there is nothing more
|
||||
*/
|
||||
protected static void serializeNotification(SharedPreferences prefs, Notification notification, boolean serializeParcel) {
|
||||
try {
|
||||
String serialized;
|
||||
ByteArrayOutputStream data = new ByteArrayOutputStream();
|
||||
DataOutputStream out = new DataOutputStream(data);
|
||||
if (serializeParcel) {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(KEY_NOTIFICATION, notification);
|
||||
if (serializeNotificationParcel(intent, out)) {
|
||||
out.close();
|
||||
byte[] bytes = data.toByteArray();
|
||||
serialized = Base64.encodeToString(bytes, 0, bytes.length, 0);
|
||||
} else {
|
||||
return; // failed
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (serializeNotificationCustom(notification, out)) {
|
||||
out.flush();
|
||||
byte[] bytes = data.toByteArray();
|
||||
serialized = Base64.encodeToString(bytes, 0, bytes.length, 0);
|
||||
} else {
|
||||
return; // failed
|
||||
}
|
||||
}
|
||||
|
||||
SharedPreferences.Editor editor = prefs.edit().clear();
|
||||
editor.putString(SAVED_NOTIFICATION_PRIMARY_KEY, serialized);
|
||||
editor.apply();
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG_UNITY, "Failed to serialize notification", e);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean serializeNotificationParcel(Intent intent, DataOutputStream out) {
|
||||
try {
|
||||
byte[] bytes = serializeParcelable(intent);
|
||||
if (bytes == null || bytes.length == 0)
|
||||
return false;
|
||||
out.write(UNITY_MAGIC_NUMBER_PARCELLED);
|
||||
out.writeInt(INTENT_SERIALIZATION_VERSION);
|
||||
out.writeInt(bytes.length);
|
||||
out.write(bytes);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG_UNITY, "Failed to serialize notification as Parcel", e);
|
||||
} catch (OutOfMemoryError e) {
|
||||
Log.e(TAG_UNITY, "Failed to serialize notification as Parcel", e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean serializeNotificationCustom(Notification notification, DataOutputStream out) {
|
||||
try {
|
||||
out.write(UNITY_MAGIC_NUMBER);
|
||||
out.writeInt(NOTIFICATION_SERIALIZATION_VERSION);
|
||||
|
||||
// serialize extras
|
||||
boolean showWhen = notification.extras.getBoolean(Notification.EXTRA_SHOW_WHEN, false);
|
||||
|
||||
out.writeInt(notification.extras.getInt(KEY_ID));
|
||||
serializeString(out, notification.extras.getString(Notification.EXTRA_TITLE));
|
||||
serializeString(out, notification.extras.getString(Notification.EXTRA_TEXT));
|
||||
serializeString(out, notification.extras.getString(KEY_SMALL_ICON));
|
||||
serializeString(out, notification.extras.getString(KEY_LARGE_ICON));
|
||||
out.writeLong(notification.extras.getLong(KEY_FIRE_TIME, -1));
|
||||
out.writeLong(notification.extras.getLong(KEY_REPEAT_INTERVAL, -1));
|
||||
serializeString(out, Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP ? null : notification.extras.getString(Notification.EXTRA_BIG_TEXT));
|
||||
out.writeBoolean(notification.extras.getBoolean(Notification.EXTRA_SHOW_CHRONOMETER, false));
|
||||
out.writeBoolean(showWhen);
|
||||
serializeString(out, notification.extras.getString(KEY_INTENT_DATA));
|
||||
out.writeBoolean(notification.extras.getBoolean(KEY_SHOW_IN_FOREGROUND, true));
|
||||
|
||||
String bigPicture = notification.extras.getString(KEY_BIG_PICTURE);
|
||||
serializeString(out, bigPicture);
|
||||
if (bigPicture != null && bigPicture.length() > 0) {
|
||||
// the following only need to be put in if big picture is there
|
||||
serializeString(out, notification.extras.getString(KEY_BIG_LARGE_ICON));
|
||||
serializeString(out, notification.extras.getString(KEY_BIG_CONTENT_TITLE));
|
||||
serializeString(out, notification.extras.getString(KEY_BIG_CONTENT_DESCRIPTION));
|
||||
serializeString(out, notification.extras.getString(KEY_BIG_SUMMARY_TEXT));
|
||||
out.writeBoolean(notification.extras.getBoolean(KEY_BIG_SHOW_WHEN_COLLAPSED, false));
|
||||
}
|
||||
|
||||
serializeString(out, Build.VERSION.SDK_INT < Build.VERSION_CODES.O ? null : notification.getChannelId());
|
||||
Integer color = UnityNotificationManager.getNotificationColor(notification);
|
||||
out.writeBoolean(color != null);
|
||||
if (color != null)
|
||||
out.writeInt(color);
|
||||
out.writeInt(notification.number);
|
||||
out.writeBoolean(0 != (notification.flags & Notification.FLAG_AUTO_CANCEL));
|
||||
serializeString(out, notification.getGroup());
|
||||
out.writeBoolean(0 != (notification.flags & Notification.FLAG_GROUP_SUMMARY));
|
||||
out.writeInt(UnityNotificationManager.getNotificationGroupAlertBehavior(notification));
|
||||
serializeString(out, notification.getSortKey());
|
||||
if (showWhen)
|
||||
out.writeLong(notification.when);
|
||||
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG_UNITY, "Failed to serialize notification", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void serializeString(DataOutputStream out, String s) throws IOException {
|
||||
if (s == null || s.length() == 0)
|
||||
out.writeInt(0);
|
||||
else {
|
||||
byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
|
||||
out.writeInt(bytes.length);
|
||||
out.write(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
static byte[] serializeParcelable(Parcelable obj) {
|
||||
try {
|
||||
Parcel p = Parcel.obtain();
|
||||
Bundle b = new Bundle();
|
||||
b.putParcelable("obj", obj);
|
||||
p.writeParcelable(b, 0);
|
||||
byte[] result = p.marshall();
|
||||
p.recycle();
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG_UNITY, "Failed to serialize Parcelable", e);
|
||||
} catch (OutOfMemoryError e) {
|
||||
Log.e(TAG_UNITY, "Failed to serialize Parcelable", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static Object deserializeNotification(Context context, SharedPreferences prefs) {
|
||||
String serializedIntentData = prefs.getString(SAVED_NOTIFICATION_PRIMARY_KEY, "");
|
||||
if (null == serializedIntentData || serializedIntentData.length() <= 0)
|
||||
return null;
|
||||
byte[] bytes = Base64.decode(serializedIntentData, 0);
|
||||
Object notification = deserializeNotification(context, bytes);
|
||||
if (notification != null)
|
||||
return notification;
|
||||
serializedIntentData = prefs.getString(SAVED_NOTIFICATION_FALLBACK_KEY, "");
|
||||
if (null == serializedIntentData || serializedIntentData.length() <= 0)
|
||||
return null;
|
||||
bytes = Base64.decode(serializedIntentData, 0);
|
||||
return deserializeNotification(context, bytes);
|
||||
}
|
||||
|
||||
/* See serialization method above for explaination of fallbacks.
|
||||
This one matches it with one additional fallback: support for "old" bundle serialization.
|
||||
*/
|
||||
private static Object deserializeNotification(Context context, byte[] bytes) {
|
||||
ByteArrayInputStream data = new ByteArrayInputStream(bytes);
|
||||
DataInputStream in = new DataInputStream(data);
|
||||
Notification notification = deserializeNotificationParcelable(in);
|
||||
if (notification != null)
|
||||
return notification;
|
||||
data.reset();
|
||||
Notification.Builder builder = deserializeNotificationCustom(context, in);
|
||||
if (builder == null) {
|
||||
builder = deserializedFromOldIntent(context, bytes);
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static boolean readAndCheckMagicNumber(DataInputStream in, byte[] magic) {
|
||||
try {
|
||||
boolean magicNumberMatch = true;
|
||||
for (int i = 0; i < magic.length; ++i) {
|
||||
byte b = in.readByte();
|
||||
if (b != magic[i]) {
|
||||
magicNumberMatch = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return magicNumberMatch;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static Notification deserializeNotificationParcelable(DataInputStream in) {
|
||||
try {
|
||||
if (!readAndCheckMagicNumber(in, UNITY_MAGIC_NUMBER_PARCELLED))
|
||||
return null;
|
||||
int version = in.readInt();
|
||||
if (version < 0 || version > INTENT_SERIALIZATION_VERSION)
|
||||
return null;
|
||||
Intent intent = deserializeParcelable(in);
|
||||
Notification notification = intent.getParcelableExtra(KEY_NOTIFICATION);
|
||||
return notification;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG_UNITY, "Failed to deserialize notification intent", e);
|
||||
} catch (OutOfMemoryError e) {
|
||||
Log.e(TAG_UNITY, "Failed to deserialize notification intent", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Notification.Builder deserializeNotificationCustom(Context context, DataInputStream in) {
|
||||
try {
|
||||
if (!readAndCheckMagicNumber(in, UNITY_MAGIC_NUMBER))
|
||||
return null;
|
||||
int version = in.readInt();
|
||||
if (version < 0 || version > NOTIFICATION_SERIALIZATION_VERSION)
|
||||
return null;
|
||||
|
||||
// deserialize extras
|
||||
int id = 0;
|
||||
String title, text, smallIcon, largeIcon, bigText, intentData;
|
||||
long fireTime, repeatInterval;
|
||||
boolean usesStopWatch, showWhen, showInForeground = true;
|
||||
Bundle extras = null;
|
||||
String bigPicture = null, bigLargeIcon = null, bigContentTitle = null, bigSummary = null, bigContentDesc = null;
|
||||
boolean bigShowWhenCollapsed = false;
|
||||
if (version < 2) {
|
||||
// no longer serialized since v2
|
||||
extras = deserializeParcelable(in);
|
||||
}
|
||||
|
||||
// before v2 it was extras or variables, since 2 always variables
|
||||
if (extras == null) {
|
||||
// extras serialized manually
|
||||
id = in.readInt();
|
||||
title = deserializeString(in);
|
||||
text = deserializeString(in);
|
||||
smallIcon = deserializeString(in);
|
||||
largeIcon = deserializeString(in);
|
||||
fireTime = in.readLong();
|
||||
repeatInterval = in.readLong();
|
||||
bigText = deserializeString(in);
|
||||
usesStopWatch = in.readBoolean();
|
||||
showWhen = in.readBoolean();
|
||||
intentData = deserializeString(in);
|
||||
if (version > 0)
|
||||
showInForeground = in.readBoolean();
|
||||
|
||||
if (version >= 3) {
|
||||
bigPicture = deserializeString(in);
|
||||
if (bigPicture != null && bigPicture.length() > 0) {
|
||||
// the following only need to be put in if big picture is there
|
||||
bigLargeIcon = deserializeString(in);
|
||||
bigContentTitle = deserializeString(in);
|
||||
bigContentDesc = deserializeString(in);
|
||||
bigSummary = deserializeString(in);
|
||||
bigShowWhenCollapsed = in.readBoolean();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
title = extras.getString(Notification.EXTRA_TITLE);
|
||||
text = extras.getString(Notification.EXTRA_TEXT);
|
||||
smallIcon = extras.getString(KEY_SMALL_ICON);
|
||||
largeIcon = extras.getString(KEY_LARGE_ICON);
|
||||
fireTime = extras.getLong(KEY_FIRE_TIME, -1);
|
||||
repeatInterval = extras.getLong(KEY_REPEAT_INTERVAL, -1);
|
||||
bigText = Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP ? null : extras.getString(Notification.EXTRA_BIG_TEXT);
|
||||
usesStopWatch = extras.getBoolean(Notification.EXTRA_SHOW_CHRONOMETER, false);
|
||||
showWhen = extras.getBoolean(Notification.EXTRA_SHOW_WHEN, false);
|
||||
intentData = extras.getString(KEY_INTENT_DATA);
|
||||
}
|
||||
|
||||
String channelId = deserializeString(in);
|
||||
boolean haveColor = in.readBoolean();
|
||||
int color = 0;
|
||||
if (haveColor)
|
||||
color = in.readInt();
|
||||
int number = in.readInt();
|
||||
boolean shouldAutoCancel = in.readBoolean();
|
||||
String group = deserializeString(in);
|
||||
boolean groupSummary = in.readBoolean();
|
||||
int groupAlertBehavior = in.readInt();
|
||||
String sortKey = deserializeString(in);
|
||||
long when = showWhen ? in.readLong() : 0;
|
||||
|
||||
UnityNotificationManager manager = UnityNotificationManager.getNotificationManagerImpl(context);
|
||||
Notification.Builder builder = manager.createNotificationBuilder(channelId);
|
||||
if (extras != null)
|
||||
builder.setExtras(extras);
|
||||
else {
|
||||
builder.getExtras().putInt(KEY_ID, id);
|
||||
UnityNotificationManager.setNotificationIcon(builder, KEY_SMALL_ICON, smallIcon);
|
||||
UnityNotificationManager.setNotificationIcon(builder, KEY_LARGE_ICON, largeIcon);
|
||||
if (fireTime != -1)
|
||||
builder.getExtras().putLong(KEY_FIRE_TIME, fireTime);
|
||||
if (repeatInterval != -1)
|
||||
builder.getExtras().putLong(KEY_REPEAT_INTERVAL, repeatInterval);
|
||||
if (intentData != null)
|
||||
builder.getExtras().putString(KEY_INTENT_DATA, intentData);
|
||||
builder.getExtras().putBoolean(KEY_SHOW_IN_FOREGROUND, showInForeground);
|
||||
}
|
||||
if (title != null)
|
||||
builder.setContentTitle(title);
|
||||
if (text != null)
|
||||
builder.setContentText(text);
|
||||
if (bigText != null)
|
||||
builder.setStyle(new Notification.BigTextStyle().bigText(bigText));
|
||||
else if (bigPicture != null)
|
||||
manager.setupBigPictureStyle(builder, bigLargeIcon, bigPicture, bigContentTitle, bigContentDesc, bigSummary, bigShowWhenCollapsed);
|
||||
if (haveColor)
|
||||
UnityNotificationManager.setNotificationColor(builder, color);
|
||||
if (number >= 0)
|
||||
builder.setNumber(number);
|
||||
builder.setAutoCancel(shouldAutoCancel);
|
||||
UnityNotificationManager.setNotificationUsesChronometer(builder, usesStopWatch);
|
||||
if (group != null && group.length() > 0)
|
||||
builder.setGroup(group);
|
||||
builder.setGroupSummary(groupSummary);
|
||||
UnityNotificationManager.setNotificationGroupAlertBehavior(builder, groupAlertBehavior);
|
||||
if (sortKey != null && sortKey.length() > 0)
|
||||
builder.setSortKey(sortKey);
|
||||
if (showWhen) {
|
||||
builder.setShowWhen(true);
|
||||
builder.setWhen(when);
|
||||
}
|
||||
|
||||
return builder;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG_UNITY, "Failed to deserialize notification", e);
|
||||
} catch (OutOfMemoryError e) {
|
||||
Log.e(TAG_UNITY, "Failed to deserialize notification", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Notification.Builder deserializedFromOldIntent(Context context, byte[] bytes) {
|
||||
try {
|
||||
Parcel p = Parcel.obtain();
|
||||
p.unmarshall(bytes, 0, bytes.length);
|
||||
p.setDataPosition(0);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.readFromParcel(p);
|
||||
|
||||
int id = bundle.getInt(KEY_ID, -1);
|
||||
String channelId = bundle.getString("channelID");
|
||||
String textTitle = bundle.getString("textTitle");
|
||||
String textContent = bundle.getString("textContent");
|
||||
String smallIcon = bundle.getString("smallIconStr");
|
||||
boolean autoCancel = bundle.getBoolean("autoCancel", false);
|
||||
boolean usesChronometer = bundle.getBoolean("usesChronometer", false);
|
||||
long fireTime = bundle.getLong(KEY_FIRE_TIME, -1);
|
||||
long repeatInterval = bundle.getLong(KEY_REPEAT_INTERVAL, -1);
|
||||
String largeIcon = bundle.getString("largeIconStr");
|
||||
int style = bundle.getInt("style", -1);
|
||||
int color = bundle.getInt("color", 0);
|
||||
int number = bundle.getInt("number", 0);
|
||||
String intentData = bundle.getString(KEY_INTENT_DATA);
|
||||
String group = bundle.getString("group");
|
||||
boolean groupSummary = bundle.getBoolean("groupSummary", false);
|
||||
String sortKey = bundle.getString("sortKey");
|
||||
int groupAlertBehaviour = bundle.getInt("groupAlertBehaviour", -1);
|
||||
boolean showTimestamp = bundle.getBoolean("showTimestamp", false);
|
||||
|
||||
Notification.Builder builder = UnityNotificationManager.getNotificationManagerImpl(context).createNotificationBuilder(channelId);
|
||||
builder.getExtras().putInt(KEY_ID, id);
|
||||
builder.setContentTitle(textTitle);
|
||||
builder.setContentText(textContent);
|
||||
UnityNotificationManager.setNotificationIcon(builder, KEY_SMALL_ICON, smallIcon);
|
||||
builder.setAutoCancel(autoCancel);
|
||||
builder.setUsesChronometer(usesChronometer);
|
||||
builder.getExtras().putLong(KEY_FIRE_TIME, fireTime);
|
||||
builder.getExtras().putLong(KEY_REPEAT_INTERVAL, repeatInterval);
|
||||
UnityNotificationManager.setNotificationIcon(builder, KEY_LARGE_ICON, largeIcon);
|
||||
if (style == 2)
|
||||
builder.setStyle(new Notification.BigTextStyle().bigText(textContent));
|
||||
if (color != 0)
|
||||
UnityNotificationManager.setNotificationColor(builder, color);
|
||||
if (number >= 0)
|
||||
builder.setNumber(number);
|
||||
if (intentData != null)
|
||||
builder.getExtras().putString(KEY_INTENT_DATA, intentData);
|
||||
if (null != group && group.length() > 0)
|
||||
builder.setGroup(group);
|
||||
builder.setGroupSummary(groupSummary);
|
||||
if (null != sortKey && sortKey.length() > 0)
|
||||
builder.setSortKey(sortKey);
|
||||
UnityNotificationManager.setNotificationGroupAlertBehavior(builder, groupAlertBehaviour);
|
||||
builder.setShowWhen(showTimestamp);
|
||||
return builder;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG_UNITY, "Failed to deserialize old style notification", e);
|
||||
} catch (OutOfMemoryError e) {
|
||||
Log.e(TAG_UNITY, "Failed to deserialize old style notification", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String deserializeString(DataInputStream in) throws IOException {
|
||||
int length = in.readInt();
|
||||
if (length <= 0)
|
||||
return null;
|
||||
byte[] bytes = new byte[length];
|
||||
int didRead = in.read(bytes);
|
||||
if (didRead != bytes.length)
|
||||
throw new IOException("Insufficient amount of bytes read");
|
||||
return new String(bytes, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
private static <T extends Parcelable> T deserializeParcelable(DataInputStream in) throws IOException {
|
||||
int length = in.readInt();
|
||||
if (length <= 0)
|
||||
return null;
|
||||
byte[] bytes = new byte[length];
|
||||
int didRead = in.read(bytes);
|
||||
if (didRead != bytes.length)
|
||||
throw new IOException("Insufficient amount of bytes read");
|
||||
|
||||
try {
|
||||
Parcel p = Parcel.obtain();
|
||||
p.unmarshall(bytes, 0, bytes.length);
|
||||
p.setDataPosition(0);
|
||||
Bundle b = p.readParcelable(UnityNotificationUtilities.class.getClassLoader());
|
||||
p.recycle();
|
||||
if (b != null) {
|
||||
return b.getParcelable("obj");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG_UNITY, "Failed to deserialize parcelable", e);
|
||||
} catch (OutOfMemoryError e) {
|
||||
Log.e(TAG_UNITY, "Failed to deserialize parcelable", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Returns Activity class to be opened when notification is tapped
|
||||
// Search is done in this order:
|
||||
// * class specified in meta-data key custom_notification_android_activity
|
||||
// * the only enabled activity with name ending in either .UnityPlayerActivity or .UnityPlayerGameActivity
|
||||
// * the only enabled activity in the package
|
||||
protected static Class<?> getOpenAppActivity(Context context) {
|
||||
try {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
ApplicationInfo ai = pm.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
|
||||
Bundle bundle = ai.metaData;
|
||||
|
||||
if (bundle.containsKey("custom_notification_android_activity")) {
|
||||
try {
|
||||
return Class.forName(bundle.getString("custom_notification_android_activity"));
|
||||
} catch (ClassNotFoundException e) {
|
||||
Log.e(TAG_UNITY, "Specified activity class for notifications not found: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
Log.w(TAG_UNITY, "No custom_notification_android_activity found, attempting to find app activity class");
|
||||
|
||||
ActivityInfo[] aInfo = pm.getPackageInfo(context.getPackageName(), PackageManager.GET_ACTIVITIES).activities;
|
||||
if (aInfo == null) {
|
||||
Log.e(TAG_UNITY, "Could not get package activities");
|
||||
return null;
|
||||
}
|
||||
|
||||
String activityClassName = null;
|
||||
boolean activityIsUnity = false, activityConflict = false;
|
||||
for (ActivityInfo info : aInfo) {
|
||||
// activity alias not supported
|
||||
if (!info.enabled || info.targetActivity != null)
|
||||
continue;
|
||||
|
||||
boolean candidateIsUnity = isUnityActivity(info.name);
|
||||
if (activityClassName == null) {
|
||||
activityClassName = info.name;
|
||||
activityIsUnity = candidateIsUnity;
|
||||
continue;
|
||||
}
|
||||
|
||||
// two Unity activities is a hard conflict
|
||||
// two non-Unity activities is a conflict unless we find a Unity activity later on
|
||||
if (activityIsUnity == candidateIsUnity) {
|
||||
activityConflict = true;
|
||||
if (activityIsUnity && candidateIsUnity)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (candidateIsUnity) {
|
||||
activityClassName = info.name;
|
||||
activityIsUnity = candidateIsUnity;
|
||||
activityConflict = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (activityConflict) {
|
||||
Log.e(TAG_UNITY, "Multiple choices for activity for notifications, set activity explicitly in Notification Settings");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (activityClassName == null) {
|
||||
Log.e(TAG_UNITY, "Activity class for notifications not found");
|
||||
return null;
|
||||
}
|
||||
|
||||
return Class.forName(activityClassName);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ClassNotFoundException e) {
|
||||
Log.e(TAG_UNITY, "Failed to find activity class: " + e.getMessage());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isUnityActivity(String name) {
|
||||
return name.endsWith(".UnityPlayerActivity") || name.endsWith(".UnityPlayerGameActivity");
|
||||
}
|
||||
|
||||
protected static Notification.Builder recoverBuilder(Context context, Notification notification) {
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
Notification.Builder builder = Notification.Builder.recoverBuilder(context, notification);
|
||||
// extras not recovered, transfer manually
|
||||
builder.setExtras(notification.extras);
|
||||
return builder;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG_UNITY, "Failed to recover builder for notification!", e);
|
||||
} catch (OutOfMemoryError e) {
|
||||
Log.e(TAG_UNITY, "Failed to recover builder for notification!", e);
|
||||
}
|
||||
|
||||
return recoverBuilderCustom(context, notification);
|
||||
}
|
||||
|
||||
private static Notification.Builder recoverBuilderCustom(Context context, Notification notification) {
|
||||
String channelID = notification.extras.getString(KEY_CHANNEL_ID);
|
||||
Notification.Builder builder = UnityNotificationManager.getNotificationManagerImpl(context).createNotificationBuilder(channelID);
|
||||
UnityNotificationManager.setNotificationIcon(builder, KEY_SMALL_ICON, notification.extras.getString(KEY_SMALL_ICON));
|
||||
String largeIcon = notification.extras.getString(KEY_LARGE_ICON);
|
||||
if (largeIcon != null && !largeIcon.isEmpty())
|
||||
UnityNotificationManager.setNotificationIcon(builder, KEY_LARGE_ICON, largeIcon);
|
||||
builder.setContentTitle(notification.extras.getString(Notification.EXTRA_TITLE));
|
||||
builder.setContentText(notification.extras.getString(Notification.EXTRA_TEXT));
|
||||
builder.setAutoCancel(0 != (notification.flags & Notification.FLAG_AUTO_CANCEL));
|
||||
if (notification.number >= 0)
|
||||
builder.setNumber(notification.number);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
String bigText = notification.extras.getString(Notification.EXTRA_BIG_TEXT);
|
||||
if (bigText != null)
|
||||
builder.setStyle(new Notification.BigTextStyle().bigText(bigText));
|
||||
}
|
||||
|
||||
builder.setWhen(notification.when);
|
||||
String group = notification.getGroup();
|
||||
if (group != null && !group.isEmpty())
|
||||
builder.setGroup(group);
|
||||
builder.setGroupSummary(0 != (notification.flags & Notification.FLAG_GROUP_SUMMARY));
|
||||
String sortKey = notification.getSortKey();
|
||||
if (sortKey != null && !sortKey.isEmpty())
|
||||
builder.setSortKey(sortKey);
|
||||
builder.setShowWhen(notification.extras.getBoolean(Notification.EXTRA_SHOW_WHEN, false));
|
||||
Integer color = UnityNotificationManager.getNotificationColor(notification);
|
||||
if (color != null)
|
||||
UnityNotificationManager.setNotificationColor(builder, color);
|
||||
UnityNotificationManager.setNotificationUsesChronometer(builder, notification.extras.getBoolean(Notification.EXTRA_SHOW_CHRONOMETER, false));
|
||||
UnityNotificationManager.setNotificationGroupAlertBehavior(builder, UnityNotificationManager.getNotificationGroupAlertBehavior(notification));
|
||||
|
||||
builder.getExtras().putInt(KEY_ID, notification.extras.getInt(KEY_ID, 0));
|
||||
builder.getExtras().putLong(KEY_REPEAT_INTERVAL, notification.extras.getLong(KEY_REPEAT_INTERVAL, 0));
|
||||
builder.getExtras().putLong(KEY_FIRE_TIME, notification.extras.getLong(KEY_FIRE_TIME, 0));
|
||||
String intentData = notification.extras.getString(KEY_INTENT_DATA);
|
||||
if (intentData != null && !intentData.isEmpty())
|
||||
builder.getExtras().putString(KEY_INTENT_DATA, intentData);
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
BIN
BFVersions/android/keystore/dz_keystore.jks
Executable file
BIN
BFVersions/android/keystore/dz_keystore.jks
Executable file
Binary file not shown.
1
BFVersions/android/keystore/dz_keystore.txt
Executable file
1
BFVersions/android/keystore/dz_keystore.txt
Executable file
@ -0,0 +1 @@
|
||||
juzu_dz0!
|
||||
Loading…
x
Reference in New Issue
Block a user