diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 5899e74..2b8c76b 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -5,6 +5,8 @@ plugins { id("com.android.application") id("org.jetbrains.kotlin.android") kotlin("kapt") + id("com.google.gms.google-services") + id("com.google.firebase.crashlytics") } val timestamp = SimpleDateFormat("MM_dd_HH_mm").format(Date()) @@ -13,11 +15,12 @@ android { compileSdk = 34 defaultConfig { + //com.wall.photography applicationId = "com.wall.photography" minSdk = 23 targetSdk = 34 - versionCode = 1 - versionName = "1.0.0" + versionCode = 2 + versionName = "1.0.1" setProperty("archivesBaseName", "Photography Wallpapers_V" + versionName + "(${versionCode})_$timestamp") testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } @@ -40,6 +43,7 @@ android { } buildFeatures { viewBinding = true + buildConfig = true } } @@ -69,4 +73,73 @@ dependencies { implementation("com.squareup.okhttp3:okhttp:4.11.0") + // Import the BoM for the Firebase platform + implementation(platform("com.google.firebase:firebase-bom:33.1.1")) + + // Add the dependencies for the Crashlytics and Analytics libraries + // When using the BoM, you don't specify versions in Firebase library dependencies + implementation("com.google.firebase:firebase-crashlytics") + implementation("com.google.firebase:firebase-analytics") + implementation("com.google.firebase:firebase-config") + + + //-----------------------------------------------TopOn(pangle、IronSource、mintegral、unityads、liftoff(vungle)、Bigo) + //Anythink (Necessary) + implementation("com.anythink.sdk:core-tpn:6.3.68") + implementation("com.anythink.sdk:nativead-tpn:6.3.68") + implementation("com.anythink.sdk:banner-tpn:6.3.68") + implementation("com.anythink.sdk:interstitial-tpn:6.3.68") + implementation("com.anythink.sdk:rewardedvideo-tpn:6.3.68") + implementation("com.anythink.sdk:splash-tpn:6.3.68") + + //Androidx (Necessary) + implementation("androidx.appcompat:appcompat:1.1.0") + implementation("androidx.browser:browser:1.4.0") + + //Vungle + implementation("com.anythink.sdk:adapter-tpn-vungle:6.3.68") + implementation("com.vungle:vungle-ads:7.3.2") + implementation("com.google.android.gms:play-services-basement:18.1.0") + implementation("com.google.android.gms:play-services-ads-identifier:18.0.1") + + //UnityAds + implementation("com.anythink.sdk:adapter-tpn-unityads:6.3.68") + implementation("com.unity3d.ads:unity-ads:4.9.3") + + //Ironsource + implementation("com.anythink.sdk:adapter-tpn-ironsource:6.3.68") + implementation("com.ironsource.sdk:mediationsdk:8.1.0") + implementation("com.google.android.gms:play-services-appset:16.0.2") + implementation("com.google.android.gms:play-services-ads-identifier:18.0.1") + implementation("com.google.android.gms:play-services-basement:18.1.0") + + //Bigo + implementation("com.anythink.sdk:adapter-tpn-bigo:6.3.68") + implementation("com.bigossp:bigo-ads:4.7.4") + + //Pangle + implementation("com.anythink.sdk:adapter-tpn-pangle-nonchina:6.3.68.1") + implementation( "com.pangle.global:ads-sdk:6.0.0.3") + implementation( "com.google.android.gms:play-services-ads-identifier:18.0.1") + + //Mintegral + implementation("com.anythink.sdk:adapter-tpn-mintegral-nonchina:6.3.68") + implementation("com.mbridge.msdk.oversea:reward:16.7.51") + implementation("com.mbridge.msdk.oversea:newinterstitial:16.7.51") + implementation("com.mbridge.msdk.oversea:mbnative:16.7.51") + implementation("com.mbridge.msdk.oversea:mbnativeadvanced:16.7.51") + implementation("com.mbridge.msdk.oversea:mbsplash:16.7.51") + implementation("com.mbridge.msdk.oversea:mbbanner:16.7.51") + implementation("com.mbridge.msdk.oversea:mbbid:16.7.51") + implementation("androidx.recyclerview:recyclerview:1.1.0") + + //Tramini + implementation("com.anythink.sdk:tramini-plugin-tpn:6.3.68") + + // Debugger UI Tools + implementation ("com.anythink.sdk:debugger-ui:1.0.7") + + //----------------------------------------------TopOn + + } \ No newline at end of file diff --git a/app/google-services.json b/app/google-services.json new file mode 100644 index 0000000..1747f52 --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,29 @@ +{ + "project_info": { + "project_number": "486670482005", + "project_id": "photography-wallpapers-236db", + "storage_bucket": "photography-wallpapers-236db.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:486670482005:android:1ac3da593dd52e1ee8f2dc", + "android_client_info": { + "package_name": "com.wall.photography" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyAaJZFpzRNLYYO3ffvpW70BUkzP6N_Zjps" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 81a7059..11ebed7 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -35,4 +35,91 @@ #-keepclassmembers class com.wall.photography.wallpaper.data { *; } -keep class com.wall.photography.wallpaper.room.MyDataBase { *; } --keep class com.wall.photography.wallpaper.room.BeanDao { *; } \ No newline at end of file +-keep class com.wall.photography.wallpaper.room.BeanDao { *; } + + +#---------------------------------------------Topon +# Vungle +-dontwarn com.vungle.ads.** +-keepclassmembers class com.vungle.ads.** { + *; +} + +# Google +-keep class com.google.android.gms.** { *; } +-dontwarn com.google.android.gms.** + +# START OkHttp + Okio +# JSR 305 annotations are for embedding nullability information. +-dontwarn javax.annotation.** + + +# A resource is loaded with a relative path so the package of this class must be preserved. +-adaptresourcefilenames okhttp3/internal/publicsuffix/PublicSuffixDatabase.gz + + +# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java. +-dontwarn org.codehaus.mojo.animal_sniffer.* + + +# OkHttp platform used only on JVM and when Conscrypt and other security providers are available. +-dontwarn okhttp3.internal.platform.** +-dontwarn org.conscrypt.** +-dontwarn org.bouncycastle.** +-dontwarn org.openjsse.** + + +# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java. +-dontwarn org.codehaus.mojo.animal_sniffer.* + + +# END OkHttp + Okio + + +# START Protobuf +-dontwarn com.google.protobuf.** +-keepclassmembers class com.google.protobuf.** { + *; +} +-keep class * extends com.google.protobuf.GeneratedMessageLite { *; } + + +# END Protobuf +-keepclassmembers class com.ironsource.sdk.controller.IronSourceWebView$JSInterface { + public *; +} +-keepclassmembers class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} +-keep public class com.google.android.gms.ads.** { + public *; +} +-keep class com.ironsource.adapters.** { *; +} +-dontwarn com.ironsource.mediationsdk.** +-dontwarn com.ironsource.adapters.** +-keepattributes JavascriptInterface +-keepclassmembers class * { + @android.webkit.JavascriptInterface ; +} +-keep class com.bytedance.sdk.** { *; } +-keepattributes Signature +-keepattributes *Annotation* +-keep class com.mbridge.** {*; } +-keep interface com.mbridge.** {*; } +-keep class android.support.v4.** { *; } +-dontwarn com.mbridge.** +-keep class **.R$* { public static final int mbridge*; } +-keep public class com.mbridge.* extends androidx.** { *; } +-keep public class androidx.viewpager.widget.PagerAdapter{ *; } +-keep public class androidx.viewpager.widget.ViewPager.OnPageChangeListener{ *; } +-keep interface androidx.annotation.IntDef{ *; } +-keep interface androidx.annotation.Nullable{ *; } +-keep interface androidx.annotation.CheckResult{ *; } +-keep interface androidx.annotation.NonNull{ *; } +-keep public class androidx.fragment.app.Fragment{ *; } +-keep public class androidx.core.content.FileProvider{ *; } +-keep public class androidx.core.app.NotificationCompat{ *; } +-keep public class androidx.appcompat.widget.AppCompatImageView { *; } +-keep public class androidx.recyclerview.*{ *; } +#---------------------------------------------Topon \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8269789..41ec326 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -19,6 +19,9 @@ android:supportsRtl="true" android:theme="@style/Theme.PhotographyWallpaper" tools:targetApi="31"> + diff --git a/app/src/main/assets/privacy.html b/app/src/main/assets/privacy.html new file mode 100644 index 0000000..b05935a --- /dev/null +++ b/app/src/main/assets/privacy.html @@ -0,0 +1,86 @@ + + + + + + Privacy Policy + + + +

Privacy Policy

+

Date: August 8, 2024

+ +

We provide this Privacy Policy to help you understand how we collect, use, and disclose information, including what you may provide to us or that we obtain from our products and services. We treat your privacy very seriously. Your privacy is important to us.

+ +

Information Collection and Use

+

For a better experience, while using our Service, we may require you to provide us with certain personally identifiable information, such as users' name, address, location, pictures, etc. The information that we request will be retained on your device and is not collected or retained by us in any way and used as described in this privacy policy.

+

The app does use third-party services that may collect information used to identify you.

+

Please refer to the privacy policy of the third-party service provider used by the application:

+
    +
  • Google Play Services
  • +
  • Google Analytics for Firebase
  • +
  • Firebase Crashlytics
  • +
  • Unity
  • +
  • AppLovin
  • +
  • Pangle
  • +
  • Mintegral
  • +
  • Bigo
  • +
  • Ironsource
  • +
  • Vungle
  • +
+ +

Log Data

+

We want to inform you that whenever you use our Service, in case of an error in the app, we collect data and information (through third-party products) on your phone called Log Data. This Log Data may include information such as your device Internet Protocol (“IP”) address, device name, operating system version, the configuration of the app when utilizing our Service, the time and date of your use of the Service, and other statistics.

+ +

Cookies

+

Cookies are files with a small amount of data that are commonly used as anonymous unique identifiers. These are sent to your browser from the websites that you visit and are stored on your device's internal memory.

+

This Service does not use these “cookies” explicitly. However, the app may use third-party code and libraries that use “cookies” to collect information and improve their services. You have the option to either accept or refuse these cookies and know when a cookie is being sent to your device. If you choose to refuse our cookies, you may not be able to use some portions of this Service.

+ +

Service Providers

+

We may employ third-party companies and individuals due to the following reasons:

+
    +
  • To facilitate our Service
  • +
  • To provide the Service on our behalf
  • +
  • To perform Service-related services
  • +
  • To assist us in analyzing how our Service is used
  • +
+

We want to inform users of this Service that these third parties have access to their Personal Information. The reason is to perform the tasks assigned to them on our behalf. However, they are obligated not to disclose or use the information for any other purpose.

+ +

Security

+

We value your trust in providing us your Personal Information, thus we are striving to use commercially acceptable means of protecting it. But remember that no method of transmission over the internet, or method of electronic storage is 100% secure and reliable, and we cannot guarantee its absolute security.

+ +

Links to Other Sites

+

This Service may contain links to other sites. If you click on a third-party link, you will be directed to that site. Note that these external sites are not operated by us. Therefore, we strongly advise you to review the Privacy Policy of these websites. We have no control over and assume no responsibility for the content, privacy policies, or practices of any third-party sites or services.

+ +

Children’s Privacy

+

These Services do not address anyone under the age of 13. We do not knowingly collect personally identifiable information from children under 13 years of age. In the case we discover that a child under 13 has provided us with personal information, we will immediately delete this from our servers. If you are a parent or guardian and you are aware that your child has provided us with personal information, please contact us so that we will be able to take the necessary actions.

+ +

Changes to This Privacy Policy

+

We may update our Privacy Policy from time to time. Thus, you are advised to review this page periodically for any changes. We will notify you of any changes by posting the new Privacy Policy on this page.

+ +

Privacy Questions

+

We may update the Privacy Policy from time to time. When we change the policy in a material way, a notice will be posted on our website along with the updated Privacy Policy.

+

If you have any questions or concerns about our Privacy Policy or data processing, please contact us: ml0944887MarieLatham1983445@gmail.com.

+ + diff --git a/app/src/main/java/com/wall/photography/wallpaper/MyApp.kt b/app/src/main/java/com/wall/photography/wallpaper/MyApp.kt index 5daf39a..ee4b99c 100644 --- a/app/src/main/java/com/wall/photography/wallpaper/MyApp.kt +++ b/app/src/main/java/com/wall/photography/wallpaper/MyApp.kt @@ -2,13 +2,19 @@ package com.wall.photography.wallpaper import android.app.Application import android.util.Log +import com.anythink.core.api.ATSDK +import com.anythink.core.api.NetTrafficeCallback +import com.anythink.debug.api.ATDebuggerUITest import com.wall.photography.wallpaper.data.Bean +import com.wall.photography.wallpaper.firebase.RemoteConfigNew import com.wall.photography.wallpaper.manager.DealData import com.wall.photography.wallpaper.room.MyDataBase +import com.wall.photography.wallpaper.topon.AdManager import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch + class MyApp : Application() { companion object { lateinit var application: Application @@ -29,19 +35,26 @@ class MyApp : Application() { lateinit var strings: Array + + } + private val APPId = "h66b1d37c22a77" + private val AppKey = "a3f5e17582cca6e43dcbb0732c125dec8" + + private val debug_Key = "63db2183733f4027ed5333d9ea59e1540d46b1a6" override fun onCreate() { super.onCreate() application = this - Log.d(TAG, "---------------onCreate") - + Log.d(TAG, "--------------Application-onCreate") + RemoteConfigNew.instance.init(this) + initTopOnSDK() CoroutineScope(Dispatchers.IO).launch { - Log.d(TAG, "---------------协程开始" + Thread.currentThread().name) + Log.d(TAG, "---------------协程开始") strings = resources.getStringArray(R.array.category_name) val allWallpaper = MyDataBase.getInstance().getBeanDao().getCategoryCovert(strings[7]) if (allWallpaper != null) { - Log.d(TAG, "---------------协程结束 --" + Thread.currentThread().name) + Log.d(TAG, "---------------协程结束 --") return@launch } for (i in 0 until 8) { @@ -53,9 +66,9 @@ class MyApp : Application() { } dataAlready = true - Log.d(TAG, "---------------协程结束 --" + Thread.currentThread().name) + Log.d(TAG, "---------------协程结束 --") } - Log.d(TAG, "---------------onCreate end") + Log.d(TAG, "---------------Application onCreate end") } private fun initData(fileName: String): List { @@ -67,5 +80,25 @@ class MyApp : Application() { return bean } + private fun initTopOnSDK() { + ATSDK.checkIsEuTraffic(this, object : NetTrafficeCallback { + override fun onResultCallback(isEU: Boolean) { + Log.e(TAG, "onResultCallback:$isEU") + if (isEU && ATSDK.getGDPRDataLevel(this@MyApp) == ATSDK.UNKNOWN) { + ATSDK.showGdprAuth(this@MyApp) + } + } + + override fun onErrorCallback(errorMsg: String) { + Log.e(TAG, "onErrorCallback:$errorMsg") + } + }) + ATSDK.init(this, APPId, AppKey) + AdManager.loadAllAd() + //测试工具 +// ATDebuggerUITest.showDebuggerUI(this, debug_Key) +// ATSDK.setNetworkLogDebug(true) + } + } \ No newline at end of file diff --git a/app/src/main/java/com/wall/photography/wallpaper/activivty/AboutActivity.kt b/app/src/main/java/com/wall/photography/wallpaper/activivty/AboutActivity.kt index 6408973..2572259 100644 --- a/app/src/main/java/com/wall/photography/wallpaper/activivty/AboutActivity.kt +++ b/app/src/main/java/com/wall/photography/wallpaper/activivty/AboutActivity.kt @@ -9,6 +9,7 @@ import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import com.wall.photography.wallpaper.R import com.wall.photography.wallpaper.databinding.ActivityAboutBinding +import com.wall.photography.wallpaper.topon.AdManager class AboutActivity : AppCompatActivity() { @@ -17,17 +18,18 @@ class AboutActivity : AppCompatActivity() { super.onCreate(savedInstanceState) vb = ActivityAboutBinding.inflate(layoutInflater) setContentView(vb.root) - + AdManager.loadAllAd() val appVersionName = getAppVersionName() appVersionName?.run { vb.tvVersion.text = String.format(getString(R.string.version), this.versionName) } ?: run { vb.tvVersion.text = String.format(getString(R.string.version), "1.0.0") } - - - - vb.back.setOnClickListener { finish() } + vb.back.setOnClickListener { + AdManager.showTopOn(this@AboutActivity) { + finish() + } + } vb.layoutRate.setOnClickListener { try { val uri = String.format(getString(R.string.google_link), packageName) @@ -43,6 +45,20 @@ class AboutActivity : AppCompatActivity() { ).show() } } + + vb.layoutPrivacy.setOnClickListener { + AdManager.showTopOn(this@AboutActivity) { + startActivity(Intent(this@AboutActivity, PrivacyActivity::class.java)) + } + } + } + + + override fun onBackPressed() { + super.onBackPressed() + AdManager.showTopOn(this@AboutActivity) { + + } } private fun getAppVersionName(): PackageInfo? { diff --git a/app/src/main/java/com/wall/photography/wallpaper/activivty/ListActivity.kt b/app/src/main/java/com/wall/photography/wallpaper/activivty/ListActivity.kt index 0bc8d5b..c995d87 100644 --- a/app/src/main/java/com/wall/photography/wallpaper/activivty/ListActivity.kt +++ b/app/src/main/java/com/wall/photography/wallpaper/activivty/ListActivity.kt @@ -14,6 +14,7 @@ import com.wall.photography.wallpaper.databinding.ActivityListBinding import com.wall.photography.wallpaper.databinding.ActivityMainBinding import com.wall.photography.wallpaper.fragment.HomeViewModel import com.wall.photography.wallpaper.manager.MyItemDecoration +import com.wall.photography.wallpaper.topon.AdManager import com.wall.photography.wallpaper.viewmode.ListActivityViewModel import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -22,31 +23,38 @@ import kotlinx.coroutines.launch class ListActivity : AppCompatActivity() { private lateinit var vb: ActivityListBinding - companion object{ + + companion object { const val KEY = "category_name" } - private lateinit var viewModel:ListActivityViewModel + private lateinit var viewModel: ListActivityViewModel private lateinit var adapterHomepaging: AdapterHomePaing - private lateinit var name:String + private lateinit var name: String override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) vb = ActivityListBinding.inflate(layoutInflater) + AdManager.loadAllAd() setContentView(vb.root) viewModel = ViewModelProvider(this)[ListActivityViewModel::class.java] name = intent.getStringExtra(KEY)!! vb.tvName.text = name vb.back.setOnClickListener { - finish() + AdManager.showTopOn(this@ListActivity) { + finish() + } } - adapterHomepaging = AdapterHomePaing(mContext=this@ListActivity){ - startActivity(Intent(this, SetWallpaperActivity::class.java).apply { - putExtra(SetWallpaperActivity.KEY_DATA, it) - }) + adapterHomepaging = AdapterHomePaing(mContext = this@ListActivity) { + AdManager.showTopOn(this@ListActivity) { + startActivity(Intent(this, SetWallpaperActivity::class.java).apply { + putExtra(SetWallpaperActivity.KEY_DATA, it) + putExtra(SetWallpaperActivity.KEY_MAIN_ENTER, false) + }) + } } - CoroutineScope(Dispatchers.Main).launch{ + CoroutineScope(Dispatchers.Main).launch { viewModel.getPagingData(name).collectLatest { - Log.d(MyApp.TAG,"------------collectLatest ") + Log.d(MyApp.TAG, "------------collectLatest ") adapterHomepaging.submitData(it) } } @@ -54,6 +62,13 @@ class ListActivity : AppCompatActivity() { } + override fun onBackPressed() { + super.onBackPressed() + AdManager.showTopOn(this@ListActivity) { + + } + } + private fun initWallpaper() { vb.list.run { layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL) diff --git a/app/src/main/java/com/wall/photography/wallpaper/activivty/MainActivity.kt b/app/src/main/java/com/wall/photography/wallpaper/activivty/MainActivity.kt index fb66fdb..ca23ea6 100644 --- a/app/src/main/java/com/wall/photography/wallpaper/activivty/MainActivity.kt +++ b/app/src/main/java/com/wall/photography/wallpaper/activivty/MainActivity.kt @@ -14,6 +14,7 @@ import com.wall.photography.wallpaper.fragment.CategoryFragment import com.wall.photography.wallpaper.fragment.HomeFragment import com.wall.photography.wallpaper.fragment.LoveFragment import com.wall.photography.wallpaper.manager.DealData +import com.wall.photography.wallpaper.topon.AdManager class MainActivity : AppCompatActivity() { private lateinit var vb: ActivityMainBinding @@ -31,9 +32,12 @@ class MainActivity : AppCompatActivity() { initVp2() vb.iconSet.setOnClickListener { - startActivity(Intent(this@MainActivity,AboutActivity::class.java).apply { + AdManager.showTopOn(this@MainActivity) { + startActivity(Intent(this@MainActivity, AboutActivity::class.java).apply { + + }) + } - }) } vb.bottomNavigation.setOnItemSelectedListener { menu -> when (menu.itemId) { @@ -43,6 +47,7 @@ class MainActivity : AppCompatActivity() { val cateFragment = listOf[1] as CategoryFragment cateFragment.refreshCate() } + R.id.love -> { vb.viewpager2.currentItem = 2 val loveFragment = listOf[2] as LoveFragment @@ -73,6 +78,7 @@ class MainActivity : AppCompatActivity() { val cateFragment = listOf[1] as CategoryFragment cateFragment.refreshCate() } + 2 -> { vb.bottomNavigation.selectedItemId = R.id.love val loveFragment = listOf[2] as LoveFragment diff --git a/app/src/main/java/com/wall/photography/wallpaper/activivty/MyWelComeActivity.kt b/app/src/main/java/com/wall/photography/wallpaper/activivty/MyWelComeActivity.kt index 82ecb50..5a2f34b 100644 --- a/app/src/main/java/com/wall/photography/wallpaper/activivty/MyWelComeActivity.kt +++ b/app/src/main/java/com/wall/photography/wallpaper/activivty/MyWelComeActivity.kt @@ -4,16 +4,19 @@ import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.os.CountDownTimer +import android.util.Log import com.wall.photography.wallpaper.MyApp import com.wall.photography.wallpaper.R import com.wall.photography.wallpaper.databinding.ActivityMainBinding import com.wall.photography.wallpaper.databinding.ActivityWelcomeBinding +import com.wall.photography.wallpaper.topon.AdManager +import kotlin.math.roundToInt class MyWelComeActivity : AppCompatActivity() { - private lateinit var vb:ActivityWelcomeBinding - private lateinit var goTimer:CountDownTimer - private val countTime = 2000L + private lateinit var vb: ActivityWelcomeBinding + private var goTimer: CountDownTimer? = null + private val countTime = 11000L override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) vb = ActivityWelcomeBinding.inflate(layoutInflater) @@ -21,24 +24,33 @@ class MyWelComeActivity : AppCompatActivity() { init() } - private fun init(){ - goTimer = object :CountDownTimer(countTime,500){ - override fun onTick(millisUntilFinished: Long) { + private fun init() { - } - - override fun onFinish() { + goTimer = + AdManager.showWelcomeAd(this@MyWelComeActivity, countTime, { millisUntilFinished -> + val percentage: Float = 100 - millisUntilFinished.toFloat() / countTime * 100 + val round = percentage.roundToInt() + vb.progressbar.progress = round + if (AdManager.place1LoadFail && AdManager.place2LoadFail && AdManager.place3LoadFail) { + goTimer?.cancel() enterMain() - - + Log.d(MyApp.TAG, "-------------cancel") + } + }) { + enterMain() } - } - goTimer.start() + + goTimer?.start() } - private fun enterMain(){ + private fun enterMain() { startActivity(Intent(this@MyWelComeActivity, MainActivity::class.java)) finish() } + override fun onDestroy() { + super.onDestroy() + goTimer?.cancel() + } + } \ No newline at end of file diff --git a/app/src/main/java/com/wall/photography/wallpaper/activivty/PrivacyActivity.kt b/app/src/main/java/com/wall/photography/wallpaper/activivty/PrivacyActivity.kt new file mode 100644 index 0000000..43c2eb6 --- /dev/null +++ b/app/src/main/java/com/wall/photography/wallpaper/activivty/PrivacyActivity.kt @@ -0,0 +1,33 @@ +package com.wall.photography.wallpaper.activivty + +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import com.wall.photography.wallpaper.R +import com.wall.photography.wallpaper.databinding.ActivityPrivacyBinding +import com.wall.photography.wallpaper.topon.AdManager + + +class PrivacyActivity : AppCompatActivity() { + + private lateinit var vb: ActivityPrivacyBinding + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + AdManager.loadAllAd() + vb = ActivityPrivacyBinding.inflate(layoutInflater) + setContentView(vb.root) + vb.webView.loadUrl("file:///android_asset/privacy.html") + vb.back.setOnClickListener { + AdManager.showTopOn(this@PrivacyActivity) { + finish() + } + } + + } + + override fun onBackPressed() { + super.onBackPressed() + AdManager.showTopOn(this@PrivacyActivity) { + + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/wall/photography/wallpaper/activivty/SetWallpaperActivity.kt b/app/src/main/java/com/wall/photography/wallpaper/activivty/SetWallpaperActivity.kt index ff11a27..29b507b 100644 --- a/app/src/main/java/com/wall/photography/wallpaper/activivty/SetWallpaperActivity.kt +++ b/app/src/main/java/com/wall/photography/wallpaper/activivty/SetWallpaperActivity.kt @@ -3,20 +3,16 @@ package com.wall.photography.wallpaper.activivty import android.app.WallpaperManager import android.content.pm.PackageManager -import android.graphics.BitmapFactory -import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable import android.os.Build import android.os.Bundle import android.util.Log import android.view.View import android.view.WindowManager -import android.widget.RelativeLayout import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.view.isVisible -import androidx.core.view.marginBottom import com.bumptech.glide.Glide import com.bumptech.glide.load.DataSource import com.bumptech.glide.load.engine.DiskCacheStrategy @@ -25,12 +21,13 @@ import com.bumptech.glide.request.RequestListener import com.bumptech.glide.request.target.Target import com.wall.photography.wallpaper.MyApp import com.wall.photography.wallpaper.R -import com.wall.photography.wallpaper.Test +import com.wall.photography.wallpaper.util.Utils import com.wall.photography.wallpaper.data.Bean import com.wall.photography.wallpaper.databinding.ActivitySetWallpaperBinding import com.wall.photography.wallpaper.manager.DealData import com.wall.photography.wallpaper.manager.Other import com.wall.photography.wallpaper.room.MyDataBase +import com.wall.photography.wallpaper.topon.AdManager import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -42,6 +39,7 @@ class SetWallpaperActivity : AppCompatActivity(), View.OnClickListener { companion object { const val KEY_DATA = "key_data" + const val KEY_MAIN_ENTER = "key_main_enter" } private var code = 1 @@ -52,15 +50,19 @@ class SetWallpaperActivity : AppCompatActivity(), View.OnClickListener { private lateinit var data: Bean private lateinit var vb: ActivitySetWallpaperBinding + + private var mainEnter = true override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Log.d(MyApp.TAG, "----------SetWallpaperActivity--onCreate=$this") - + AdManager.loadAllAd() vb = ActivitySetWallpaperBinding.inflate(layoutInflater) setContentView(vb.root) vb.loadingView.isVisible = true initBar() data = intent.getSerializableExtra(KEY_DATA) as Bean + mainEnter = intent.getBooleanExtra(KEY_MAIN_ENTER, true) + wallpaperManager = WallpaperManager.getInstance(this) CoroutineScope(Dispatchers.IO).launch { data = MyDataBase.getInstance().getBeanDao().getCurWallpaper(data.id) @@ -97,7 +99,7 @@ class SetWallpaperActivity : AppCompatActivity(), View.OnClickListener { if (navigationBarHeight != 0) { val newLayoutParams = vb.relayout.layoutParams as ConstraintLayout.LayoutParams vb.relayout.layoutParams = newLayoutParams.apply { - bottomMargin = navigationBarHeight+Other.dpToPx(20,MyApp.application) + bottomMargin = navigationBarHeight + Other.dpToPx(20, MyApp.application) } } @@ -166,7 +168,7 @@ class SetWallpaperActivity : AppCompatActivity(), View.OnClickListener { } else { val newFile = File(it) // val saveToGallery = DealData.saveToGallery(this@SetWallpaperActivity, newFile) - val saveToGallery = Test.saveToGallery(this@SetWallpaperActivity, newFile) + val saveToGallery = Utils.saveToGallery(this@SetWallpaperActivity, newFile) if (saveToGallery != null) getString(R.string.save_ok) else getString( R.string.save_fail ) @@ -222,7 +224,7 @@ class SetWallpaperActivity : AppCompatActivity(), View.OnClickListener { .diskCacheStrategy(DiskCacheStrategy.ALL) .error(R.drawable.placeholder) .placeholder(R.drawable.placeholder) - .listener(object : RequestListener{ + .listener(object : RequestListener { override fun onLoadFailed( e: GlideException?, model: Any?, @@ -252,20 +254,19 @@ class SetWallpaperActivity : AppCompatActivity(), View.OnClickListener { } private fun loadRegular() { - Glide.with(MyApp.application) - .asDrawable() - .load(data.urls.regular) - .thumbnail(0.2f) - .error(R.drawable.placeholder) - .skipMemoryCache(true) - .diskCacheStrategy(DiskCacheStrategy.ALL) - .placeholder(R.drawable.placeholder) - .into(vb.preview) + Glide.with(MyApp.application) + .asDrawable() + .load(data.urls.regular) + .thumbnail(0.2f) + .error(R.drawable.placeholder) + .skipMemoryCache(true) + .diskCacheStrategy(DiskCacheStrategy.ALL) + .placeholder(R.drawable.placeholder) + .into(vb.preview) } - private fun initBar() { window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) @@ -287,23 +288,47 @@ class SetWallpaperActivity : AppCompatActivity(), View.OnClickListener { } + override fun onBackPressed() { + super.onBackPressed() + AdManager.showTopOn(this@SetWallpaperActivity) { + } + + } + override fun onClick(v: View?) { v?.run { vb.run { when (v) { back -> { - finish() + AdManager.showTopOn(this@SetWallpaperActivity) { + finish() + } + } imLove -> { - imLove.isSelected = !imLove.isSelected + AdManager.showTopOn(this@SetWallpaperActivity) { + imLove.isSelected = !imLove.isSelected + + var msg: String = if (imLove.isSelected) { + getString(R.string.like_success) + } else { + getString(R.string.cancel_like_success) + } + Toast.makeText(this@SetWallpaperActivity, msg, Toast.LENGTH_SHORT) + .show() + } + } imSetWallpaper -> { if (dialog == null) { dialog = SelectDialog { vb.loadingView.visibility = View.VISIBLE - Log.d(MyApp.TAG, "-------------isVisible ${Thread.currentThread().name}") + Log.d( + MyApp.TAG, + "-------------isVisible ${Thread.currentThread().name}" + ) data.downloadFilePath?.let { filePath -> val file = File(filePath) if (file.exists()) { @@ -337,12 +362,11 @@ class SetWallpaperActivity : AppCompatActivity(), View.OnClickListener { } imDownload -> { - if (Other.requestPermission(this@SetWallpaperActivity, code)) { - startSaveIm() - } else { - + AdManager.showTopOn(this@SetWallpaperActivity) { + if (Other.requestPermission(this@SetWallpaperActivity, code)) { + startSaveIm() + } } - } else -> {} @@ -356,14 +380,20 @@ class SetWallpaperActivity : AppCompatActivity(), View.OnClickListener { private fun launchSet(type: Int, file: File) { CoroutineScope(Dispatchers.Main).launch { - var msg: String = try { - startSetWallpaper(type, file) - getString(R.string.set_success) - } catch (ex: Exception) { - getString(R.string.set_fail) + + AdManager.showTopOn( + this@SetWallpaperActivity + ) { + var msg: String = try { + startSetWallpaper(type, file) + getString(R.string.set_success) + } catch (ex: Exception) { + getString(R.string.set_fail) + } + saveResultToast(msg) + Log.d(MyApp.TAG, "------------end SetWallpaper") } - saveResultToast(msg) - Log.d(MyApp.TAG, "------------end SetWallpaper") + } } diff --git a/app/src/main/java/com/wall/photography/wallpaper/firebase/RemoteConfigKey.kt b/app/src/main/java/com/wall/photography/wallpaper/firebase/RemoteConfigKey.kt new file mode 100644 index 0000000..39730dd --- /dev/null +++ b/app/src/main/java/com/wall/photography/wallpaper/firebase/RemoteConfigKey.kt @@ -0,0 +1,245 @@ +package com.wall.photography.wallpaper.firebase + +object RemoteConfigKey { + + //配置在firebase中的key,通过它取出自己配置的json + const val KEY_AD_SHOW_INTERVAL = "key_ad_show_interval" + + + const val DEFAULT_AD_JSON = """ +{ + "AD_SHOW_LIMIT": { + "admob_inst": 100, + "admob_native": 100, + "max_banner": 100, + "max_inst": 100, + "max_native": 100 + }, + "sounds_inst_show_interval": 25000, + "LOLAds_EXPIRE_HOURS_NEW_USER": 20, + "sounds_inst_splash": { + "data": [{ + "after_click": { + "admob_inst": "keep", + "max_inst": "keep" + }, + "block": { + "admob_inst": { + "delay": 0, + "rate": 0 + }, + "max_inst": { + "delay": 0, + "rate": 0 + } + }, + "close": { + "admob_inst": { + "delay": 0, + "rate": 0 + }, + "max_inst": { + "delay": 0, + "rate": 0 + } + }, + "config": [ + [ + "admob_inst", + { + "ca-app-pub-2419639357236809/7376891200": 100 + } + ] + ], + "limit": { + "admob_inst": 100, + "max_inst": 100 + }, + "cycle": 0, + "timeout": 15000, + "showIntervalEnable": false + }] + }, + "sounds_inst_into_play": { + "data": [{ + "after_click": { + "admob_inst": "keep", + "max_inst": "keep" + }, + "block": { + "admob_inst": { + "delay": 0, + "rate": 0 + }, + "max_inst": { + "delay": 0, + "rate": 0 + } + }, + "close": { + "admob_inst": { + "delay": 0, + "rate": 0 + }, + "max_inst": { + "delay": 0, + "rate": 0 + } + }, + "config": [ + [ + "admob_inst", + { + "ca-app-pub-2419639357236809/9750976941": 100 + } + ] + ], + "limit": { + "admob_inst": 100, + "max_inst": 100 + }, + "cycle": 0, + "timeout": 15000, + "showIntervalEnable": false + }] + }, + "sounds_inst_exit_sounds_list": { + "data": [{ + "after_click": { + "admob_inst": "keep", + "max_inst": "keep" + }, + "block": { + "admob_inst": { + "delay": 0, + "rate": 0 + }, + "max_inst": { + "delay": 0, + "rate": 0 + } + }, + "close": { + "admob_inst": { + "delay": 0, + "rate": 0 + }, + "max_inst": { + "delay": 0, + "rate": 0 + } + }, + "config": [ + [ + "admob_inst", + { + "ca-app-pub-2419639357236809/9844693327": 100 + } + ] + ], + "limit": { + "admob_inst": 100, + "max_inst": 100 + }, + "cycle": 0, + "timeout": 15000, + "showIntervalEnable": false + }] + }, + "sounds_android_native_musicList": { + "data": [{ + "config": [ + [ + "admob_native", + { + "ca-app-pub-2419639357236809/9811482858": 100 + } + ] + ], + "block": { + "admob_native": { + "delay": 0, + "rate": 0 + }, + "max_native": { + "delay": 0, + "rate": 0 + } + }, + "click": { + "admob_native": [ + 100, + 100, + 100, + 100, + 100 + ], + "max_native": [ + 100, + 100, + 100, + 100, + 100 + ] + }, + "after_click": { + "admob_native": "next", + "max_native": "next" + }, + "limit": { + "admob_native": 100, + "max_native": 100 + } + }] + }, + "sounds_android_native_play": { + "data": [{ + "config": [ + [ + "admob_native", + { + "ca-app-pub-2419639357236809/8134642941": 100 + } + ] + ], + "block": { + "admob_native": { + "delay": 0, + "rate": 0 + }, + "max_native": { + "delay": 0, + "rate": 0 + } + }, + "click": { + "admob_native": [ + 100, + 100, + 100, + 100, + 100 + ], + "max_native": [ + 100, + 100, + 100, + 100, + 100 + ] + }, + "after_click": { + "admob_native": "next", + "max_native": "next" + }, + "limit": { + "admob_native": 100, + "max_native": 100 + } + }] + } +} + """ +//"{\"AD_SHOW_LIMIT\":{\"max_banner\":100,\"max_inst\":100,\"max_native\":100},\"sounds_inst_show_interval\":25000,\"LOLAds_EXPIRE_HOURS_NEW_USER\":20,\"sounds_inst_splash\":{\"data\":[{\"after_click\":{\"max_inst\":\"keep\"},\"block\":{\"max_inst\":{\"delay\":0,\"rate\":0}},\"close\":{\"max_inst\":{\"delay\":0,\"rate\":0}},\"config\":[[\"max_inst\",{\"f685a8fc471fd92b\":100}]],\"limit\":{\"max_inst\":100},\"cycle\":0,\"timeout\":15000,\"showIntervalEnable\":false}]},\"sounds_inst_into_sounds_list\":{\"data\":[{\"after_click\":{\"max_inst\":\"keep\"},\"block\":{\"max_inst\":{\"delay\":0,\"rate\":0}},\"close\":{\"max_inst\":{\"delay\":0,\"rate\":0}},\"config\":[[\"max_inst\",{\"2a1e13e10c0358c9\":100}]],\"limit\":{\"max_inst\":100},\"cycle\":0,\"timeout\":15000,\"showIntervalEnable\":false}]},\"sounds_inst_into_play\":{\"data\":[{\"after_click\":{\"max_inst\":\"keep\"},\"block\":{\"max_inst\":{\"delay\":0,\"rate\":0}},\"close\":{\"max_inst\":{\"delay\":0,\"rate\":0}},\"config\":[[\"max_inst\",{\"2a1e13e10c0358c9\":100}]],\"limit\":{\"max_inst\":100},\"cycle\":0,\"timeout\":15000,\"showIntervalEnable\":false}]},\"sounds_inst_into_play2\":{\"data\":[{\"after_click\":{\"max_inst\":\"keep\"},\"block\":{\"max_inst\":{\"delay\":0,\"rate\":0}},\"close\":{\"max_inst\":{\"delay\":0,\"rate\":0}},\"config\":[[\"max_inst\",{\"2a1e13e10c0358c9\":100}]],\"limit\":{\"max_inst\":100},\"cycle\":0,\"timeout\":15000,\"showIntervalEnable\":false}]},\"sounds_inst_exit_sounds_list\":{\"data\":[{\"after_click\":{\"max_inst\":\"keep\"},\"block\":{\"max_inst\":{\"delay\":0,\"rate\":0}},\"close\":{\"max_inst\":{\"delay\":0,\"rate\":0}},\"config\":[[\"max_inst\",{\"b0c27a89f370cbed\":100}]],\"limit\":{\"max_inst\":100},\"cycle\":0,\"timeout\":15000,\"showIntervalEnable\":false}]},\"sounds_inst_exit_play\":{\"data\":[{\"after_click\":{\"max_inst\":\"keep\"},\"block\":{\"max_inst\":{\"delay\":0,\"rate\":0}},\"close\":{\"max_inst\":{\"delay\":0,\"rate\":0}},\"config\":[[\"max_inst\",{\"b0c27a89f370cbed\":100}]],\"limit\":{\"max_inst\":100},\"cycle\":0,\"timeout\":15000,\"showIntervalEnable\":false}]},\"sounds_inst_exit_play2\":{\"data\":[{\"after_click\":{\"max_inst\":\"keep\"},\"block\":{\"max_inst\":{\"delay\":0,\"rate\":0}},\"close\":{\"max_inst\":{\"delay\":0,\"rate\":0}},\"config\":[[\"max_inst\",{\"b0c27a89f370cbed\":100}]],\"limit\":{\"max_inst\":100},\"cycle\":0,\"timeout\":15000,\"showIntervalEnable\":false}]},\"sounds_inst_exit_edit\":{\"data\":[{\"after_click\":{\"max_inst\":\"keep\"},\"block\":{\"max_inst\":{\"delay\":0,\"rate\":0}},\"close\":{\"max_inst\":{\"delay\":0,\"rate\":0}},\"config\":[[\"max_inst\",{\"b0c27a89f370cbed\":100}]],\"limit\":{\"max_inst\":100},\"cycle\":0,\"timeout\":15000,\"showIntervalEnable\":false}]},\"sounds_inst_create_next\":{\"data\":[{\"after_click\":{\"max_inst\":\"keep\"},\"block\":{\"max_inst\":{\"delay\":0,\"rate\":0}},\"close\":{\"max_inst\":{\"delay\":0,\"rate\":0}},\"config\":[[\"max_inst\",{\"66d99619cea2243d\":100}]],\"limit\":{\"max_inst\":100},\"cycle\":0,\"timeout\":15000,\"showIntervalEnable\":false}]},\"sounds_android_native_musicList\":{\"data\":[{\"config\":[[\"max_native\",{\"2aa4162b650aa26d\":100}]],\"block\":{\"max_native\":{\"delay\":0,\"rate\":0}},\"click\":{\"max_native\":[100,100,100,100,100]},\"after_click\":{\"max_native\":\"next\"},\"limit\":{\"max_native\":100}}]},\"sounds_android_native_play\":{\"data\":[{\"config\":[[\"max_native\",{\"35f6847f26ddcd76\":100}]],\"block\":{\"max_native\":{\"delay\":0,\"rate\":0}},\"click\":{\"max_native\":[100,100,100,100,100]},\"after_click\":{\"max_native\":\"next\"},\"limit\":{\"max_native\":100}}]}}" +} + diff --git a/app/src/main/java/com/wall/photography/wallpaper/firebase/RemoteConfigNew.kt b/app/src/main/java/com/wall/photography/wallpaper/firebase/RemoteConfigNew.kt new file mode 100644 index 0000000..d892d4b --- /dev/null +++ b/app/src/main/java/com/wall/photography/wallpaper/firebase/RemoteConfigNew.kt @@ -0,0 +1,142 @@ +package com.wall.photography.wallpaper.firebase + +import android.annotation.SuppressLint +import android.app.Application +import android.content.Context +import android.os.Handler +import android.os.Looper +import android.os.Message +import android.text.TextUtils +import android.util.Log +import com.google.firebase.remoteconfig.ConfigUpdate +import com.google.firebase.remoteconfig.ConfigUpdateListener +import com.google.firebase.remoteconfig.FirebaseRemoteConfig +import com.google.firebase.remoteconfig.FirebaseRemoteConfigException +import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings +import com.google.firebase.remoteconfig.FirebaseRemoteConfigValue +import com.wall.photography.wallpaper.MyApp + +import java.lang.ref.WeakReference +import com.wall.photography.wallpaper.BuildConfig +import com.wall.photography.wallpaper.util.Sp + +class RemoteConfigNew { + + + private var ctx: Context? = null + private var mFirebaseRemoteConfig: FirebaseRemoteConfig? = null + + //配置是否初始化成功 + private var isInit = false + + //上次获取数据的时间 + private var lastFetchTime: Long = 0 + private val handler = MHandler(this) + + + companion object { + const val MSG_REFRESH_CONFIG = 1 + val instance: RemoteConfigNew by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { + RemoteConfigNew() + } + } + + fun init(ctx: Application) { + this.ctx = ctx + initConfig() + fetchConfig() + onConfigUpdate() + } + + private fun initConfig() { + var intervalTime = (60 * 10).toLong() + //如果是开发状态,则将提取时间缩短 + if (BuildConfig.DEBUG) { + intervalTime = (60 * 5).toLong() + } + mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance() + val configSettings = + FirebaseRemoteConfigSettings.Builder() //默认值12小时的最短提取间隔,如果在间隔内取值,则优先取上次的结果 + .setMinimumFetchIntervalInSeconds(intervalTime).build() + mFirebaseRemoteConfig!!.setConfigSettingsAsync(configSettings) + } + + private fun onConfigUpdate() { + mFirebaseRemoteConfig!!.addOnConfigUpdateListener(object : ConfigUpdateListener { + override fun onUpdate(configUpdate: ConfigUpdate) { + Log.d(MyApp.TAG, "Updated keys: " + configUpdate.updatedKeys) + try { + mFirebaseRemoteConfig!!.activate().addOnCompleteListener { task -> + if (task.isSuccessful) { + updateData("onConfigUpdate", mFirebaseRemoteConfig!!.all) + } + } + } catch (ignore: Exception) { + } + } + + override fun onError(error: FirebaseRemoteConfigException) { + Log.d(MyApp.TAG, "Config update error with code: " + error.code) + } + }) + } + + private fun fetchConfig() { + //这里可能会抛出异常 FirebaseRemoteConfigFetchThrottledException + try { + mFirebaseRemoteConfig!!.fetchAndActivate().addOnCompleteListener { task -> + if (task.isSuccessful) { + isInit = true + lastFetchTime = System.currentTimeMillis() + updateData("fetchAndActivate", mFirebaseRemoteConfig!!.all) + //24小时后,重新再去获取 + handler.removeMessages(MSG_REFRESH_CONFIG) + handler.sendEmptyMessageDelayed( + MSG_REFRESH_CONFIG, (1000 * 60 * 60 * 24).toLong() + ) + } else { + //15分钟后重新再去获取 + handler.removeMessages(MSG_REFRESH_CONFIG) + handler.sendEmptyMessageDelayed(MSG_REFRESH_CONFIG, (1000 * 60 * 15).toLong()) + } + } + } catch (ignore: Exception) { + } + } + + private fun updateData(from: String, all: Map) { + for ((key, value) in all) { + try { + Log.d( + MyApp.TAG, "from = " + from + "Key = " + key + " Value = " + value.asString() + ) + if (TextUtils.equals(RemoteConfigKey.KEY_AD_SHOW_INTERVAL, key)) { + Sp.getInstance(MyApp.application) + .putLong(RemoteConfigKey.KEY_AD_SHOW_INTERVAL, value.asLong()).commit() + } + + } catch (ignore: Exception) { + + } + } + } + + private class MHandler(remoteConfig: RemoteConfigNew) : Handler(Looper.getMainLooper()) { + private val weakReference: WeakReference + + init { + weakReference = WeakReference(remoteConfig) + } + + override fun handleMessage(msg: Message) { + super.handleMessage(msg) + val remoteConfig = weakReference.get() + if (remoteConfig?.ctx != null) { + if (msg.what == MSG_REFRESH_CONFIG) { + remoteConfig.fetchConfig() + } + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/wall/photography/wallpaper/fragment/CategoryFragment.kt b/app/src/main/java/com/wall/photography/wallpaper/fragment/CategoryFragment.kt index 6ad74f7..c78625e 100644 --- a/app/src/main/java/com/wall/photography/wallpaper/fragment/CategoryFragment.kt +++ b/app/src/main/java/com/wall/photography/wallpaper/fragment/CategoryFragment.kt @@ -17,6 +17,7 @@ import com.wall.photography.wallpaper.adapter.AdapterCategory import com.wall.photography.wallpaper.databinding.FragmentCategoryBinding import com.wall.photography.wallpaper.databinding.FragmentHomeBinding import com.wall.photography.wallpaper.manager.MyItemDecoration +import com.wall.photography.wallpaper.topon.AdManager import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -27,7 +28,7 @@ class CategoryFragment : Fragment() { fun newInstance() = CategoryFragment() } - private var viewModel: CategoryViewModel? = null + private var viewModel: CategoryViewModel? = null private lateinit var vb: FragmentCategoryBinding private lateinit var mAdapter: AdapterCategory override fun onCreateView( @@ -44,10 +45,12 @@ class CategoryFragment : Fragment() { CoroutineScope(Dispatchers.IO).launch { viewModel?.getData() } - mAdapter = AdapterCategory(requireContext()){ - startActivity(Intent(requireActivity(),ListActivity::class.java).apply { - putExtra(ListActivity.KEY,it.cateName) - }) + mAdapter = AdapterCategory(requireContext()) { + AdManager.showTopOn(requireActivity()) { + startActivity(Intent(requireActivity(), ListActivity::class.java).apply { + putExtra(ListActivity.KEY, it.cateName) + }) + } } viewModel?.data?.observe(requireActivity()) { @@ -61,7 +64,8 @@ class CategoryFragment : Fragment() { addItemDecoration(MyItemDecoration(requireContext(), 8, 8, 0)) } } - fun refreshCate(){ + + fun refreshCate() { CoroutineScope(Dispatchers.IO).launch { viewModel?.getData() } diff --git a/app/src/main/java/com/wall/photography/wallpaper/fragment/HomeFragment.kt b/app/src/main/java/com/wall/photography/wallpaper/fragment/HomeFragment.kt index f84daed..ff717ae 100644 --- a/app/src/main/java/com/wall/photography/wallpaper/fragment/HomeFragment.kt +++ b/app/src/main/java/com/wall/photography/wallpaper/fragment/HomeFragment.kt @@ -20,6 +20,7 @@ import com.wall.photography.wallpaper.adapter.AdapterHomePaing import com.wall.photography.wallpaper.data.Bean import com.wall.photography.wallpaper.databinding.FragmentHomeBinding import com.wall.photography.wallpaper.manager.MyItemDecoration +import com.wall.photography.wallpaper.topon.AdManager import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.collectLatest @@ -50,16 +51,14 @@ class HomeFragment : Fragment() { override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - Log.d(MyApp.TAG, "------------onActivityCreated homeFragment=$this") - - if (savedInstanceState != null) { - // 恢复之前的状态 - Log.d(MyApp.TAG, "------------onActivityCreated homeFragment list=${list.size}") - } adapterHomepaging = AdapterHomePaing(mContext = requireContext()) { - startActivity(Intent(requireActivity(), SetWallpaperActivity::class.java).apply { - putExtra(SetWallpaperActivity.KEY_DATA, it) - }) + + AdManager.showTopOn(requireActivity()){ + startActivity(Intent(requireActivity(), SetWallpaperActivity::class.java).apply { + putExtra(SetWallpaperActivity.KEY_DATA, it) + }) + } + } viewModel = ViewModelProvider(this)[HomeViewModel::class.java] diff --git a/app/src/main/java/com/wall/photography/wallpaper/fragment/LoveFragment.kt b/app/src/main/java/com/wall/photography/wallpaper/fragment/LoveFragment.kt index 6b988f6..b22d261 100644 --- a/app/src/main/java/com/wall/photography/wallpaper/fragment/LoveFragment.kt +++ b/app/src/main/java/com/wall/photography/wallpaper/fragment/LoveFragment.kt @@ -20,6 +20,7 @@ import com.wall.photography.wallpaper.adapter.AdapterLoves import com.wall.photography.wallpaper.data.Bean import com.wall.photography.wallpaper.databinding.FragmentLoveBinding import com.wall.photography.wallpaper.manager.MyItemDecoration +import com.wall.photography.wallpaper.topon.AdManager import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.collectLatest @@ -35,7 +36,7 @@ class LoveFragment : Fragment() { private lateinit var vb: FragmentLoveBinding private lateinit var adapterLove: AdapterLoves - private var adapterLovePaging: AdapterHomePaing? = null + private var adapterLovePaging: AdapterHomePaing? = null override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -53,26 +54,24 @@ class LoveFragment : Fragment() { } private fun initWallpaper() { -// adapterLove = AdapterLoves(requireContext()) { -// startActivity(Intent(requireActivity(), SetWallpaperActivity::class.java).apply { -// putExtra(SetWallpaperActivity.KEY_DATA, it) -// }) -// } - adapterLovePaging = AdapterHomePaing(true,requireContext()) { - startActivity(Intent(requireActivity(), SetWallpaperActivity::class.java).apply { - putExtra(SetWallpaperActivity.KEY_DATA, it) - }) + + adapterLovePaging = AdapterHomePaing(true, requireContext()) { + AdManager.showTopOn(requireActivity()) { + startActivity(Intent(requireActivity(), SetWallpaperActivity::class.java).apply { + putExtra(SetWallpaperActivity.KEY_DATA, it) + }) + } }.apply { addLoadStateListener { - if(it.source.refresh is LoadState.NotLoading && adapterLovePaging?.itemCount == 0){ - Log.d(MyApp.TAG, "------------love-空") - vb.tvNoLove.isVisible = true - vb.loveRecycler.isVisible = false - }else{ - Log.d(MyApp.TAG, "------------love-不空") - vb.tvNoLove.isVisible = false - vb.loveRecycler.isVisible = true - } + if (it.source.refresh is LoadState.NotLoading && adapterLovePaging?.itemCount == 0) { + Log.d(MyApp.TAG, "------------love-空") + vb.tvNoLove.isVisible = true + vb.loveRecycler.isVisible = false + } else { + Log.d(MyApp.TAG, "------------love-不空") + vb.tvNoLove.isVisible = false + vb.loveRecycler.isVisible = true + } } } @@ -83,10 +82,7 @@ class LoveFragment : Fragment() { } } -// viewModel.getLoves().observe(viewLifecycleOwner) { -// Log.d(MyApp.TAG, "-----------love-update ") -// adapterLove.updateData(it) -// } + vb.loveRecycler.run { layoutManager = LinearLayoutManager(requireContext()) adapter = adapterLovePaging @@ -95,14 +91,11 @@ class LoveFragment : Fragment() { } - fun refreshLoves(){ + fun refreshLoves() { adapterLovePaging?.refresh() } - override fun onResume() { - super.onResume() - Log.d(MyApp.TAG, "------------love onResume") - } + } \ No newline at end of file diff --git a/app/src/main/java/com/wall/photography/wallpaper/topon/AdListener.kt b/app/src/main/java/com/wall/photography/wallpaper/topon/AdListener.kt new file mode 100644 index 0000000..af3cb01 --- /dev/null +++ b/app/src/main/java/com/wall/photography/wallpaper/topon/AdListener.kt @@ -0,0 +1,11 @@ +package com.wall.photography.wallpaper.topon + +interface AdListener { + + fun loadFail(placeId: String) + fun showSuccess() + + fun showFail() + + fun showClose() +} \ No newline at end of file diff --git a/app/src/main/java/com/wall/photography/wallpaper/topon/AdManager.kt b/app/src/main/java/com/wall/photography/wallpaper/topon/AdManager.kt new file mode 100644 index 0000000..e1bf79e --- /dev/null +++ b/app/src/main/java/com/wall/photography/wallpaper/topon/AdManager.kt @@ -0,0 +1,243 @@ +package com.wall.photography.wallpaper.topon + +import android.app.Activity +import android.os.CountDownTimer +import android.util.Log +import com.anythink.core.api.ATAdInfo +import com.anythink.core.api.AdError +import com.anythink.interstitial.api.ATInterstitial +import com.anythink.interstitial.api.ATInterstitialListener +import com.wall.photography.wallpaper.MyApp +import com.wall.photography.wallpaper.firebase.RemoteConfigKey +import com.wall.photography.wallpaper.util.Sp + + +object AdManager { + + //默认的广告展示间隔时间20s + const val VALUE_SHOW_INTERVAL = 1000 * 30L + + //上次广告展示时刻 + var LAST_AD_SHOW = 0L + + const val type_no_cache = 0 + const val type_has_cache = 1 + const val type_show_success = 2 + const val type_show_close = 3 + const val type_show_fail = 4 + + /** + n66b1d3d019590 + n66b1d3cfebd3c + n66b1d3cfc4f3b + */ + + const val place1Id = "n66b1d3d019590" + const val place2Id = "n66b1d3cfebd3c" + const val place3Id = "n66b1d3cfc4f3b" + + + var place1LoadFail = false + var place2LoadFail = false + var place3LoadFail = false + + val list = mutableListOf() + + + @JvmStatic + fun loadAllAd() { + if (list.size <= 0) { + val mInterstitialAd1 = ATInterstitial(MyApp.application, place1Id) + val mInterstitialAd2 = ATInterstitial(MyApp.application, place2Id) + val mInterstitialAd3 = ATInterstitial(MyApp.application, place3Id) + list.add(mInterstitialAd1) + list.add(mInterstitialAd2) + list.add(mInterstitialAd3) + } + for (ad in list) { + if (!ad.isAdReady) { + setCallBack(ad, object : AdListener { + override fun loadFail(placeId: String) { + if (placeId == place1Id) { + place1LoadFail = true + } + if (placeId == place2Id) { + place2LoadFail = true + } + if (placeId == place3Id) { + place3LoadFail = true + } + } + + override fun showSuccess() { + + } + + override fun showFail() { + + } + + override fun showClose() { + + } + + }) + ad.load() + } + } + + + } + + @JvmStatic + fun getReadyAd(): ATInterstitial? { + + if (LAST_AD_SHOW > 0L) { + val adInterval = + Sp.getInstance(MyApp.application).getLongValue(RemoteConfigKey.KEY_AD_SHOW_INTERVAL) + val curInterval = System.currentTimeMillis() - LAST_AD_SHOW + + Log.d( + MyApp.TAG, + "-广告判断------------LAST_AD_SHOW=${LAST_AD_SHOW} curInterval=${curInterval} adInterval=${adInterval}" + ) + if (curInterval < adInterval) { + Log.d( + MyApp.TAG, + "-没有广告--------" + ) + return null + } + } + list.shuffle() + for (ad in list) { + if (ad.isAdReady) { + Log.d(MyApp.TAG, "-有广告------------") + return ad + } + } + Log.d(MyApp.TAG, "-没有广告------------") + return null + } + + + @JvmStatic + fun showWelcomeAd( + activity: Activity, + totalTim: Long, + countAction: (millisUntilFinished: Long) -> Unit, + goMain: () -> Unit + ): CountDownTimer { + var alreadyShow = false + var timer = object : CountDownTimer(totalTim, 100) { + override fun onTick(millisUntilFinished: Long) { + countAction.invoke(millisUntilFinished) + if (!alreadyShow) { + showAD(activity) { + if (it == type_has_cache) { + alreadyShow = true + } + if (it == type_show_close || it == type_show_fail) { + goMain.invoke() + } + + } + } + + } + + override fun onFinish() { + if (!alreadyShow) { + showAD(activity) { + if (it == type_show_close || it == type_show_fail || it == type_no_cache) { + goMain.invoke() + } + } + } + } + + } + return timer + } + + private fun setCallBack(ad: ATInterstitial, listener: AdListener) { + ad.setAdListener(object : ATInterstitialListener { + override fun onInterstitialAdLoaded() { + Log.d(MyApp.TAG, "LoadLoaded ${ad.mPlacementId}") + } + + override fun onInterstitialAdLoadFail(p0: AdError?) { + Log.d(MyApp.TAG, "LoadFail:${p0?.code} ${p0?.desc}") + } + + override fun onInterstitialAdClicked(p0: ATAdInfo?) { + + } + + override fun onInterstitialAdShow(p0: ATAdInfo?) { + Log.d(MyApp.TAG, "AdShow ${p0?.showId} ") + listener.showSuccess() + ad.load() + } + + override fun onInterstitialAdClose(p0: ATAdInfo?) { + listener.showClose() + } + + override fun onInterstitialAdVideoStart(p0: ATAdInfo?) { + + } + + override fun onInterstitialAdVideoEnd(p0: ATAdInfo?) { + + } + + override fun onInterstitialAdVideoError(p0: AdError?) { + listener.showFail() + } + + }) + } + + + @JvmStatic + private fun showAD(activity: Activity, action: (type: Int) -> Unit) { + val readyAd = getReadyAd() + if (readyAd != null) { + Log.d(MyApp.TAG, "readyAd ${readyAd.mPlacementId} ") + action.invoke(type_has_cache) + setCallBack(readyAd, object : AdListener { + override fun loadFail(placeId: String) { + + } + + override fun showSuccess() { + action.invoke(type_show_success) + LAST_AD_SHOW = System.currentTimeMillis() + } + + override fun showFail() { + action.invoke(type_show_fail) + } + + override fun showClose() { + action.invoke(type_show_close) + } + + }) + readyAd.show(activity) + } else { + action.invoke(type_no_cache) + + } + } + + @JvmStatic + fun showTopOn(activity: Activity, listener: onActionListener) { + showAD(activity) { type -> + if (type == type_no_cache || type == type_show_close || type == type_show_fail) { + listener.onAction() + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/wall/photography/wallpaper/topon/FirebaseConfig.java b/app/src/main/java/com/wall/photography/wallpaper/topon/FirebaseConfig.java new file mode 100644 index 0000000..ae919b0 --- /dev/null +++ b/app/src/main/java/com/wall/photography/wallpaper/topon/FirebaseConfig.java @@ -0,0 +1,34 @@ +package com.wall.photography.wallpaper.topon; + +import androidx.annotation.NonNull; + +import com.google.firebase.remoteconfig.ConfigUpdate; +import com.google.firebase.remoteconfig.ConfigUpdateListener; +import com.google.firebase.remoteconfig.FirebaseRemoteConfig; +import com.google.firebase.remoteconfig.FirebaseRemoteConfigException; +import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; + +public class FirebaseConfig { + + + + public static void initFireBaseConfig(){ + FirebaseRemoteConfig mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); + FirebaseRemoteConfigSettings configSettings = new FirebaseRemoteConfigSettings.Builder() + .setMinimumFetchIntervalInSeconds(3600) + .build(); + mFirebaseRemoteConfig.setConfigSettingsAsync(configSettings); + + mFirebaseRemoteConfig.addOnConfigUpdateListener(new ConfigUpdateListener() { + @Override + public void onUpdate(@NonNull ConfigUpdate configUpdate) { + + } + + @Override + public void onError(@NonNull FirebaseRemoteConfigException error) { + + } + }); + } +} diff --git a/app/src/main/java/com/wall/photography/wallpaper/topon/onActionListener.java b/app/src/main/java/com/wall/photography/wallpaper/topon/onActionListener.java new file mode 100644 index 0000000..dda63f2 --- /dev/null +++ b/app/src/main/java/com/wall/photography/wallpaper/topon/onActionListener.java @@ -0,0 +1,6 @@ +package com.wall.photography.wallpaper.topon; + +public interface onActionListener { + + void onAction(); +} diff --git a/app/src/main/java/com/wall/photography/wallpaper/util/Sp.java b/app/src/main/java/com/wall/photography/wallpaper/util/Sp.java new file mode 100644 index 0000000..2053a0c --- /dev/null +++ b/app/src/main/java/com/wall/photography/wallpaper/util/Sp.java @@ -0,0 +1,43 @@ +package com.wall.photography.wallpaper.util; + +import android.app.Application; +import android.content.Context; +import android.content.SharedPreferences; + +import com.wall.photography.wallpaper.MyApp; +import com.wall.photography.wallpaper.topon.AdManager; + +public class Sp { + private static String spName = "AD_SHOW"; + private static Sp instance; + private SharedPreferences.Editor editor; + + private SharedPreferences preferences; + + private Sp(Application context) { + preferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE); + editor = preferences.edit(); + } + + + public static Sp getInstance(Application context) { + if (instance == null) { + instance = new Sp(context); + } + return instance; + } + + + public Sp putLong(String key, long value) { + editor.putLong(key, value); + return this; + } + + public boolean commit() { + return editor.commit(); + } + + public long getLongValue(String key) { + return preferences.getLong(key, AdManager.VALUE_SHOW_INTERVAL); + } +} diff --git a/app/src/main/java/com/wall/photography/wallpaper/Test.java b/app/src/main/java/com/wall/photography/wallpaper/util/Utils.java similarity index 96% rename from app/src/main/java/com/wall/photography/wallpaper/Test.java rename to app/src/main/java/com/wall/photography/wallpaper/util/Utils.java index dd60531..36a15cf 100644 --- a/app/src/main/java/com/wall/photography/wallpaper/Test.java +++ b/app/src/main/java/com/wall/photography/wallpaper/util/Utils.java @@ -1,4 +1,4 @@ -package com.wall.photography.wallpaper; +package com.wall.photography.wallpaper.util; import android.content.ContentResolver; import android.content.ContentValues; @@ -11,7 +11,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.OutputStream; -public class Test { +public class Utils { public static Uri saveToGallery(Context context, File photoFile) { String displayName = System.currentTimeMillis()+".jpg"; @@ -60,4 +60,6 @@ public class Test { return null; } } + + } diff --git a/app/src/main/res/drawable/progressbar.xml b/app/src/main/res/drawable/progressbar.xml new file mode 100644 index 0000000..a4650ec --- /dev/null +++ b/app/src/main/res/drawable/progressbar.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index f5b6ba0..d24ec65 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -11,7 +11,7 @@ android:layout_width="44dp" android:layout_height="44dp" android:layout_marginStart="12dp" - android:layout_marginTop="23dp" + android:layout_marginTop="8dp" android:padding="10dp" android:src="@drawable/back" app:layout_constraintLeft_toLeftOf="parent" @@ -78,9 +78,32 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_privacy.xml b/app/src/main/res/layout/activity_privacy.xml new file mode 100644 index 0000000..e8e7a14 --- /dev/null +++ b/app/src/main/res/layout/activity_privacy.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_welcome.xml b/app/src/main/res/layout/activity_welcome.xml index e7e73ce..814d111 100644 --- a/app/src/main/res/layout/activity_welcome.xml +++ b/app/src/main/res/layout/activity_welcome.xml @@ -28,4 +28,19 @@ android:textSize="18sp" app:layout_constraintTop_toBottomOf="@id/icon" /> + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 956a6de..5cb61bd 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -7,4 +7,8 @@ #cdd5d5 #80FFFFFF #80414548 + + #898989 + #B9F6F1 + #2fe7f3 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 17a5098..6341537 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -14,9 +14,12 @@ You haven not collected any wallpapers yet App Version V%s Rate App + Privacy Policy Consider giving us a review on the Google Play Store https://play.google.com/store/apps/details?id=%s An exception occurred. Please try again later. + Successfully collected! + Successfully canceled the collection! Wallpaper Animals @@ -27,4 +30,6 @@ Patterns Travel + + \ No newline at end of file diff --git a/app/src/test/java/com/wall/photography/wallpaper/ExampleUnitTest.kt b/app/src/test/java/com/wall/photography/wallpaper/ExampleUnitUtils.kt similarity index 92% rename from app/src/test/java/com/wall/photography/wallpaper/ExampleUnitTest.kt rename to app/src/test/java/com/wall/photography/wallpaper/ExampleUnitUtils.kt index 09b9baa..7af817a 100644 --- a/app/src/test/java/com/wall/photography/wallpaper/ExampleUnitTest.kt +++ b/app/src/test/java/com/wall/photography/wallpaper/ExampleUnitUtils.kt @@ -9,7 +9,7 @@ import org.junit.Assert.* * * See [testing documentation](http://d.android.com/tools/testing). */ -class ExampleUnitTest { +class ExampleUnitUtils { @Test fun addition_isCorrect() { assertEquals(4, 2 + 2) diff --git a/build.gradle.kts b/build.gradle.kts index 0aa79b8..110528c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,4 +3,6 @@ plugins { id("com.android.application") version "8.1.3" apply false id("org.jetbrains.kotlin.android") version "1.9.0" apply false kotlin("kapt") version "1.9.0" + id("com.google.gms.google-services") version "4.3.15" apply false + id ("com.google.firebase.crashlytics") version "2.9.2" apply false } \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 8238b4a..dfe9f75 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -10,6 +10,17 @@ dependencyResolutionManagement { repositories { google() mavenCentral() + //Anythink(Core) + maven("https://jfrog.anythinktech.com/artifactory/overseas_sdk") + //Ironsource + maven("https://android-sdk.is.com/") + //Mintegral + maven("https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea") + //Pangle + maven ( "https://artifact.bytedance.com/repository/pangle") + + //TopOn集成测试工具 + maven ( "https://jfrog.anythinktech.com/artifactory/debugger") } }