diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 97f5bf0..153740a 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -17,8 +17,8 @@ android { applicationId = "com.sunny.tools.app.soft" minSdk = 23 targetSdk = 34 - versionCode = 2 - versionName = "1.0.1" + versionCode = 3 + versionName = "1.0.2" setProperty("archivesBaseName", "Custom Keyboard_V" + versionName + "(${versionCode})_$timestamp") testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } @@ -65,6 +65,9 @@ dependencies { implementation("com.google.firebase:firebase-analytics-ktx") implementation("com.google.firebase:firebase-crashlytics-ktx") + //-----------------------------Unity Ads SDK + implementation("com.unity3d.ads:unity-ads:4.9.1") + } \ No newline at end of file diff --git a/app/google-services.json b/app/google-services.json index 41473f9..6b54dbe 100644 --- a/app/google-services.json +++ b/app/google-services.json @@ -1,13 +1,13 @@ { "project_info": { - "project_number": "361631722137", - "project_id": "custom-keyboardtheme-3768d", - "storage_bucket": "custom-keyboardtheme-3768d.appspot.com" + "project_number": "894189375933", + "project_id": "custom-keyboard-theme", + "storage_bucket": "custom-keyboard-theme.appspot.com" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:361631722137:android:fb69ca1b27d2564b07a608", + "mobilesdk_app_id": "1:894189375933:android:0409bb4d16339f3a5082d4", "android_client_info": { "package_name": "com.sunny.tools.app.soft" } @@ -15,7 +15,7 @@ "oauth_client": [], "api_key": [ { - "current_key": "AIzaSyAqGYvcuwa6SIijZVuJrvsfS221d5G2oJQ" + "current_key": "AIzaSyBjQotqK18eK8QAu9g-GWSgmuWczahMlDY" } ], "services": { diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 3b47044..f99985f 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -20,4 +20,40 @@ # hide the original source file name. #-renamesourcefileattribute SourceFile -keep class com.sunny.app.soft.timberkeyboardnew.data.entity.CategoryEntity { *; } - -keep class com.sunny.app.soft.timberkeyboardnew.data.entity.BackgroundEntity { *; } \ No newline at end of file + -keep class com.sunny.app.soft.timberkeyboardnew.data.entity.BackgroundEntity { *; } + + + #=======================================UNity SDK + # Keep filenames and line numbers for stack traces + -keepattributes SourceFile,LineNumberTable + + # Keep JavascriptInterface for WebView bridge + -keepattributes JavascriptInterface + + + -keep class android.webkit.JavascriptInterface { + *; + } + + # Keep all classes in Unity Ads package + + -keep class com.unity3d.ads.** { + *; + } + + # Keep all classes in Unity Services package + -keep class com.unity3d.services.** { + *; + } + + -keep class com.google.android.gms.ads.initialization.** { + *; + } + + -keep class com.google.android.gms.ads.MobileAds { + *; + } + + -dontwarn com.google.ads.mediation.admob.* + -dontwarn com.google.android.gms.ads.** + #==================================UNity SDK \ No newline at end of file diff --git a/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/App.kt b/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/App.kt index 47488a3..e66c086 100644 --- a/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/App.kt +++ b/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/App.kt @@ -2,28 +2,52 @@ package com.sunny.app.soft.timberkeyboardnew import android.app.Application import android.content.Context +import android.util.Log +import com.sunny.app.soft.timberkeyboardnew.unityad.UnityAdManager +import com.unity3d.ads.IUnityAdsInitializationListener +import com.unity3d.ads.UnityAds class App : Application() { companion object { lateinit var appContext: Context - const val SDK = - "Gh30bAynDQKKuCplTJzpa0Up7GT11xtMxoe5SGqIJaNG2a8wTWTHNvHo_CJaHm416PdQDk5mVAtfMdT9OL_8zy" + const val AD_INIT = "on_action" - var initOK = false + + + + var SDKOK = false + + + } override fun onCreate() { super.onCreate() appContext = this - initMAX() + initUNity() } - private fun initMAX() { + private fun initUNity() { + Log.d(UnityAdManager.TAG, "----------------------application init") + UnityAds.initialize(this, UnityAdManager.unityGameID, UnityAdManager.testMode, object : IUnityAdsInitializationListener { + override fun onInitializationComplete() { + SDKOK = true + UnityAdManager.loadAllAdNew() + } + + override fun onInitializationFailed( + error: UnityAds.UnityAdsInitializationError?, + message: String? + ) { + SDKOK = false + } + + }); } } \ No newline at end of file diff --git a/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/ui/activity/DownloadActivity.kt b/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/ui/activity/DownloadActivity.kt index 1721597..e175585 100644 --- a/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/ui/activity/DownloadActivity.kt +++ b/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/ui/activity/DownloadActivity.kt @@ -21,6 +21,8 @@ import com.sunny.app.soft.timberkeyboardnew.tools.AppConstant import com.sunny.app.soft.timberkeyboardnew.tools.KeyboardManager import com.sunny.app.soft.timberkeyboardnew.tools.ZipTools import com.sunny.app.soft.timberkeyboardnew.ui.listener.ApplyListener +import com.sunny.app.soft.timberkeyboardnew.unityad.UnityAdManager +import com.sunny.app.soft.timberkeyboardnew.unityad.onShowCallBack import java.io.ByteArrayOutputStream import java.io.File import java.io.FileInputStream @@ -57,7 +59,8 @@ class DownloadActivity : AppConstant.SHARE_NAME, Context.MODE_PRIVATE ) - val path = sp.getString("${AppConstant.KEY_CUR_Path_img}_${backgroundEntity.skinNumber}", "") + val path = + sp.getString("${AppConstant.KEY_CUR_Path_img}_${backgroundEntity.skinNumber}", "") val file = File(path) if (file.exists()) { val bitmapDrawable = @@ -89,8 +92,28 @@ class DownloadActivity : } private fun onShowAd() { - startSetSkin() + val readyUnitAd = UnityAdManager.getReadyUnitAd() + if (readyUnitAd == null) { + startSetSkin() + } else { + UnityAdManager.showUnityAd(this, readyUnitAd, object : onShowCallBack { + override fun onShowFail() { + startSetSkin() + } + + override fun onShowClose() { + startSetSkin() + } + + override fun onShowSuccess() { + + } + + }) + } + } + private fun initButton() { binding.downloadBack.setOnClickListener(this) binding.btnDownload.setOnClickListener(this) @@ -179,7 +202,7 @@ class DownloadActivity : } - private fun startSetSkin(){ + private fun startSetSkin() { binding.downloadProgress.visibility = View.VISIBLE val zipFile = File(unzipPath) diff --git a/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/ui/activity/LoadingActivity.kt b/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/ui/activity/LoadingActivity.kt index badddea..e22e33c 100644 --- a/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/ui/activity/LoadingActivity.kt +++ b/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/ui/activity/LoadingActivity.kt @@ -2,20 +2,20 @@ package com.sunny.app.soft.timberkeyboardnew.ui.activity import android.content.Intent import android.os.CountDownTimer +import android.util.Log import android.view.View -import com.applovin.mediation.ads.MaxInterstitialAd import com.sunny.app.soft.timberkeyboardnew.databinding.ActivityLoadingBinding -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers +import com.sunny.app.soft.timberkeyboardnew.unityad.UnityAdManager +import com.sunny.app.soft.timberkeyboardnew.unityad.onShowCallBack class LoadingActivity : BaseActivity() { private lateinit var binding: ActivityLoadingBinding - private val coroutineScope = CoroutineScope(Dispatchers.Main) - private val countTime: Long = 12000 - private lateinit var lists: List + private lateinit var timer: CountDownTimer + private var hasShow = false + override fun setRootView(): View { binding = ActivityLoadingBinding.inflate(layoutInflater) @@ -26,26 +26,67 @@ class LoadingActivity : BaseActivity() { super.onDestroy() timer.cancel() } + override fun initView() { super.initView() - - timer = object :CountDownTimer(10000,200){ + timer = object : CountDownTimer(11000, 100) { override fun onTick(millisUntilFinished: Long) { + Log.d(UnityAdManager.TAG, "----------------------onTick =$millisUntilFinished") + if (hasShow) return + show(false) { + + intoMainActivity() + + } + } override fun onFinish() { - intoMainActivity() + Log.d(UnityAdManager.TAG, "----------------------onFinish =$hasShow") + if (!hasShow) { + show(true) { + intoMainActivity() + } + } + } } - - + timer.start() } + private fun show(isFinish: Boolean, action: (showSuccess: Boolean) -> Unit) { + val readyUnitAd = UnityAdManager.getReadyUnitAd() + if (readyUnitAd != null) { + hasShow = true + UnityAdManager.showUnityAd(this@LoadingActivity, readyUnitAd, object : + onShowCallBack { + override fun onShowFail() { + action.invoke(false) + } + + override fun onShowClose() { + intoMainActivity() + action.invoke(true) + } + + override fun onShowSuccess() { + + } + + }) + } else { + if (isFinish) { + action.invoke(false) + } + + } + } + private fun intoMainActivity() { val intent = Intent(this, MainActivity::class.java) startActivity(intent) diff --git a/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/ui/fragment/HomeFragment.kt b/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/ui/fragment/HomeFragment.kt index cb2b0e5..900d39a 100644 --- a/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/ui/fragment/HomeFragment.kt +++ b/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/ui/fragment/HomeFragment.kt @@ -13,13 +13,15 @@ import com.sunny.app.soft.timberkeyboardnew.tools.AppConstant import com.sunny.app.soft.timberkeyboardnew.ui.activity.SelectActivity import com.sunny.app.soft.timberkeyboardnew.ui.adapter.HomeViewAdapter import com.sunny.app.soft.timberkeyboardnew.ui.listener.OnItemClickListener +import com.sunny.app.soft.timberkeyboardnew.unityad.UnityAdManager +import com.sunny.app.soft.timberkeyboardnew.unityad.onShowCallBack class HomeFragment : BaseFragment() { private lateinit var binding: FragmentHomeBinding - private lateinit var data:CategoryEntity + private lateinit var data: CategoryEntity override fun setRootView(): View { binding = FragmentHomeBinding.inflate(layoutInflater) return binding.root @@ -40,19 +42,20 @@ class HomeFragment : layoutManager = LinearLayoutManager(requireContext()).apply { orientation = LinearLayoutManager.VERTICAL } - adapter = HomeViewAdapter(requireContext(), categoryEntityList, object : OnItemClickListener { - override fun onItemClick(position: Int, categoryEntity: CategoryEntity) { - data = categoryEntity - onShowAd() + adapter = + HomeViewAdapter(requireContext(), categoryEntityList, object : OnItemClickListener { + override fun onItemClick(position: Int, categoryEntity: CategoryEntity) { + data = categoryEntity + onShowAd() - } - }) + } + }) } } - private fun enterList(){ + private fun enterList() { val intent = Intent(requireContext(), SelectActivity::class.java) intent.putExtra(AppConstant.KEY_EXTRA, data) startActivity(intent) @@ -60,7 +63,28 @@ class HomeFragment : fun onShowAd() { - enterList() + + val readyUnitAd = UnityAdManager.getReadyUnitAd() + if (readyUnitAd == null) { + enterList() + } else { + UnityAdManager.showUnityAd(requireActivity(), readyUnitAd, object : onShowCallBack { + override fun onShowFail() { + enterList() + } + + override fun onShowClose() { + enterList() + } + + override fun onShowSuccess() { + + } + + }) + } + + } private fun initTitle() { diff --git a/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/unityad/UnityAdManager.java b/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/unityad/UnityAdManager.java new file mode 100644 index 0000000..d2cb6aa --- /dev/null +++ b/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/unityad/UnityAdManager.java @@ -0,0 +1,191 @@ +package com.sunny.app.soft.timberkeyboardnew.unityad; + +import android.app.Activity; +import android.content.Intent; +import android.util.Log; + +import androidx.localbroadcastmanager.content.LocalBroadcastManager; + +import com.sunny.app.soft.timberkeyboardnew.App; +import com.unity3d.ads.IUnityAdsLoadListener; +import com.unity3d.ads.IUnityAdsShowListener; +import com.unity3d.ads.UnityAds; +import com.unity3d.ads.UnityAdsShowOptions; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Objects; + +public class UnityAdManager { + public static String unityGameID = "5649487"; + + public static Boolean testMode = false; + + public static String unitAd1 = "Custom_Keyboard_ad_unity_inst_open"; + public static String unitAd2 = "Custom_Keyboard_ad_unity_inst_set"; + public static String unitAd3 = "Custom_Keyboard_ad_unity_inst_theme"; + + public static Boolean AD1Ready = false; + public static Boolean AD2Ready = false; + public static Boolean AD3Ready = false; + + public static String ACTION = "----"; + + + public static String TAG = "-----------------tt"; + + public static String KEY_UNIT = "unitAD"; + + public static String KEY_OK = "unit_ready"; + + + public static void loadAllAd() { + loadAd(unitAd1, new onLoadCallBack() { + @Override + public void onIsLoad(boolean loaded) { + Log.d(TAG, "-------unitAd1" + loaded); + + Intent intent = new Intent(ACTION); + intent.putExtra(KEY_UNIT, unitAd1); + intent.putExtra(KEY_OK, loaded); + LocalBroadcastManager.getInstance(App.appContext).sendBroadcast(intent); + + + } + }); + loadAd(unitAd2, new onLoadCallBack() { + @Override + public void onIsLoad(boolean loaded) { + + Intent intent = new Intent(ACTION); + intent.putExtra(KEY_UNIT, unitAd2); + intent.putExtra(KEY_OK, loaded); + LocalBroadcastManager.getInstance(App.appContext).sendBroadcast(intent); + + Log.d("------------------tt", "-------unitAd2" + loaded); + } + }); + loadAd(unitAd3, new onLoadCallBack() { + @Override + public void onIsLoad(boolean loaded) { + + Intent intent = new Intent(ACTION); + intent.putExtra(KEY_UNIT, unitAd3); + intent.putExtra(KEY_OK, loaded); + LocalBroadcastManager.getInstance(App.appContext).sendBroadcast(intent); + + Log.d(TAG, "-------unitAd3" + loaded); + } + }); + } + + public static void loadAllAdNew() { + if (!AD1Ready) + loadAd(unitAd1); + if (!AD2Ready) + loadAd(unitAd2); + if (!AD3Ready) + loadAd(unitAd3); + } + + public static String getReadyUnitAd() { + ArrayList unitList = new ArrayList<>(); + unitList.add(unitAd1); + unitList.add(unitAd2); + unitList.add(unitAd3); + Collections.shuffle(unitList); + + for (String unit : unitList) { + if (Objects.equals(unit, unitAd1)) { + if (AD1Ready) { + return unit; + } + } else if (Objects.equals(unit, unitAd2)) { + if (AD2Ready) { + return unit; + } + } else if (Objects.equals(unit, unitAd3)) { + if (AD3Ready) { + return unit; + } + } + } + return null; + } + + public static void loadAd(String adUnitId) { + UnityAds.load(adUnitId, new IUnityAdsLoadListener() { + @Override + public void onUnityAdsAdLoaded(String placementId) { + Log.d(TAG, "------loaded-unit" + placementId); + if (Objects.equals(placementId, unitAd1)) { + AD1Ready = true; + } else if (Objects.equals(placementId, unitAd2)) { + AD2Ready = true; + } else if (Objects.equals(placementId, unitAd3)) { + AD3Ready = true; + } + + } + + @Override + public void onUnityAdsFailedToLoad(String placementId, UnityAds.UnityAdsLoadError error, String message) { + Log.d(TAG, "------load fail-unit" + placementId + "-----" + message); + } + }); + + } + + private static void loadAd(String adUnitId, onLoadCallBack callBack) { + UnityAds.load(adUnitId, new IUnityAdsLoadListener() { + @Override + public void onUnityAdsAdLoaded(String placementId) { + Log.d(TAG, "------loaded-unit" + placementId); + callBack.onIsLoad(true); + } + + @Override + public void onUnityAdsFailedToLoad(String placementId, UnityAds.UnityAdsLoadError error, String message) { + Log.d(TAG, "------load fail-unit" + placementId + "-----" + message); + callBack.onIsLoad(false); + } + }); + + } + + public static void showUnityAd(Activity activity, String adUnitId, onShowCallBack onShowCallBack) { + UnityAds.show(activity, adUnitId, new UnityAdsShowOptions(), new IUnityAdsShowListener() { + @Override + public void onUnityAdsShowFailure(String placementId, UnityAds.UnityAdsShowError error, String message) { + onShowCallBack.onShowFail(); + Log.d(TAG, "--------onUnityAdsShowFailure---message=" + message); + } + + @Override + public void onUnityAdsShowStart(String placementId) { + Log.d(TAG, "--------onUnityAdsShowStart---=" + placementId); + if (Objects.equals(placementId, unitAd1)) { + AD1Ready = false; + } else if (Objects.equals(placementId, unitAd2)) { + AD2Ready = false; + } else if (Objects.equals(placementId, unitAd3)) { + AD3Ready = false; + } + onShowCallBack.onShowSuccess(); + + } + + @Override + public void onUnityAdsShowClick(String placementId) { + + } + + @Override + public void onUnityAdsShowComplete(String placementId, UnityAds.UnityAdsShowCompletionState state) { + onShowCallBack.onShowClose(); + Log.d(TAG, "--------onUnityAdsShowComplete---"); + loadAd(placementId); + } + }); + } +} diff --git a/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/unityad/onLoadCallBack.java b/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/unityad/onLoadCallBack.java new file mode 100644 index 0000000..3743a8f --- /dev/null +++ b/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/unityad/onLoadCallBack.java @@ -0,0 +1,6 @@ +package com.sunny.app.soft.timberkeyboardnew.unityad; + +public interface onLoadCallBack { + + void onIsLoad(boolean loaded); +} diff --git a/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/unityad/onShowCallBack.java b/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/unityad/onShowCallBack.java new file mode 100644 index 0000000..b6bb030 --- /dev/null +++ b/app/src/main/java/com/sunny/app/soft/timberkeyboardnew/unityad/onShowCallBack.java @@ -0,0 +1,8 @@ +package com.sunny.app.soft.timberkeyboardnew.unityad; + +public interface onShowCallBack { + + void onShowFail( ); + void onShowClose( ); + void onShowSuccess( ); +}