Commit 9ce17b16 authored by wanglei's avatar wanglei

...

parent a3745b91
...@@ -5,7 +5,7 @@ package com.base.scanqr ...@@ -5,7 +5,7 @@ package com.base.scanqr
*/ */
object GlobalConfig { object GlobalConfig {
//包名 //包名
const val PACKAGE_NAME = "com.loactation.alibabab.ccccaa" const val PACKAGE_NAME = "com.scan.barcode.deeplink"
// 域名 // 域名
/** /**
...@@ -21,17 +21,17 @@ object GlobalConfig { ...@@ -21,17 +21,17 @@ object GlobalConfig {
/** /**
* Url Privacy 隐私链接 * Url Privacy 隐私链接
*/ */
const val URL_PRIVACY = "https://sites.google.com/view/locationuses/location" const val URL_PRIVACY = "https://sites.google.com/view/scan-qr-code-barcode-reader/scan-qr-code-barcode-reader"
/** /**
* Url Use 使用条款 * Url Use 使用条款
*/ */
const val URL_USE = "" const val URL_USE = "https://sites.google.com/view/termsofscanqr/terms-of-scan-qr"
/** /**
* Key Aes 加密key * Key Aes 加密key
*/ */
const val KEY_AES = "pex50vwzuhpim3yh" const val KEY_AES = "o3yb8vzeptlki1ve"
/** /**
* Key solar 归因key * Key solar 归因key
......
...@@ -3,20 +3,36 @@ package com.base.scanqr ...@@ -3,20 +3,36 @@ package com.base.scanqr
import android.app.Activity import android.app.Activity
import android.app.Application import android.app.Application
import android.content.Context import android.content.Context
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import com.base.scanqr.ads.AdsMgr import com.base.scanqr.ads.AdsMgr
import com.base.scanqr.bean.ConstObject.appLanguageCountrySp import com.base.scanqr.bean.ConstObject.appLanguageCountrySp
import com.base.scanqr.bean.ConstObject.appLanguageSp import com.base.scanqr.bean.ConstObject.appLanguageSp
import com.base.scanqr.bean.config.AdConfigBean
import com.base.scanqr.bean.config.ConfigBean
import com.base.scanqr.bean.config.PopupConfigBean
import com.base.scanqr.fcm.FCMManager import com.base.scanqr.fcm.FCMManager
import com.base.scanqr.fcm.TimerManager.Companion.changeTimer
import com.base.scanqr.fcm.receiver.BatteryStatusReceiver
import com.base.scanqr.fcm.receiver.PackageStatusReceiver
import com.base.scanqr.fcm.receiver.ScreenStatusReceiver
import com.base.scanqr.helper.EventUtils
import com.base.scanqr.helper.InstallHelps
import com.base.scanqr.helper.NewComUtils
import com.base.scanqr.ui.start.StartActivity
import com.base.scanqr.utils.ActivityManagerUtils import com.base.scanqr.utils.ActivityManagerUtils
import com.base.scanqr.utils.AppPreferences import com.base.scanqr.utils.AppPreferences
import com.base.scanqr.utils.LogEx import com.base.scanqr.utils.LogEx
import com.base.scanqr.utils.SolarEngineUtils.solarkey
import com.facebook.FacebookSdk import com.facebook.FacebookSdk
import com.google.android.gms.ads.identifier.AdvertisingIdClient import com.google.android.gms.ads.identifier.AdvertisingIdClient
import com.google.gson.Gson
import com.hjq.language.MultiLanguages import com.hjq.language.MultiLanguages
import com.hjq.language.OnLanguageListener import com.hjq.language.OnLanguageListener
import com.reyun.solar.engine.SolarEngineManager
import org.json.JSONObject
import java.util.Locale import java.util.Locale
import java.util.UUID import java.util.UUID
...@@ -102,21 +118,23 @@ class MyApplication : Application() { ...@@ -102,21 +118,23 @@ class MyApplication : Application() {
FCMManager.initFirebase(this) FCMManager.initFirebase(this)
FCMManager.subscribeToTopic(topic) FCMManager.subscribeToTopic(topic)
// initConfig() initConfig()
//
// Thread {
// InstallHelps.init {
// initRemoteConfig()
// }
// }.start()
// SolarEngineManager.getInstance().preInit(this, solarkey) Thread {
InstallHelps.init {
initRemoteConfig()
}
// val json = Gson().toJson(ConfigBean())
// LogEx.logDebug(TAG, "json=$json")
}.start()
SolarEngineManager.getInstance().preInit(this, solarkey)
initLifeListener() initLifeListener()
// ScreenStatusReceiver.registerScreenStatusReceiver(this) ScreenStatusReceiver.registerScreenStatusReceiver(this)
// PackageStatusReceiver.registerPackageStatusReceiver(this) PackageStatusReceiver.registerPackageStatusReceiver(this)
// BatteryStatusReceiver.registerBatteryStatusReceiver(this) BatteryStatusReceiver.registerBatteryStatusReceiver(this)
// startJob() // startJob()
// startAlarm(appContext, 24) // startAlarm(appContext, 24)
...@@ -157,13 +175,13 @@ class MyApplication : Application() { ...@@ -157,13 +175,13 @@ class MyApplication : Application() {
LogEx.logDebug(TAG, "flag=$flag" + " activity:" + activity.localClassName) LogEx.logDebug(TAG, "flag=$flag" + " activity:" + activity.localClassName)
if (flag) { if (flag) {
// topActivity?.startActivity( topActivity?.startActivity(
// Intent( Intent(
// topActivity, SplashActivity::class.java topActivity, StartActivity::class.java
// ).apply { ).apply {
// putExtra("isHotLaunch", true) putExtra("isHotLaunch", true)
// putExtra("type", -1) putExtra("type", -1)
// }) })
} }
} }
lastTimeResume = 0 lastTimeResume = 0
...@@ -192,42 +210,44 @@ class MyApplication : Application() { ...@@ -192,42 +210,44 @@ class MyApplication : Application() {
} }
private fun initRemoteConfig() { private fun initRemoteConfig() {
LogEx.logDebug(TAG, "initRemoteConfig")
NewComUtils.requestCfg { config ->
if (config != null) {
AppPreferences.getInstance().put("config", config)
}
LogEx.logDebug("requestCfg", "config=$config")
// NewComUtils.requestCfg { config -> initConfig(config)
// if (config != null) { }
// AppPreferences.getInstance().put("config", config)
// }
//
// LogEx.logDebug("requestCfg", "config=$config")
//
// initConfig(config)
// }
} }
private fun initConfig(config: String? = AppPreferences.getInstance().getString("config", "")) { private fun initConfig(config: String? = AppPreferences.getInstance().getString("config", "")) {
// kotlin.runCatching { kotlin.runCatching {
// val configBean = Gson().fromJson(config, com.base.scanqr.bean.config.ConfigBean::class.java) val configBean = Gson().fromJson(config, ConfigBean::class.java)
//
// val jsonObject = JSONObject() val jsonObject = JSONObject()
// jsonObject.put("ut", configBean.ut) jsonObject.put("ut", configBean.ut)
// EventUtils.event("user_type", ext = jsonObject) EventUtils.event("user_type", ext = jsonObject)
// LogEx.logDebug("initConfig", "ut=${configBean.ut}")
// //配置
// com.base.scanqr.bean.config.ConfigBean.configBean = configBean //配置
// ConfigBean.configBean = configBean
// //广告
// com.base.scanqr.ads.AdsMgr.adsConfigBean = configBean.adConfigBean //广告
// com.base.localweatherwhite.utils.LogEx.logDebug("initConfig", "com.base.scanqr.ads.AdsMgr.adsConfigBean=${configBean.adConfigBean.functionInShowAd}") AdConfigBean.adsConfigBean = configBean.adConfigBean
// LogEx.logDebug("initConfig", "adsConfigBean=${AdConfigBean.adsConfigBean.functionInShowAd}")
// //通知
// PopupConstObject.popupConfigBean = configBean.popupConfigBean //通知
// PopupConfigBean.popupConfigBean = configBean.popupConfigBean
// //启动定时器 LogEx.logDebug("initConfig", "popupConfigBean=${PopupConfigBean.popupConfigBean.popupCount}")
// changeTimer()
// } //启动定时器
changeTimer()
}
} }
......
...@@ -73,11 +73,6 @@ object AdsMgr { ...@@ -73,11 +73,6 @@ object AdsMgr {
var isMaxInit = false var isMaxInit = false
private set private set
/**
* 广告配置项目
*/
var adsConfigBean: AdConfigBean = AdConfigBean()
/** /**
* Init 初始化 * Init 初始化
...@@ -104,7 +99,7 @@ object AdsMgr { ...@@ -104,7 +99,7 @@ object AdsMgr {
EventUtils.event("AdmobInit", "AdmobInit") EventUtils.event("AdmobInit", "AdmobInit")
// context.toast("admob init") // context.toast("admob init")
if (adsConfigBean.adSwitch) { if (AdConfigBean.adsConfigBean.adSwitch) {
admobInitCallBack?.invoke() admobInitCallBack?.invoke()
admobInitCallBack = null admobInitCallBack = null
adOpenMgr.loadAd(context, false, AdmobEvent("openAd", context::class.java.simpleName)) adOpenMgr.loadAd(context, false, AdmobEvent("openAd", context::class.java.simpleName))
...@@ -134,7 +129,7 @@ object AdsMgr { ...@@ -134,7 +129,7 @@ object AdsMgr {
AppLovinSdk.getInstance(context).initialize(initConfig) { AppLovinSdk.getInstance(context).initialize(initConfig) {
isMaxInit = true isMaxInit = true
// maxOpenMgr.loadAd(context) // maxOpenMgr.loadAd(context)
if (!adsConfigBean.adSwitch) { if (!AdConfigBean.adsConfigBean.adSwitch) {
maxInsertMgr.loadAd(context, false, AdMaxEvent("interAd", context::class.java.simpleName)) maxInsertMgr.loadAd(context, false, AdMaxEvent("interAd", context::class.java.simpleName))
context.toast("max init") context.toast("max init")
maxInitCallBack?.invoke() maxInitCallBack?.invoke()
...@@ -169,7 +164,7 @@ object AdsMgr { ...@@ -169,7 +164,7 @@ object AdsMgr {
} }
val from = activity::class.java.simpleName val from = activity::class.java.simpleName
if (adsConfigBean.adSwitch) { if (AdConfigBean.adsConfigBean.adSwitch) {
if (isAdmobInit) { if (isAdmobInit) {
adOpenMgr.show(activity, isUnLimit, AdmobEvent("openAd", from), showCallBack) adOpenMgr.show(activity, isUnLimit, AdmobEvent("openAd", from), showCallBack)
} else { } else {
...@@ -205,9 +200,9 @@ object AdsMgr { ...@@ -205,9 +200,9 @@ object AdsMgr {
EventUtils.event("isInBlackList", configBean.isInBlackList.toString()) EventUtils.event("isInBlackList", configBean.isInBlackList.toString())
return return
} }
LogEx.logDebug("showAd", "adSwitch=${adsConfigBean.adSwitch}") LogEx.logDebug("showAd", "adSwitch=${AdConfigBean.adsConfigBean.adSwitch}")
val from = activity::class.java.simpleName val from = activity::class.java.simpleName
if (adsConfigBean.adSwitch) { if (AdConfigBean.adsConfigBean.adSwitch) {
adInsertMgr.show(activity, isUnLimit, AdmobEvent("interAd", from), showCallBack) adInsertMgr.show(activity, isUnLimit, AdmobEvent("interAd", from), showCallBack)
} else { } else {
maxInsertMgr.show(activity, isUnLimit, AdMaxEvent("interAd", from), showCallBack) maxInsertMgr.show(activity, isUnLimit, AdMaxEvent("interAd", from), showCallBack)
...@@ -233,14 +228,14 @@ object AdsMgr { ...@@ -233,14 +228,14 @@ object AdsMgr {
if (!isAdmobInit) return if (!isAdmobInit) return
if (adsConfigBean.adSwitch) { if (AdConfigBean.adsConfigBean.adSwitch) {
adNativeMgr.show(AdmobEvent("nativeAd", "nativeAd"), nativeView, layout, nativeCallBack) adNativeMgr.show(AdmobEvent("nativeAd", "nativeAd"), nativeView, layout, nativeCallBack)
} else { } else {
maxNativeMgr.show(AdMaxEvent("nativeAd", "nativeAd"), nativeView, layout, nativeCallBack) maxNativeMgr.show(AdMaxEvent("nativeAd", "nativeAd"), nativeView, layout, nativeCallBack)
} }
} }
fun isNativeShow() = LimitUtils.isAdShow(AdsType.NATIVE, null) fun isNativeShow() = LimitUtils.isAdShow(AdsType.NATIVE, null)
/** /**
* 展示banner广告 * 展示banner广告
...@@ -252,7 +247,7 @@ object AdsMgr { ...@@ -252,7 +247,7 @@ object AdsMgr {
EventUtils.event("isInBlackList", configBean.isInBlackList.toString()) EventUtils.event("isInBlackList", configBean.isInBlackList.toString())
return return
} }
if (adsConfigBean.adSwitch) { if (AdConfigBean.adsConfigBean.adSwitch) {
adBannerMgr.show(parent, collapsible, adClose) adBannerMgr.show(parent, collapsible, adClose)
} }
} }
......
package com.base.scanqr.ads package com.base.scanqr.ads
import com.base.scanqr.bean.config.AdConfigBean
import com.base.scanqr.utils.AppPreferences import com.base.scanqr.utils.AppPreferences
import com.base.scanqr.utils.KotlinExt.toFormatTime4 import com.base.scanqr.utils.KotlinExt.toFormatTime4
...@@ -31,7 +32,7 @@ object LimitUtils { ...@@ -31,7 +32,7 @@ object LimitUtils {
*/ */
private inline val isRequestLimited: Boolean private inline val isRequestLimited: Boolean
get() { get() {
val maxCount = AdsMgr.adsConfigBean.numRequestLimit val maxCount = AdConfigBean.adsConfigBean.numRequestLimit
return maxCount > -1 && AppPreferences.getInstance() return maxCount > -1 && AppPreferences.getInstance()
.getInt(NUM_REQUEST, 0) >= maxCount .getInt(NUM_REQUEST, 0) >= maxCount
} }
...@@ -41,7 +42,7 @@ object LimitUtils { ...@@ -41,7 +42,7 @@ object LimitUtils {
*/ */
private inline val isDisplayLimited: Boolean private inline val isDisplayLimited: Boolean
get() { get() {
val maxCount = AdsMgr.adsConfigBean.numDisplayLimit val maxCount = AdConfigBean.adsConfigBean.numDisplayLimit
return maxCount > -1 && AppPreferences.getInstance() return maxCount > -1 && AppPreferences.getInstance()
.getInt(NUM_DISPLAY, 0) >= maxCount .getInt(NUM_DISPLAY, 0) >= maxCount
} }
...@@ -51,7 +52,7 @@ object LimitUtils { ...@@ -51,7 +52,7 @@ object LimitUtils {
*/ */
private inline val isClickLimited: Boolean private inline val isClickLimited: Boolean
get() { get() {
val maxCount = AdsMgr.adsConfigBean.numClickLimit val maxCount = AdConfigBean.adsConfigBean.numClickLimit
return maxCount > -1 && AppPreferences.getInstance() return maxCount > -1 && AppPreferences.getInstance()
.getInt(NUM_CLICK, 0) >= maxCount .getInt(NUM_CLICK, 0) >= maxCount
} }
...@@ -84,21 +85,21 @@ object LimitUtils { ...@@ -84,21 +85,21 @@ object LimitUtils {
val value = "current${getAdEventMsg(adsType)} " + val value = "current${getAdEventMsg(adsType)} " +
"show=${AppPreferences.getInstance().getInt(NUM_DISPLAY, 0)} " + "show=${AppPreferences.getInstance().getInt(NUM_DISPLAY, 0)} " +
"${getAdEventMsg(adsType).lowercase()}_" + "max_show=${AdsMgr.adsConfigBean.numDisplayLimit}" "${getAdEventMsg(adsType).lowercase()}_" + "max_show=${AdConfigBean.adsConfigBean.numDisplayLimit}"
adEvent?.adLimited(value) adEvent?.adLimited(value)
} }
if (isClickLimited) { if (isClickLimited) {
val value = val value =
"current${getAdEventMsg(adsType)}Click=${AppPreferences.getInstance().getInt(NUM_CLICK, 0)} " "current${getAdEventMsg(adsType)}Click=${AppPreferences.getInstance().getInt(NUM_CLICK, 0)} "
"${getAdEventMsg(adsType).lowercase()}_max_click=${AdsMgr.adsConfigBean.numClickLimit}" "${getAdEventMsg(adsType).lowercase()}_max_click=${AdConfigBean.adsConfigBean.numClickLimit}"
adEvent?.adLimited(value) adEvent?.adLimited(value)
} }
if (isRequestLimited) { if (isRequestLimited) {
val value = "current${getAdEventMsg(adsType)}Request=${AppPreferences.getInstance().getInt(NUM_REQUEST, 0)} " + val value = "current${getAdEventMsg(adsType)}Request=${AppPreferences.getInstance().getInt(NUM_REQUEST, 0)} " +
"${getAdEventMsg(adsType).lowercase()}_max_request=${AdsMgr.adsConfigBean.numRequestLimit}" "${getAdEventMsg(adsType).lowercase()}_max_request=${AdConfigBean.adsConfigBean.numRequestLimit}"
adEvent?.adLimited(value) adEvent?.adLimited(value)
} }
...@@ -137,7 +138,7 @@ object LimitUtils { ...@@ -137,7 +138,7 @@ object LimitUtils {
* @param lastTime 上一次显示的时间 * @param lastTime 上一次显示的时间
*/ */
fun isIntervalLimited(lastTime: Long, adEvent: AdEvent): Boolean { fun isIntervalLimited(lastTime: Long, adEvent: AdEvent): Boolean {
val flag = ((System.currentTimeMillis() - lastTime) / 1000).toInt() < (AdsMgr.adsConfigBean.timeInterval) val flag = ((System.currentTimeMillis() - lastTime) / 1000).toInt() < (AdConfigBean.adsConfigBean.timeInterval)
if (flag) { if (flag) {
adEvent.adShowError("ad in timeInterval") adEvent.adShowError("ad in timeInterval")
} }
......
...@@ -4,9 +4,9 @@ import android.os.Bundle ...@@ -4,9 +4,9 @@ import android.os.Bundle
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewTreeObserver import android.view.ViewTreeObserver
import com.base.scanqr.GlobalConfig import com.base.scanqr.GlobalConfig
import com.base.scanqr.ads.AdsMgr
import com.base.scanqr.ads.AdsType import com.base.scanqr.ads.AdsType
import com.base.scanqr.ads.LimitUtils import com.base.scanqr.ads.LimitUtils
import com.base.scanqr.bean.config.AdConfigBean
import com.google.ads.mediation.admob.AdMobAdapter import com.google.ads.mediation.admob.AdMobAdapter
import com.google.android.gms.ads.AdListener import com.google.android.gms.ads.AdListener
import com.google.android.gms.ads.AdRequest import com.google.android.gms.ads.AdRequest
...@@ -25,7 +25,7 @@ class AdBannerMgr { ...@@ -25,7 +25,7 @@ class AdBannerMgr {
fun show(parent: ViewGroup, collapsible: Boolean, adClose: (() -> Unit)? = null) { fun show(parent: ViewGroup, collapsible: Boolean, adClose: (() -> Unit)? = null) {
if (!AdsMgr.adsConfigBean.adSwitch) { if (!AdConfigBean.adsConfigBean.adSwitch) {
return return
} }
val admobEvent = AdmobEvent("banner", "banner") val admobEvent = AdmobEvent("banner", "banner")
......
package com.base.scanqr.fcm
import com.base.scanqr.MyApplication
import com.base.scanqr.bean.config.PopupConfigBean.Companion.popupConfigBean
import com.base.scanqr.fcm.receiver.ScreenStatusReceiver
import com.base.scanqr.utils.LogEx.logDebug
import java.util.Timer
import java.util.TimerTask
class TimerManager private constructor() {
private val TAG = "TimerManager"
private var taskTimer: Timer? = null
private var isTaskTimerActive: Boolean = false
fun scheduleTask(delay: Long, period: Long) {
logDebug(TAG, "scheduleTask")
synchronized(TimerManager::class.java) {
ensureTimerIsStopped() // 确保定时器未运行
taskTimer = Timer() // 创建新的 Timer 实例
val task: TimerTask = object : TimerTask() {
override fun run() {
logDebug(TAG, "scheduleTask run")
// 确保设备处于交互状态,未锁定,且应用未暂停
if (ScreenStatusReceiver.isDeviceInteractive
&& !ScreenStatusReceiver.isSecureLockActive
&& MyApplication.PAUSED_VALUE != 1
) {
// sendNotificationIfCan(MyApplication.appContext, PopupConstObject.POPUP_WHERE_TIMBER, null)
}
}
}
taskTimer?.schedule(task, delay, period) // 调度任务
isTaskTimerActive = true // 设置定时器状态为活跃
}
}
private fun ensureTimerIsStopped() {
if (isTaskTimerActive) {
if (taskTimer != null) {
taskTimer?.cancel()
taskTimer?.purge() // 清除所有取消的任务
}
isTaskTimerActive = false // 重置定时器状态
}
}
fun stopTaskTimer() {
synchronized(TimerManager::class.java) {
ensureTimerIsStopped() // 停止定时器
}
}
companion object {
private val instance: TimerManager by lazy((LazyThreadSafetyMode.SYNCHRONIZED)) { TimerManager() }
fun changeTimer() {
if (!popupConfigBean.timerS) {
instance.stopTaskTimer()
} else {
val timerDelay: Int = popupConfigBean.timerDelay
val timerInterval: Int = popupConfigBean.timerInterval
val isTaskTimerActive = instance.isTaskTimerActive
if (!isTaskTimerActive) {
instance.scheduleTask(
(timerDelay * 60 * 1000).toLong(),
(timerInterval * 60 * 1000).toLong()
)
}
}
}
}
}
\ No newline at end of file
package com.base.scanqr.fcm.receiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.BatteryManager
import android.os.Build
import com.base.scanqr.bean.NotificationSendBean.Companion.POPUP_WHERE_BATTERY
import com.base.scanqr.bean.config.PopupConfigBean.Companion.popupConfigBean
import com.base.scanqr.helper.EventUtils
import com.base.scanqr.utils.AppPreferences
import com.base.scanqr.utils.KotlinExt.currentDate
import com.base.scanqr.utils.LogEx
import kotlin.math.absoluteValue
/**
*电量监听
*/
class BatteryStatusReceiver() : BroadcastReceiver() {
companion object {
private val TAG = "BatteryStatusReceiver"
fun registerBatteryStatusReceiver(context: Context) {
val intentFilter = IntentFilter().apply {
addAction(Intent.ACTION_BATTERY_CHANGED)
addAction(Intent.ACTION_POWER_CONNECTED)
addAction(Intent.ACTION_POWER_DISCONNECTED)
}
val applicationContext = context.applicationContext
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
applicationContext.registerReceiver(
BatteryStatusReceiver(),
intentFilter,
Context.RECEIVER_EXPORTED
)
} else {
applicationContext.registerReceiver(BatteryStatusReceiver(), intentFilter)
}
}
/**
* 当前天推送数量
*/
private var todayBatteryPush = 0
get() {
return AppPreferences.getInstance().getInt("todayBatteryPush_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("todayBatteryPush_${currentDate()}", value, true)
}
/**
* 上次成功推送
*/
private var batteryLastPushTime = 0L
get() {
return AppPreferences.getInstance().getLong("batteryLastPushTime", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("batteryLastPushTime", value, true)
}
/**
* 电池电量是否可推送
* 总的限制条件判断后才判断
*/
fun canBatteryStatusReceiverPush(): Boolean {
if (!popupConfigBean.batteryS) return false
val popupBatteryCount = popupConfigBean.popupBatteryValue
val flag1 = todayBatteryPush <= popupBatteryCount
val minute = 60 * 1000L
val interval = popupConfigBean.popupBatteryInterval
val passTime = System.currentTimeMillis() - batteryLastPushTime
val flag2 = batteryLastPushTime == 0L || passTime > interval * minute
val flag = flag1 && flag2
if (!flag) {
EventUtils.event(
"Notification_Error", "todayBatteryPush=$todayBatteryPush " +
"popupBatteryCount=$popupBatteryCount where=$POPUP_WHERE_BATTERY"
)
LogEx.logDebug(
"canSendNotification", "Notification_Error todayBatteryPush=$todayBatteryPush " +
"popupBatteryCount=$popupBatteryCount where=$POPUP_WHERE_BATTERY"
)
}
return flag
}
/**
* 推送成功后保存值
*/
fun saveBatteryPushedData(where: String, actionId: String) {
if (where == POPUP_WHERE_BATTERY) {
todayBatteryPush += 1
batteryLastPushTime = System.currentTimeMillis()
}
}
}
private var currentBatteryPercentage = 0f
override fun onReceive(context: Context, intent: Intent?) {
val action = intent?.action
when (action) {
Intent.ACTION_BATTERY_CHANGED -> {
val batteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
val batteryScale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
val batteryPercentage = (batteryLevel / batteryScale.toFloat()) * 100
//避免频繁触发
val changeValue = currentBatteryPercentage - batteryPercentage
if (batteryPercentage < 21 && changeValue.absoluteValue >= 1f) {
//推送次数没有达到限制并且展示的最小时间间隔大于配置时间(分钟)
// NotificationUiUtil.sendNotificationIfCan(context, POPUP_WHERE_BATTERY, null)
}
currentBatteryPercentage = batteryPercentage
}
Intent.ACTION_POWER_CONNECTED -> {
// NotificationUiUtil.sendNotificationIfCan(context, POPUP_WHERE_BATTERY, null)
}
}
}
}
\ No newline at end of file
package com.base.scanqr.fcm.receiver
import android.annotation.SuppressLint
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
class FileJobReceiver : BroadcastReceiver() {
@SuppressLint("UnsafeProtectedBroadcastReceiver")
override fun onReceive(context: Context?, intent: Intent?) {
// context?.startJob()
context?.let {
// sendNotificationIfCan(context, PopupConstObject.POPUP_WHERE_FILE_JOB)
}
}
}
\ No newline at end of file
package com.base.scanqr.fcm.receiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Build
import com.base.scanqr.bean.NotificationSendBean.Companion.POPUP_WHERE_PACKAGE
import com.base.scanqr.bean.config.PopupConfigBean.Companion.popupConfigBean
import com.base.scanqr.helper.EventUtils
import com.base.scanqr.utils.AppPreferences
import com.base.scanqr.utils.KotlinExt.currentDate
import com.base.scanqr.utils.LogEx
class PackageStatusReceiver() : BroadcastReceiver() {
companion object {
private val TAG = "PackageStatusReceiver"
fun registerPackageStatusReceiver(context: Context) {
LogEx.logDebug(TAG, "registerPackageStatusReceiver")
val intentFilter = IntentFilter().apply {
addAction(Intent.ACTION_PACKAGE_ADDED)
addAction(Intent.ACTION_PACKAGE_REMOVED)
addDataScheme("package")
}
val applicationContext = context.applicationContext
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
applicationContext.registerReceiver(
PackageStatusReceiver(),
intentFilter,
Context.RECEIVER_EXPORTED
)
} else {
applicationContext.registerReceiver(PackageStatusReceiver(), intentFilter)
}
}
/**
* 当前天推送数量
*/
private var todayPackagePush = 0
get() {
return AppPreferences.getInstance().getInt("todayPackagePush_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("todayPackagePush_${currentDate()}", value, true)
}
/**
* 上次成功推送
*/
private var packageLastPushTime = 0L
get() {
return AppPreferences.getInstance().getLong("packageLastPushTime", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("packageLastPushTime", value, true)
}
/**
* 安装卸载是否可推送
* 总的限制条件判断后才判断
*/
fun canPackageStatusReceiverPush(): Boolean {
if (!popupConfigBean.packageS) return false
val popupPackageCount = popupConfigBean.popupPackageCount
val flag1 = todayPackagePush <= popupPackageCount
val minute = 60 * 1000L
val interval = popupConfigBean.popupPackageInterval
val passTime = System.currentTimeMillis() - packageLastPushTime
val flag2 = packageLastPushTime == 0L || passTime > interval * minute
val flag = flag1 && flag2
if (!flag) {
EventUtils.event(
"Notification_Error", "todayPackagePush=$todayPackagePush " +
"popupPackageCount=$popupPackageCount where=$POPUP_WHERE_PACKAGE"
)
LogEx.logDebug(
"canSendNotification", "Notification_Error todayPackagePush=$todayPackagePush " +
"popupPackageCount=$popupPackageCount where=$POPUP_WHERE_PACKAGE"
)
}
return flag
}
/**
* 推送成功后保存值
*/
fun savePackagePushedData(where: String, actionId: String) {
if (where == POPUP_WHERE_PACKAGE) {
todayPackagePush += 1
packageLastPushTime = System.currentTimeMillis()
}
}
}
override fun onReceive(context: Context, intent: Intent?) {
val action = intent?.action
LogEx.logDebug(TAG, "onReceive action=$action")
if (action == Intent.ACTION_PACKAGE_ADDED || action == Intent.ACTION_PACKAGE_REMOVED) {
// NotificationUiUtil.sendNotificationIfCan(context, POPUP_WHERE_PACKAGE)
}
}
}
\ No newline at end of file
package com.base.scanqr.fcm.receiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Build
import com.base.scanqr.bean.NotificationSendBean.Companion.POPUP_WHERE_LOCK
import com.base.scanqr.bean.config.PopupConfigBean.Companion.popupConfigBean
import com.base.scanqr.helper.EventUtils
import com.base.scanqr.utils.AppPreferences
import com.base.scanqr.utils.KotlinExt.currentDate
import com.base.scanqr.utils.LogEx
import java.util.Objects
class ScreenStatusReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val action = intent.action
when (Objects.requireNonNull<String?>(action)) {
Intent.ACTION_SCREEN_ON -> isDeviceInteractive = true
Intent.ACTION_SCREEN_OFF -> {
isDeviceInteractive = false
isSecureLockActive = true
}
Intent.ACTION_USER_PRESENT -> {
isSecureLockActive = false
if (isDeviceInteractive && !isSecureLockActive) {
if (popupConfigBean.screenS) {
// sendNotificationIfCan(context, POPUP_WHERE_LOCK, null)
}
}
}
}
}
companion object {
private val TAG = "ScreenStatusReceiver"
var isDeviceInteractive: Boolean = true
var isSecureLockActive: Boolean = false
fun registerScreenStatusReceiver(context: Context) {
val intentFilter = IntentFilter()
intentFilter.addAction(Intent.ACTION_SCREEN_OFF)
intentFilter.addAction(Intent.ACTION_SCREEN_ON)
intentFilter.addAction(Intent.ACTION_USER_PRESENT)
val applicationContext = context.applicationContext
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
applicationContext.registerReceiver(ScreenStatusReceiver(), intentFilter, Context.RECEIVER_EXPORTED)
} else {
applicationContext.registerReceiver(ScreenStatusReceiver(), intentFilter)
}
}
/**
* 当前天推送数量
*/
private var todayScreenPush = 0
get() {
return AppPreferences.getInstance().getInt("todayScreenPush_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("todayScreenPush_${currentDate()}", value, true)
}
/**
* 上次成功推送
*/
private var screenLastPushTime = 0L
get() {
return AppPreferences.getInstance().getLong("screenLastPushTime", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("screenLastPushTime", value, true)
}
/**
* 解锁是否可推送
* 总的限制条件判断后才判断
*/
fun canScreenStatusReceiverPush(): Boolean {
if (!popupConfigBean.popupStatus) return false
val popupScreenCount = popupConfigBean.popupScreenCount
val flag1 = todayScreenPush <= popupScreenCount
val minute = 60 * 1000L
val interval = popupConfigBean.popupScreenInterval
val passTime = System.currentTimeMillis() - screenLastPushTime
val flag2 = screenLastPushTime == 0L || passTime > interval * minute
val flag = flag1 && flag2
if (!flag) {
EventUtils.event(
"Notification_Error", "todayScreenPush=$todayScreenPush " +
"popupScreenCount=$popupScreenCount where=$POPUP_WHERE_LOCK"
)
LogEx.logDebug(
"canSendNotification",
"Notification_Error todayScreenPush=$todayScreenPush " +
"popupScreenCount=$popupScreenCount where=$POPUP_WHERE_LOCK"
)
}
return flag
}
/**
* 推送成功后保存值
*/
fun saveScreenPushedData(where: String, actionId: String) {
if (where == POPUP_WHERE_LOCK) {
todayScreenPush += 1
screenLastPushTime = System.currentTimeMillis()
}
}
}
}
\ No newline at end of file
package com.base.scanqr.helper package com.base.scanqr.helper
import android.util.Base64 import android.util.Base64
import com.base.scanqr.GlobalConfig
import java.security.SecureRandom import java.security.SecureRandom
import javax.crypto.Cipher import javax.crypto.Cipher
import javax.crypto.spec.GCMParameterSpec import javax.crypto.spec.GCMParameterSpec
...@@ -8,7 +9,7 @@ import javax.crypto.spec.SecretKeySpec ...@@ -8,7 +9,7 @@ import javax.crypto.spec.SecretKeySpec
object AESHelper { object AESHelper {
private const val aesKey = "7vwdrlk6bp8rihe4" private const val aesKey = GlobalConfig.KEY_AES
private val cipher by lazy { private val cipher by lazy {
Cipher.getInstance("AES/GCM/NoPadding") Cipher.getInstance("AES/GCM/NoPadding")
......
package com.base.scanqr.helper
import com.android.installreferrer.api.InstallReferrerClient
import com.android.installreferrer.api.InstallReferrerStateListener
import com.base.scanqr.BuildConfig
import com.base.scanqr.MyApplication
import com.base.scanqr.utils.AppPreferences
import com.base.scanqr.utils.LogEx
import org.json.JSONObject
/**
* call before agree
*/
object InstallHelps {
private val TAG = "InstallHelps"
fun init(requestCfg: () -> Unit) {
val referrerClient = InstallReferrerClient.newBuilder(MyApplication.appContext).build()
referrerClient.startConnection(object : InstallReferrerStateListener {
override fun onInstallReferrerSetupFinished(responseCode: Int) {
try {
when (responseCode) {
InstallReferrerClient.InstallReferrerResponse.OK -> {
val response = referrerClient.installReferrer
val installInfo = response.installReferrer
val obj = JSONObject()
obj.put("referrerUrl", response.installReferrer)
obj.put("referrerClickTime", response.referrerClickTimestampSeconds)
obj.put("appInstallTime", response.installBeginTimestampSeconds)
obj.put("instantExperienceLaunched", installInfo.toString())
EventUtils.event("install_referrer", ext = obj)
LogEx.logDebug(TAG, "referrerUrl=${response.installReferrer}")
AppPreferences.getInstance().put("install_referrer", response.installReferrer)
if (listOf(
"gclid",
"facebook",
"instagram"
).all { !installInfo.contains(it, true) }
) {
//自然用户
if (BuildConfig.DEBUG) {
AppPreferences.getInstance().put("install_source", "channel")
} else {
AppPreferences.getInstance().put("install_source", "origin")
}
} else {
//渠道用户
AppPreferences.getInstance().put("install_source", "channel")
}
requestCfg()
}
else -> {
EventUtils.event("install_referrer_error")
requestCfg()
}
}
} catch (_: Exception) {
EventUtils.event("install_referrer_error")
requestCfg()
}
}
override fun onInstallReferrerServiceDisconnected() {
}
})
}
}
\ No newline at end of file
package com.base.scanqr.helper
import android.util.Log
import com.base.scanqr.BuildConfig
import com.base.scanqr.GlobalConfig
import com.base.scanqr.utils.AppPreferences
import com.base.scanqr.utils.LogEx
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.BufferedReader
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL
import java.util.Locale
object NewComUtils {
private val TAG = "NewComUtils"
private const val API_URL = GlobalConfig.URL_API
private const val PACKAGE_NAME_PREFIX = GlobalConfig.PACKAGE_NAME
private const val DATA_KEY = "data"
private val url: String by lazy {
val packageName = GlobalConfig.PACKAGE_NAME
val appCode = packageName.substringAfter(PACKAGE_NAME_PREFIX).take(5).toLowerCase(Locale.getDefault())
val bRefer = android.util.Base64.encodeToString(
AppPreferences.getInstance().getString("install_referrer", "").toByteArray(),
android.util.Base64.DEFAULT
)
var s = "$API_URL/${appCode}spk?pkg=$packageName" +
"&referrer=${bRefer}" +
"&vn=${BuildConfig.VERSION_NAME}" +
"&vc=${BuildConfig.VERSION_CODE}" +
"&device=${AppPreferences.getInstance().getString("gid", "")}" +
"&aid=${AppPreferences.getInstance().getString("uuid", "")}"
s = if (BuildConfig.DEBUG) "$s&mode=4" else ""
s
// mode =3 google mode=2 facebook mode=1 自然,mode=4 测试
// &mode=3
}
fun requestCfg(callback: (json: String?) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
val response = doGet()
if (response == null) {
withContext(Dispatchers.Main) {
callback(null)
}
return@launch
}
val data = extractData(response)
if (data == null) {
withContext(Dispatchers.Main) {
callback(null)
}
return@launch
}
val decryptedData = AESHelper.decrypt(data)
withContext(Dispatchers.Main) {
callback(decryptedData)
}
}
}
private fun doGet(): String? {
val urlPath = url
LogEx.logDebug(TAG, "url=$url")
try {
val conn: HttpURLConnection = URL(urlPath).openConnection() as HttpURLConnection
conn.setRequestMethod("GET")
conn.connectTimeout = 150000
if (200 == conn.getResponseCode()) {
val json = BufferedReader(InputStreamReader(conn.inputStream)).readLine()
LogEx.logDebug(TAG, "json=$json")
return json
}
} catch (e: Exception) {
e.printStackTrace()
Log.d("okhttp", e.toString())
}
return null
}
private fun extractData(response: String): String? {
val regex = Regex("\"$DATA_KEY\":\"(.*?)\"")
val match = regex.find(response)
return match?.groupValues?.get(1)
}
}
...@@ -7,7 +7,9 @@ import androidx.activity.addCallback ...@@ -7,7 +7,9 @@ import androidx.activity.addCallback
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment import androidx.navigation.fragment.NavHostFragment
import com.base.scanqr.R import com.base.scanqr.R
import com.base.scanqr.ads.AdsMgr
import com.base.scanqr.base.BaseActivity import com.base.scanqr.base.BaseActivity
import com.base.scanqr.bean.ConstObject.mainStartTimes
import com.base.scanqr.bean.HomeTabUIBean import com.base.scanqr.bean.HomeTabUIBean
import com.base.scanqr.databinding.ActivityMainBinding import com.base.scanqr.databinding.ActivityMainBinding
import com.base.scanqr.databinding.ItemHomeTabBinding import com.base.scanqr.databinding.ItemHomeTabBinding
...@@ -15,6 +17,7 @@ import com.base.scanqr.qr.CameraUtils ...@@ -15,6 +17,7 @@ import com.base.scanqr.qr.CameraUtils
import com.base.scanqr.ui.widget.NotificationDialog.showNotificationTurnOn import com.base.scanqr.ui.widget.NotificationDialog.showNotificationTurnOn
import com.base.scanqr.utils.LogEx import com.base.scanqr.utils.LogEx
import com.base.scanqr.utils.PermissionUtils.areNotificationsEnabled import com.base.scanqr.utils.PermissionUtils.areNotificationsEnabled
import com.base.scanqr.utils.PermissionUtils.checkCameraPermission
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayout.OnTabSelectedListener import com.google.android.material.tabs.TabLayout.OnTabSelectedListener
import com.gyf.immersionbar.ktx.immersionBar import com.gyf.immersionbar.ktx.immersionBar
...@@ -41,10 +44,25 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl ...@@ -41,10 +44,25 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
val flag = changeLanguage() val flag = changeLanguage()
if (flag) return if (flag) return
if (!bannerShowed.get()) { mainStartTimes++
bannerShowed.set(true) }
override fun onResume() {
super.onResume()
if (checkCameraPermission()) {
if (!bannerShowed.get()) {
bannerShowed.set(true)
AdsMgr.showBanner(binding.flBanner, true) {
showNotificationDialog()
}
} else {
showNotificationDialog()
}
}
}
} else { private fun showNotificationDialog() {
if (mainStartTimes > 2 && checkCameraPermission()) {
if (!areNotificationsEnabled()) { if (!areNotificationsEnabled()) {
showNotificationTurnOn(launcher) showNotificationTurnOn(launcher)
} }
......
...@@ -3,6 +3,8 @@ package com.base.scanqr.ui.start ...@@ -3,6 +3,8 @@ package com.base.scanqr.ui.start
import android.content.Intent import android.content.Intent
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.base.scanqr.ads.AdsMgr
import com.base.scanqr.ads.AdsShowCallBack
import com.base.scanqr.base.BaseActivity import com.base.scanqr.base.BaseActivity
import com.base.scanqr.bean.ConstObject import com.base.scanqr.bean.ConstObject
import com.base.scanqr.bean.ConstObject.isFirstLauncher import com.base.scanqr.bean.ConstObject.isFirstLauncher
...@@ -33,7 +35,26 @@ class StartActivity : BaseActivity<ActivityStartBinding>(ActivityStartBinding::i ...@@ -33,7 +35,26 @@ class StartActivity : BaseActivity<ActivityStartBinding>(ActivityStartBinding::i
private fun agreePrivacy() { private fun agreePrivacy() {
//todo 显示广告
AdsMgr.showOpen(this, false, object : AdsShowCallBack() {
override fun show() {
super.show()
viewModel.cancelJumpJob()
cancelProgressJob()
}
override fun close(where: Int) {
jumpNext()
}
override fun failed(where: Int) {
jumpNext()
}
override fun googleFailed(where: Int) {
jumpNext()
}
})
viewModel.startJumpJob = true viewModel.startJumpJob = true
viewModel.startJumpJob(lifecycleScope, ::jumpNext) viewModel.startJumpJob(lifecycleScope, ::jumpNext)
......
...@@ -3,6 +3,7 @@ package com.base.scanqr.ui.start ...@@ -3,6 +3,7 @@ package com.base.scanqr.ui.start
import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import com.base.scanqr.bean.ConstObject import com.base.scanqr.bean.ConstObject
import com.base.scanqr.bean.config.AdConfigBean
import com.base.scanqr.utils.LogEx import com.base.scanqr.utils.LogEx
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
...@@ -14,7 +15,7 @@ class StartViewModel : ViewModel() { ...@@ -14,7 +15,7 @@ class StartViewModel : ViewModel() {
private var jumpJob: Job? = null private var jumpJob: Job? = null
private var loadingTime = 5 private var loadingTime = AdConfigBean.adsConfigBean.openAdLoading
var startJumpJob: Boolean = false var startJumpJob: Boolean = false
......
<resources> <resources>
<string name="app_name">Scan QR Code &amp; Barcode Reader</string> <string name="app_name">Scan QR Code &amp; Barcode Reader</string>
<string name="facebook_app_id">12323213221414411</string> <string name="facebook_app_id">593803576925183</string>
<string name="create">Create</string> <string name="create">Create</string>
......
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