Commit 836775bb authored by wanglei's avatar wanglei

[新增]引导

parent 1ff3594e
......@@ -17,6 +17,12 @@
android:supportsRtl="true"
android:theme="@style/Theme.AppTheme"
tools:targetApi="31">
<activity
android:name=".ui.guide.GuideActivity"
android:exported="false" />
<activity
android:name=".ui.guide.GuideCleanActivity"
android:exported="false" />
<activity
android:name=".ui.splash.SplashActivity"
android:exported="true"
......@@ -29,14 +35,12 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.main.MainActivity"
android:exported="false"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
......
......@@ -9,7 +9,7 @@ import android.util.Log
import com.base.appzxhy.business.helper.EventUtils
import com.base.appzxhy.business.helper.InstallHelps
import com.base.appzxhy.business.helper.NewComUtils
import com.base.appzxhy.business.service.StayJobService.Companion.startJob
import com.base.appzxhy.business.service.StayJobService.Companion.startStayJobService
import com.base.appzxhy.utils.ActivityManagerUtils
import com.base.appzxhy.utils.AppPreferences
import com.base.appzxhy.utils.LogEx
......@@ -24,8 +24,8 @@ import com.reyun.solar.engine.SolarEngineManager
import org.json.JSONObject
import java.util.Locale
import java.util.UUID
import com.base.appzxhy.ConstObject.appLanguageSp
import com.base.appzxhy.ConstObject.appLanguageCountrySp
import com.base.appzxhy.SpConstObject.appLanguageSp
import com.base.appzxhy.SpConstObject.appLanguageCountrySp
import com.base.appzxhy.bean.config.AdConfigBean
import com.base.appzxhy.bean.config.ConfigBean
import com.base.appzxhy.bean.config.PopupConfigBean
......@@ -69,6 +69,11 @@ class MyApplication : Application() {
initUUid()
initGid()
initApp()
initLanguage()
}
private fun initLanguage() {
// 初始化语种切换框架
MultiLanguages.init(this)
......@@ -112,10 +117,10 @@ class MyApplication : Application() {
LogEx.logDebug(TAG, "uuid=${AppPreferences.getInstance().getString("uuid", "")}")
}
private fun initApp() {
fun initApp() {
kotlin.runCatching {
startJob()
startStayJobService()
}
//初始化广告相关业务
......@@ -150,7 +155,6 @@ class MyApplication : Application() {
appContext.initSolarEngine(true)
}
private fun initAppConfig() {
......
......@@ -3,17 +3,21 @@ package com.base.appzxhy
import com.base.appzxhy.utils.AppPreferences
import java.util.Locale
object ConstObject {
object SpConstObject {
var isGuided = false
var ifAgreePrivacy = false
get() {
return AppPreferences.getInstance().getBoolean("isGuided", field)
return AppPreferences.getInstance().getBoolean("ifAgreePrivacy", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("isGuided", value, true)
AppPreferences.getInstance().put("ifAgreePrivacy", value, true)
}
var isGuided
get() = AppPreferences.getInstance().getBoolean("isGuided", false)
set(value) = AppPreferences.getInstance().putBoolean("isGuided", value)
var appLanguageSp: String = Locale.getDefault().language
get() {
return AppPreferences.getInstance().getString("languageSp", field)
......
......@@ -7,16 +7,22 @@ import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import androidx.activity.ComponentActivity
import androidx.activity.SystemBarStyle
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.ColorInt
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityOptionsCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.viewbinding.ViewBinding
import com.base.appzxhy.ConstObject.appLanguageCountrySp
import com.base.appzxhy.ConstObject.appLanguageSp
import com.base.appzxhy.SpConstObject.appLanguageCountrySp
import com.base.appzxhy.SpConstObject.appLanguageSp
import com.base.appzxhy.R
import com.base.appzxhy.business.helper.EventUtils
import com.base.appzxhy.ui.main.MainActivity
......@@ -236,4 +242,13 @@ abstract class BaseActivity<VB : ViewBinding>(
}
fun goToAc(
clazz: Class<out Activity>,
options: ActivityOptionsCompat? = null,
activityResultCallback: ActivityResultCallback<ActivityResult>? = null
) {
launcher.launch(Intent(this, clazz), options, activityResultCallback)
}
}
......@@ -14,6 +14,7 @@ class AdConfigBean(
var timeInterval: Int = 1,//广告间隔
var openAdLoading: Int = 15,//开屏广告拉取时间
var fullNativeShow: Boolean = true,//显示全屏原生
var functionBackShowAd: Boolean = true,//功能退出显示广告
var functionInShowAd: Boolean = true,//功能进入显示广告
var rvEmptyShowNative: Boolean = true,//列表空的显示原生不
......
......@@ -89,6 +89,7 @@ object AdsMgr {
}
private fun initAdmob(context: Context) {
if (isAdmobInit) return
MobileAds.initialize(context) {
val readyAdapter = it.adapterStatusMap.entries.find { entry ->
entry.value.initializationState == AdapterStatus.State.READY
......@@ -109,7 +110,7 @@ object AdsMgr {
}
private fun initMax(context: Context) = kotlin.runCatching {
if (isMaxInit) return@runCatching
val executor = Executors.newSingleThreadExecutor()
executor.execute {
......
......@@ -56,7 +56,7 @@ object GoogleSubUtil {
val vipResult: MutableStateFlow<Boolean?> = MutableStateFlow(null)
/**
* 定义接状态
* 定义接状态
*/
val connectionResult = MutableStateFlow(false)
......
......@@ -2,6 +2,7 @@ package com.base.appzxhy.business.helper
import android.os.Build
import com.base.appzxhy.BuildConfig
import com.base.appzxhy.SpConstObject.ifAgreePrivacy
import com.base.appzxhy.GlobalConfig
import com.base.appzxhy.business.helper.ReportUtils.doPost
import com.base.appzxhy.utils.AppPreferences
......@@ -13,14 +14,6 @@ import java.util.TimeZone
object EventUtils {
private val TAG = "EventUtils"
var ifAgreePrivacy = true
get() {
return AppPreferences.getInstance().getBoolean("ifAgreePrivacy", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("ifAgreePrivacy", value, true)
}
fun event(
key: String,
......
......@@ -4,6 +4,7 @@ import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.drawable.Icon
import android.os.Build
import android.widget.RemoteViews
......@@ -13,6 +14,7 @@ import com.base.appzxhy.R
import com.base.appzxhy.bean.push.NotificationSendBean
import com.base.appzxhy.bean.push.NotificationSendBean.Companion.ACTION_ID_TEST
import com.base.appzxhy.bean.config.PopupConfigBean
import com.base.appzxhy.ui.splash.SplashActivity
import kotlin.random.Random
/**
......@@ -37,12 +39,12 @@ object NotificationUiUtil {
if (PopupConfigBean.popupConfigBean.isDifferNotificationId) {
sendBean.notificationId = Random.nextInt(1000, 2000)
}
// val intent = Intent(sendBean.context, SplashActivity::class.java)
val intent = Intent(sendBean.context, SplashActivity::class.java)
// val bean = sendBean.valueMap["bean"] as NotificationInfoBean
// intent.putExtra("actionId", sendBean.actionId)
intent.putExtra("actionId", sendBean.actionId)
// intent.putExtra("linkUrl", bean.linkUrl)
// intent.putExtra("notificationId", sendBean.notificationId)
// sendBean.intent = intent
sendBean.intent = intent
sendCustomNotification(sendBean)
return sendBean
}
......
......@@ -39,7 +39,7 @@ class StayJobService : JobService() {
private var startJobTime = 0L
private val minimumLatency = if (BuildConfig.DEBUG) 5000L else 5000L
fun Context.startJob() {
fun Context.startStayJobService() {
if (isRunning) return
LogEx.logDebug(TAG, "startJob")
startJobTime = System.currentTimeMillis()
......
package com.base.appzxhy.ui.guide
import NativeFullFragment
import android.content.Intent
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import com.base.appzxhy.base.BaseActivity
import com.base.appzxhy.bean.config.AdConfigBean
import com.base.appzxhy.databinding.ActivityGuideBinding
import com.base.appzxhy.ui.main.MainActivity
class GuideActivity : BaseActivity<ActivityGuideBinding>(ActivityGuideBinding::inflate) {
private val page1: GuideFragment by lazy {
GuideFragment().apply { page = 0 }
}
private val page2: GuideFragment by lazy {
GuideFragment().apply { page = 1 }
}
private val pageNative: NativeFullFragment by lazy {
NativeFullFragment()
}
private val page3: GuideFragment by lazy {
GuideFragment().apply { page = 3 }
}
private val fragments: MutableList<Fragment> by lazy {
mutableListOf(page1, page2, page3)
}
private var currentIndex = 0
override fun initView() {
super.initView()
if (AdConfigBean.adsConfigBean.fullNativeShow) {
fragments.add(2, pageNative)
}
binding.viewpager2.run {
offscreenPageLimit = 4
adapter = object : FragmentStateAdapter(this@GuideActivity) {
override fun getItemCount(): Int {
return fragments.size
}
override fun createFragment(position: Int): Fragment {
return fragments[position]
}
}
}
binding.viewpager2.registerOnPageChangeCallback(object :
ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
currentIndex = position
}
})
}
fun next(page: Int) {
if (page == 0) {
binding.viewpager2.currentItem = 1
return
}
if (page == 1) {
binding.viewpager2.currentItem = 2
return
}
if (page == 3) {
startActivity(Intent(this, MainActivity::class.java))
finish()
}
}
}
\ No newline at end of file
package com.base.appzxhy.ui.guide
import android.content.Intent
import androidx.activity.addCallback
import com.base.appzxhy.R
import com.base.appzxhy.base.BaseActivity
import com.base.appzxhy.business.ads.AdsMgr
import com.base.appzxhy.databinding.ActivityGuideCleanBinding
class GuideCleanActivity : BaseActivity<ActivityGuideCleanBinding>(ActivityGuideCleanBinding::inflate) {
override fun initView() {
super.initView()
}
override fun initListener() {
super.initListener()
changeNative()
binding.llPhoto.setOnClickListener {
binding.iv1.isSelected = !binding.iv1.isSelected
changeNative()
}
binding.llVideo.setOnClickListener {
binding.iv2.isSelected = !binding.iv2.isSelected
changeNative()
}
binding.llAudio.setOnClickListener {
binding.iv3.isSelected = !binding.iv3.isSelected
changeNative()
}
binding.llDocument.setOnClickListener {
binding.iv4.isSelected = !binding.iv4.isSelected
changeNative()
}
onBackPressedDispatcher.addCallback {
finishToMain()
}
binding.llContinue.setOnClickListener {
startActivity(Intent(this, GuideActivity::class.java))
finish()
}
}
private fun changeNative() {
AdsMgr.showNative(binding.flAd, R.layout.layout_admob_native_custom)
}
}
\ No newline at end of file
package com.base.appzxhy.ui.guide
import android.annotation.SuppressLint
import android.content.Intent
import com.base.appzxhy.R
import com.base.appzxhy.base.BaseFragment
import com.base.appzxhy.business.ads.AdsMgr
import com.base.appzxhy.databinding.FragmentGuideBinding
import com.base.appzxhy.ui.main.MainActivity
class GuideFragment : BaseFragment<FragmentGuideBinding>(FragmentGuideBinding::inflate) {
var page: Int = 1
@SuppressLint("SetTextI18n")
override fun initView() {
super.initView()
when (page) {
0 -> {
binding.iv.setImageResource(R.drawable.chahua04)
binding.ivDian.setImageResource(R.drawable.icon1)
binding.tvContent.text = "Clean up clutter to unlock more space and\n" +
"keep your phone running smoothly."
}
1 -> {
binding.iv.setImageResource(R.drawable.chahua03)
binding.ivDian.setImageResource(R.drawable.icon2)
binding.tvContent.text = "Quickly clear junk files and free up valuable\n" +
"storage with just a few taps."
}
3 -> {
binding.iv.setImageResource(R.drawable.chahua01)
binding.ivDian.setImageResource(R.drawable.icon4)
binding.tvContent.text = "Clean photos,videos,and audio files to\n" +
"save space and keep your phone tidy."
binding.tvBtn.text = "Start"
}
}
}
override fun initListener() {
super.initListener()
binding.tvSkip.setOnClickListener {
val activity = requireActivity() as GuideActivity?
activity?.startActivity(Intent(activity, MainActivity::class.java))
activity?.finish()
}
binding.tvBtn.setOnClickListener {
val activity = requireActivity() as GuideActivity?
activity ?: requireActivity()
activity?.next(page)
}
}
override fun onResume() {
super.onResume()
if (!binding.flAd.isAdShowed) {
AdsMgr.showNative(binding.flAd, R.layout.layout_admob_native_custom)
}
}
}
import com.base.appzxhy.R
import com.base.appzxhy.base.BaseFragment
import com.base.appzxhy.business.ads.AdsMgr
import com.base.appzxhy.databinding.FragmentNativeFullBinding
class NativeFullFragment : BaseFragment<FragmentNativeFullBinding>(FragmentNativeFullBinding::inflate) {
override fun onResume() {
super.onResume()
if (!binding.flAd.isAdShowed) {
AdsMgr.showNative(binding.flAd, R.layout.layout_admob_native_full)
}
}
}
\ No newline at end of file
package com.base.appzxhy.ui.splash
import android.Manifest
import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.text.Spannable
import android.text.SpannableString
import android.text.TextPaint
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.view.View
import androidx.activity.viewModels
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.base.appzxhy.SpConstObject.ifAgreePrivacy
import com.base.appzxhy.GlobalConfig.URL_PRIVACY
import com.base.appzxhy.MyApplication
import com.base.appzxhy.R
import com.base.appzxhy.SpConstObject.isGuided
import com.base.appzxhy.base.BaseActivity
import com.base.appzxhy.business.ads.AdsMgr
import com.base.appzxhy.business.ads.AdsShowCallBack
import com.base.appzxhy.business.helper.EventUtils
import com.base.appzxhy.business.service.StayJobService.Companion.startStayJobService
import com.base.appzxhy.databinding.ActivitySplashBinding
import com.base.appzxhy.ui.guide.GuideCleanActivity
import com.base.appzxhy.ui.main.MainActivity
import com.base.appzxhy.utils.UmpUtils
import java.util.concurrent.atomic.AtomicBoolean
@SuppressLint("CustomSplashScreen")
class SplashActivity : BaseActivity<ActivitySplashBinding>(ActivitySplashBinding::inflate) {
private val viewModel: SplashViewModel by viewModels()
override fun useDefaultImmersive() {
setStatusBarColor()
......@@ -21,7 +47,120 @@ class SplashActivity : BaseActivity<ActivitySplashBinding>(ActivitySplashBinding
}
override fun onCreate(savedInstanceState: Bundle?) {
initUMP()
super.onCreate(savedInstanceState)
}
override fun onResumeOneShoot() {
super.onResumeOneShoot()
viewModel.startCountdown()
}
override fun onStop() {
super.onStop()
viewModel.stopCountdown()
}
override fun initView() {
super.initView()
showLoadingAd()
setPrivacyPolicy()
requestNotificationPermission()
}
private fun setPrivacyPolicy() {
val privacyPolicy = getString(R.string.privacy_policy)
val text = "${getString(R.string.agree)} $privacyPolicy"
val spannableString = SpannableString(text)
val start = text.indexOf(privacyPolicy)
val end = start + privacyPolicy.length
val clickableSpan = object : ClickableSpan() {
override fun onClick(widget: View) {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(URL_PRIVACY)))
}
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = getColor(R.color.colorPrimary)
ds.bgColor = 0
}
}
spannableString.setSpan(clickableSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
binding.tvAgree.text = spannableString
binding.tvAgree.movementMethod = LinkMovementMethod.getInstance()
binding.tvAgree.highlightColor = Color.TRANSPARENT
}
private fun requestNotificationPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val array = arrayOf(Manifest.permission.POST_NOTIFICATIONS)
launcher.launch(array) { permissions ->
val flag = permissions.values.all { it }
if (flag) MyApplication.appContext.startStayJobService()
}
}
}
override fun initListener() {
super.initListener()
binding.tvStart.setOnClickListener {
ifAgreePrivacy = true
showLoadingAd()
EventUtils.event("app_start")
EventUtils.event("page_${javaClass.simpleName}")
viewModel.startCountdown()
MyApplication.appContext.initApp()
}
}
private fun initUMP() {
val ump = UmpUtils(this)
if (ump.consentInformation.canRequestAds()) {
AdsMgr.init(this)
} else {
ump.callback = {
AdsMgr.init(this)
}
ump.requestUMP()
}
}
private fun showLoadingAd() {
binding.clBottomStart.visibility = if (ifAgreePrivacy) View.GONE else View.VISIBLE
binding.clBottomLoading.visibility = if (ifAgreePrivacy) View.VISIBLE else View.GONE
binding.llConsent.visibility = if (ifAgreePrivacy) View.GONE else View.VISIBLE
if (ifAgreePrivacy) {
AdsMgr.showOpen(this, showCallBack = object : AdsShowCallBack() {
override fun show() {
viewModel.stopCountdown()
}
override fun next() {
binding.root.postDelayed({ jumpNext() }, 200)
}
})
}
}
val jumped = AtomicBoolean(false)
fun jumpNext() {
if (jumped.get()) return
jumped.set(true)
if (!isGuided) {
isGuided = true
goToAc(GuideCleanActivity::class.java)
} else {
goToAc(MainActivity::class.java)
}
finish()
intent.extras?.clear()
}
}
\ No newline at end of file
package com.base.appzxhy.ui.splash
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.base.appzxhy.SpConstObject.ifAgreePrivacy
import com.base.appzxhy.bean.config.AdConfigBean
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlin.random.Random
class SplashViewModel: ViewModel() {
class SplashViewModel : ViewModel() {
private var countdownJob: Job? = null
private var startTime: Long = 0
val totalTimeMs = AdConfigBean.adsConfigBean.openAdLoading * 1000L // 倒计时总时长
private val checkIntervalMs = 100L // 检查间隔(100毫秒)
var jumpNext: (() -> Unit)? = null
var onTick: ((sLong: Long, total: Long) -> Unit)? = null
fun startCountdown() {
if (!ifAgreePrivacy) return
countdownJob?.cancel()
startTime = System.currentTimeMillis()
countdownJob = viewModelScope.launch(Dispatchers.IO) {
while (isActive) {
val currentTime = System.currentTimeMillis()
val elapsed = currentTime - startTime
val remaining = totalTimeMs - elapsed
if (remaining <= 0) {
launch(Dispatchers.Main) {
onTick?.invoke(totalTimeMs, totalTimeMs)
}
break
} else {
launch(Dispatchers.Main) {
onTick?.invoke(elapsed, totalTimeMs)
}
}
delay(Random.nextLong(checkIntervalMs, checkIntervalMs + 100L))
}
launch(Dispatchers.Main) {
jumpNext?.invoke()
}
}
}
/**
* 停止倒计时(可选,便于资源释放)
*/
fun stopCountdown() {
countdownJob?.cancel()
countdownJob = null
}
}
......@@ -5,6 +5,7 @@ import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.ActivityResultCaller
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityOptionsCompat
class ActivityLauncher(activityResultCaller: ActivityResultCaller) {
......@@ -37,10 +38,11 @@ class ActivityLauncher(activityResultCaller: ActivityResultCaller) {
*/
fun launch(
intent: Intent,
options: ActivityOptionsCompat? = null,
activityResultCallback: ActivityResultCallback<ActivityResult>? = null
) {
this.activityResultCallback = activityResultCallback
intentLauncher.launch(intent)
intentLauncher.launch(intent, options)
}
//endregion
......
package com.base.appzxhy.utils
import android.app.Activity
import android.content.Context
import com.base.appzxhy.BuildConfig
import com.google.android.ump.ConsentDebugSettings
import com.google.android.ump.ConsentForm
import com.google.android.ump.ConsentInformation
import com.google.android.ump.ConsentRequestParameters
import com.google.android.ump.FormError
import com.google.android.ump.UserMessagingPlatform
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
var umpCanAd = true
get() {
return AppPreferences.getInstance().getBoolean("umpCanAd", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("umpCanAd", value, true)
}
var umpCalled = false
get() {
return AppPreferences.getInstance().getBoolean("umpCalled", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("umpCalled", value, true)
}
class UmpUtils(
val activity: Activity
) {
private fun Context.umpTest(): ConsentDebugSettings {
val debugSettings = ConsentDebugSettings.Builder(this)
debugSettings.setDebugGeography(ConsentDebugSettings.DebugGeography.DEBUG_GEOGRAPHY_EEA)
//通过TEST-DEVICE-HASHED-ID log过滤ConsentDebugSettings 打印测试id,使用测试id来测试
// debugSettings.addTestDeviceHashedId("TEST-DEVICE-HASHED-ID")
debugSettings.addTestDeviceHashedId("73FE7C2634104D50A11BE9B902AA0FA6")
return debugSettings.build()
}
var callback: ((canAd: Boolean) -> Unit)? = null
private val TAG = "UmpUtils"
val consentInformation: ConsentInformation = UserMessagingPlatform.getConsentInformation(activity)
fun requestUMP() {
val paramsBuild = ConsentRequestParameters.Builder()
if (BuildConfig.DEBUG) {
paramsBuild.setConsentDebugSettings(activity.umpTest())
}
// 指示用户是否低于同意年龄; true 低于同意年龄
// 未满同意年龄的用户不会收到 GDPR 消息表单
paramsBuild.setTagForUnderAgeOfConsent(false)
val params = paramsBuild.build()
if (BuildConfig.DEBUG) {
consentInformation.reset()
}
val updateSuccessListener = ConsentInformation.OnConsentInfoUpdateSuccessListener {
LogEx.logDebug(TAG, "isConsentFormAvailable=${consentInformation.isConsentFormAvailable}")
if (consentInformation.isConsentFormAvailable) {
MainScope().launch(Dispatchers.Main) {
delay(500)
loadAndShowConsentFormIfRequired(activity, consentInformation)
}
} else {
callback?.invoke(true)
callback = null
}
}
val updateFailureListener = ConsentInformation.OnConsentInfoUpdateFailureListener {
LogEx.logDebug(TAG, "message=${it.message} errorCode=${it.errorCode}")
callback?.invoke(true)
callback = null
}
consentInformation.requestConsentInfoUpdate(activity, params, updateSuccessListener, updateFailureListener)
}
private fun loadAndShowConsentFormIfRequired(activity: Activity, consentInformation: ConsentInformation) {
UserMessagingPlatform.loadConsentForm(
activity,
object : UserMessagingPlatform.OnConsentFormLoadSuccessListener {
override fun onConsentFormLoadSuccess(consentForm: ConsentForm) {
LogEx.logDebug(TAG, "onConsentFormLoadSuccess")
consentForm.show(activity) {
callback?.invoke(consentInformation.canRequestAds())
callback = null
}
}
},
object : UserMessagingPlatform.OnConsentFormLoadFailureListener {
override fun onConsentFormLoadFailure(p0: FormError) {
//https://groups.google.com/g/google-admob-ads-sdk/c/x-fyDOfMSqU/m/MeZX3mO4AAAJ
LogEx.logDebug(TAG, "onConsentFormLoadFailure ${p0.message} ${p0.errorCode}")
callback?.invoke(true)
callback = null
}
})
// UserMessagingPlatform.loadAndShowConsentFormIfRequired(activity) { loadAndShowError: FormError? ->
// LogEx.logDebug(
// TAG,
// "loadAndShowConsentFormIfRequired message=${loadAndShowError?.message} errorCode=${loadAndShowError?.errorCode}"
// )
// if (loadAndShowError != null) {
// callback?.invoke(false)
// callback = null
// } else {
// callback?.invoke(consentInformation.canRequestAds())
// callback = null
// }
// }
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/colorPrimary" />
<corners android:radius="50dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#F6FBFF" />
<corners android:radius="10dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/icon_yuan_s" android:state_selected="true" />
<item android:drawable="@drawable/icon_yuan_n" android:state_selected="false" />
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.guide.GuideActivity">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewpager2"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="35dp"
android:layout_marginTop="56dp"
android:gravity="center"
android:text="Which type do you want to clean?"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<LinearLayout
android:id="@+id/ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@id/tv">
<LinearLayout
android:id="@+id/llPhoto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginVertical="4dp"
android:background="@drawable/bg_f6fbff_10"
android:foreground="?attr/selectableItemBackground"
android:orientation="horizontal">
<ImageView
android:layout_width="@dimen/dp_50"
android:layout_height="@dimen/dp_50"
android:layout_gravity="center_vertical"
android:layout_marginVertical="12dp"
android:layout_marginStart="20dp"
android:src="@drawable/icon04"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="25dp"
android:layout_weight="1"
android:text="@string/photo"
android:textColor="#111111"
android:textSize="20sp"
android:textStyle="bold" />
<ImageView
android:id="@+id/iv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="20dp"
android:background="@drawable/bg_select_yuan"
tools:ignore="ContentDescription" />
</LinearLayout>
<LinearLayout
android:id="@+id/llVideo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginVertical="4dp"
android:background="@drawable/bg_f6fbff_10"
android:foreground="?attr/selectableItemBackground"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="@dimen/dp_50"
android:layout_height="@dimen/dp_50"
android:layout_gravity="center_vertical"
android:layout_marginVertical="12dp"
android:layout_marginStart="20dp"
android:src="@drawable/icon03" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="25dp"
android:layout_weight="1"
android:text="@string/video"
android:textColor="#111111"
android:textSize="20sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="20dp"
android:background="@drawable/bg_select_yuan" />
</LinearLayout>
<LinearLayout
android:id="@+id/llAudio"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginVertical="4dp"
android:background="@drawable/bg_f6fbff_10"
android:foreground="?attr/selectableItemBackground"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginVertical="12dp"
android:layout_marginStart="20dp"
android:src="@drawable/icon02" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="25dp"
android:layout_weight="1"
android:text="@string/audio"
android:textColor="#111111"
android:textSize="20sp"
android:textStyle="bold" />
<ImageView
android:id="@+id/iv3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="20dp"
android:background="@drawable/bg_select_yuan" />
</LinearLayout>
<LinearLayout
android:id="@+id/llDocument"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginVertical="4dp"
android:background="@drawable/bg_f6fbff_10"
android:foreground="?attr/selectableItemBackground"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginVertical="12dp"
android:layout_marginStart="20dp"
android:src="@drawable/icon01" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="25dp"
android:layout_weight="1"
android:text="@string/document"
android:textColor="#111111"
android:textSize="20sp"
android:textStyle="bold" />
<ImageView
android:id="@+id/iv4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="20dp"
android:background="@drawable/bg_select_yuan" />
</LinearLayout>
</LinearLayout>
<FrameLayout
android:id="@+id/llContinue"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:background="@drawable/bg_splash_button"
android:orientation="horizontal"
android:padding="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/ll">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/continue_"
android:textColor="#ffffff"
android:textSize="17sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="@dimen/dp_30"
android:layout_height="@dimen/dp_30"
android:layout_gravity="center_vertical|end"
android:src="@drawable/du" />
</FrameLayout>
<com.base.appzxhy.business.ads.NativeParentView
android:id="@+id/flAd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="80dp"
app:layout_constraintBottom_toBottomOf="parent">
<io.supercharge.shimmerlayout.ShimmerLayout
android:id="@+id/shimmerLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:layout_marginHorizontal="16dp"
android:layout_marginVertical="10dp"
app:shimmer_angle="25"
app:shimmer_animation_duration="2000"
app:shimmer_auto_start="true"
app:shimmer_color="#33ffffff"
app:shimmer_mask_width="0.2">
<ImageView
android:layout_width="match_parent"
android:layout_height="@dimen/dp_80"
android:background="@drawable/zhanwei1"
tools:ignore="ContentDescription,ImageContrastCheck" />
</io.supercharge.shimmerlayout.ShimmerLayout>
</com.base.appzxhy.business.ads.NativeParentView>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
......@@ -96,7 +96,7 @@
app:layout_constraintBottom_toBottomOf="parent">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_start"
android:id="@+id/tvStart"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="36dp"
......@@ -121,7 +121,7 @@
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_start"
app:layout_constraintTop_toBottomOf="@id/tvStart"
tools:ignore="TextContrastCheck" />
</androidx.constraintlayout.widget.ConstraintLayout>
......
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF">
<TextView
android:id="@+id/tvSkip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:layout_marginEnd="20dp"
android:text="Skip"
android:textColor="#B6B6B6"
android:textSize="16sp"
android:visibility="visible"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<ImageView
android:id="@+id/iv"
android:layout_width="@dimen/dp_300"
android:layout_height="@dimen/dp_300"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3"
tools:ignore="ContentDescription"
tools:src="@drawable/chahua01" />
<TextView
android:id="@+id/tvContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:layout_marginTop="18dp"
android:gravity="center"
android:text="Clean up clutter to unlock more space and keep your phone running smoothly."
android:textColor="#000000"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/iv"
tools:ignore="HardcodedText" />
<ImageView
android:id="@+id/ivDian"
android:layout_width="@dimen/dp_50"
android:layout_height="@dimen/dp_10"
android:layout_marginTop="25dp"
android:src="@drawable/icon1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvContent"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/tv_btn"
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_marginHorizontal="80dp"
android:layout_marginTop="24dp"
android:layout_marginBottom="28dp"
android:background="@drawable/bg_splash_button"
android:gravity="center"
android:text="Next"
android:textColor="@color/white"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/ivDian"
tools:ignore="HardcodedText,MissingConstraints" />
<com.base.appzxhy.business.ads.NativeParentView
android:id="@+id/flAd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#D9D9D9"
android:minHeight="75dp"
app:layout_constraintBottom_toBottomOf="parent">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/zhanwei1"
tools:ignore="ImageContrastCheck,ImageContrastCheck" />
</com.base.appzxhy.business.ads.NativeParentView>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#D9D9D9">
<com.base.appzxhy.business.ads.NativeParentView
android:id="@+id/flAd"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="@drawable/ad_full" />
</com.base.appzxhy.business.ads.NativeParentView>
</FrameLayout>
\ No newline at end of file
......@@ -38,16 +38,16 @@
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="#FF923E"
android:background="@color/colorPrimary"
android:padding="2dp"
android:text="Ad"
android:textColor="@color/white"
......@@ -56,12 +56,13 @@
<TextView
android:id="@+id/ad_body"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="10dp"
android:ellipsize="end"
android:maxLines="2"
android:singleLine="true"
android:textColor="@color/black"
android:textSize="12sp" />
......@@ -86,7 +87,7 @@
android:layout_height="26dp"
android:layout_gravity="center_vertical"
android:layout_marginHorizontal="12dp"
android:background="@drawable/bg_ff8a00_10"
android:background="@drawable/bg_btn_ad"
android:gravity="center"
android:textColor="@color/white"
android:textSize="15sp"
......
<com.google.android.gms.ads.nativead.NativeAdView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="@color/white"
android:baselineAligned="false"
android:orientation="vertical">
<com.google.android.gms.ads.nativead.MediaView
android:id="@+id/ad_media"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="center_horizontal"
android:layout_marginHorizontal="@dimen/dp_16"
android:layout_weight="1" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/dp_15"
android:gravity="center_vertical">
<ImageView
android:id="@+id/ad_app_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/ad_headline"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/dp_2"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="2"
android:textColor="@color/black"
android:textSize="@dimen/sp_16"
android:textStyle="bold"
tools:text="Ad Headline" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="@color/colorPrimary"
android:padding="2dp"
android:text="Ad"
android:textColor="@color/white"
android:textSize="12sp"
tools:ignore="HardcodedText,TextContrastCheck" />
</LinearLayout>
<TextView
android:id="@+id/ad_body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/dp_15"
android:ellipsize="end"
android:maxLines="2"
android:textColor="#808080"
android:textSize="@dimen/sp_12"
tools:text="Earn more from your apps. Get started and sign up for AdMob today." />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/ad_call_to_action"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_40"
android:layout_gravity="center_vertical"
android:layout_marginHorizontal="@dimen/dp_15"
android:layout_marginTop="@dimen/dp_8"
android:layout_marginBottom="@dimen/dp_20"
android:background="@drawable/bg_btn_ad"
android:gravity="center"
android:textColor="@color/white"
android:textSize="15sp"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView>
\ No newline at end of file
......@@ -2,6 +2,8 @@
<resources>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="colorPrimary">#3e7bf7</color>
<color name="color_8b8b8b">#8B8B8B</color>
......
......@@ -4,4 +4,14 @@
<dimen name="dp_150">150dp</dimen>
<dimen name="dp_40">40dp</dimen>
<dimen name="dp_20">20dp</dimen>
<dimen name="dp_50">50dp</dimen>
<dimen name="dp_30">30dp</dimen>
<dimen name="dp_80">80dp</dimen>
<dimen name="dp_10">10dp</dimen>
<dimen name="dp_16">16dp</dimen>
<dimen name="dp_15">15dp</dimen>
<dimen name="dp_2">2dp</dimen>
<dimen name="sp_16">16sp</dimen>
<dimen name="sp_12">12sp</dimen>
<dimen name="dp_8">8dp</dimen>
</resources>
\ No newline at end of file
......@@ -13,5 +13,13 @@ Please rest assured that we will handle your information in strict accordance wi
</string>
<string name="start">Start</string>
<string name="agree">By continuing you are agreeing to the</string>
<string name="privacy_policy">Privacy Policy</string>
<string name="photo">Photo</string>
<string name="audio">Audio</string>
<string name="document">Document</string>
<string name="video">Video</string>
<string name="continue_">Continue</string>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
</resources>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment