Commit 9ce17b16 authored by wanglei's avatar wanglei

...

parent a3745b91
......@@ -5,7 +5,7 @@ package com.base.scanqr
*/
object GlobalConfig {
//包名
const val PACKAGE_NAME = "com.loactation.alibabab.ccccaa"
const val PACKAGE_NAME = "com.scan.barcode.deeplink"
// 域名
/**
......@@ -21,17 +21,17 @@ object GlobalConfig {
/**
* 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 使用条款
*/
const val URL_USE = ""
const val URL_USE = "https://sites.google.com/view/termsofscanqr/terms-of-scan-qr"
/**
* Key Aes 加密key
*/
const val KEY_AES = "pex50vwzuhpim3yh"
const val KEY_AES = "o3yb8vzeptlki1ve"
/**
* Key solar 归因key
......
......@@ -3,20 +3,36 @@ package com.base.scanqr
import android.app.Activity
import android.app.Application
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import com.base.scanqr.ads.AdsMgr
import com.base.scanqr.bean.ConstObject.appLanguageCountrySp
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.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.AppPreferences
import com.base.scanqr.utils.LogEx
import com.base.scanqr.utils.SolarEngineUtils.solarkey
import com.facebook.FacebookSdk
import com.google.android.gms.ads.identifier.AdvertisingIdClient
import com.google.gson.Gson
import com.hjq.language.MultiLanguages
import com.hjq.language.OnLanguageListener
import com.reyun.solar.engine.SolarEngineManager
import org.json.JSONObject
import java.util.Locale
import java.util.UUID
......@@ -102,21 +118,23 @@ class MyApplication : Application() {
FCMManager.initFirebase(this)
FCMManager.subscribeToTopic(topic)
// initConfig()
//
// Thread {
// InstallHelps.init {
// initRemoteConfig()
// }
// }.start()
initConfig()
// 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()
// ScreenStatusReceiver.registerScreenStatusReceiver(this)
// PackageStatusReceiver.registerPackageStatusReceiver(this)
// BatteryStatusReceiver.registerBatteryStatusReceiver(this)
ScreenStatusReceiver.registerScreenStatusReceiver(this)
PackageStatusReceiver.registerPackageStatusReceiver(this)
BatteryStatusReceiver.registerBatteryStatusReceiver(this)
// startJob()
// startAlarm(appContext, 24)
......@@ -157,13 +175,13 @@ class MyApplication : Application() {
LogEx.logDebug(TAG, "flag=$flag" + " activity:" + activity.localClassName)
if (flag) {
// topActivity?.startActivity(
// Intent(
// topActivity, SplashActivity::class.java
// ).apply {
// putExtra("isHotLaunch", true)
// putExtra("type", -1)
// })
topActivity?.startActivity(
Intent(
topActivity, StartActivity::class.java
).apply {
putExtra("isHotLaunch", true)
putExtra("type", -1)
})
}
}
lastTimeResume = 0
......@@ -192,42 +210,44 @@ class MyApplication : Application() {
}
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 ->
// if (config != null) {
// AppPreferences.getInstance().put("config", config)
// }
//
// LogEx.logDebug("requestCfg", "config=$config")
//
// initConfig(config)
// }
initConfig(config)
}
}
private fun initConfig(config: String? = AppPreferences.getInstance().getString("config", "")) {
// kotlin.runCatching {
// val configBean = Gson().fromJson(config, com.base.scanqr.bean.config.ConfigBean::class.java)
//
// val jsonObject = JSONObject()
// jsonObject.put("ut", configBean.ut)
// EventUtils.event("user_type", ext = jsonObject)
//
// //配置
// com.base.scanqr.bean.config.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}")
//
// //通知
// PopupConstObject.popupConfigBean = configBean.popupConfigBean
//
// //启动定时器
// changeTimer()
// }
kotlin.runCatching {
val configBean = Gson().fromJson(config, ConfigBean::class.java)
val jsonObject = JSONObject()
jsonObject.put("ut", configBean.ut)
EventUtils.event("user_type", ext = jsonObject)
LogEx.logDebug("initConfig", "ut=${configBean.ut}")
//配置
ConfigBean.configBean = configBean
//广告
AdConfigBean.adsConfigBean = configBean.adConfigBean
LogEx.logDebug("initConfig", "adsConfigBean=${AdConfigBean.adsConfigBean.functionInShowAd}")
//通知
PopupConfigBean.popupConfigBean = configBean.popupConfigBean
LogEx.logDebug("initConfig", "popupConfigBean=${PopupConfigBean.popupConfigBean.popupCount}")
//启动定时器
changeTimer()
}
}
......
......@@ -73,11 +73,6 @@ object AdsMgr {
var isMaxInit = false
private set
/**
* 广告配置项目
*/
var adsConfigBean: AdConfigBean = AdConfigBean()
/**
* Init 初始化
......@@ -104,7 +99,7 @@ object AdsMgr {
EventUtils.event("AdmobInit", "AdmobInit")
// context.toast("admob init")
if (adsConfigBean.adSwitch) {
if (AdConfigBean.adsConfigBean.adSwitch) {
admobInitCallBack?.invoke()
admobInitCallBack = null
adOpenMgr.loadAd(context, false, AdmobEvent("openAd", context::class.java.simpleName))
......@@ -134,7 +129,7 @@ object AdsMgr {
AppLovinSdk.getInstance(context).initialize(initConfig) {
isMaxInit = true
// maxOpenMgr.loadAd(context)
if (!adsConfigBean.adSwitch) {
if (!AdConfigBean.adsConfigBean.adSwitch) {
maxInsertMgr.loadAd(context, false, AdMaxEvent("interAd", context::class.java.simpleName))
context.toast("max init")
maxInitCallBack?.invoke()
......@@ -169,7 +164,7 @@ object AdsMgr {
}
val from = activity::class.java.simpleName
if (adsConfigBean.adSwitch) {
if (AdConfigBean.adsConfigBean.adSwitch) {
if (isAdmobInit) {
adOpenMgr.show(activity, isUnLimit, AdmobEvent("openAd", from), showCallBack)
} else {
......@@ -205,9 +200,9 @@ object AdsMgr {
EventUtils.event("isInBlackList", configBean.isInBlackList.toString())
return
}
LogEx.logDebug("showAd", "adSwitch=${adsConfigBean.adSwitch}")
LogEx.logDebug("showAd", "adSwitch=${AdConfigBean.adsConfigBean.adSwitch}")
val from = activity::class.java.simpleName
if (adsConfigBean.adSwitch) {
if (AdConfigBean.adsConfigBean.adSwitch) {
adInsertMgr.show(activity, isUnLimit, AdmobEvent("interAd", from), showCallBack)
} else {
maxInsertMgr.show(activity, isUnLimit, AdMaxEvent("interAd", from), showCallBack)
......@@ -233,14 +228,14 @@ object AdsMgr {
if (!isAdmobInit) return
if (adsConfigBean.adSwitch) {
if (AdConfigBean.adsConfigBean.adSwitch) {
adNativeMgr.show(AdmobEvent("nativeAd", "nativeAd"), nativeView, layout, nativeCallBack)
} else {
maxNativeMgr.show(AdMaxEvent("nativeAd", "nativeAd"), nativeView, layout, nativeCallBack)
}
}
fun isNativeShow() = LimitUtils.isAdShow(AdsType.NATIVE, null)
fun isNativeShow() = LimitUtils.isAdShow(AdsType.NATIVE, null)
/**
* 展示banner广告
......@@ -252,7 +247,7 @@ object AdsMgr {
EventUtils.event("isInBlackList", configBean.isInBlackList.toString())
return
}
if (adsConfigBean.adSwitch) {
if (AdConfigBean.adsConfigBean.adSwitch) {
adBannerMgr.show(parent, collapsible, adClose)
}
}
......
package com.base.scanqr.ads
import com.base.scanqr.bean.config.AdConfigBean
import com.base.scanqr.utils.AppPreferences
import com.base.scanqr.utils.KotlinExt.toFormatTime4
......@@ -31,7 +32,7 @@ object LimitUtils {
*/
private inline val isRequestLimited: Boolean
get() {
val maxCount = AdsMgr.adsConfigBean.numRequestLimit
val maxCount = AdConfigBean.adsConfigBean.numRequestLimit
return maxCount > -1 && AppPreferences.getInstance()
.getInt(NUM_REQUEST, 0) >= maxCount
}
......@@ -41,7 +42,7 @@ object LimitUtils {
*/
private inline val isDisplayLimited: Boolean
get() {
val maxCount = AdsMgr.adsConfigBean.numDisplayLimit
val maxCount = AdConfigBean.adsConfigBean.numDisplayLimit
return maxCount > -1 && AppPreferences.getInstance()
.getInt(NUM_DISPLAY, 0) >= maxCount
}
......@@ -51,7 +52,7 @@ object LimitUtils {
*/
private inline val isClickLimited: Boolean
get() {
val maxCount = AdsMgr.adsConfigBean.numClickLimit
val maxCount = AdConfigBean.adsConfigBean.numClickLimit
return maxCount > -1 && AppPreferences.getInstance()
.getInt(NUM_CLICK, 0) >= maxCount
}
......@@ -84,21 +85,21 @@ object LimitUtils {
val value = "current${getAdEventMsg(adsType)} " +
"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)
}
if (isClickLimited) {
val value =
"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)
}
if (isRequestLimited) {
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)
}
......@@ -137,7 +138,7 @@ object LimitUtils {
* @param lastTime 上一次显示的时间
*/
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) {
adEvent.adShowError("ad in timeInterval")
}
......
......@@ -4,9 +4,9 @@ import android.os.Bundle
import android.view.ViewGroup
import android.view.ViewTreeObserver
import com.base.scanqr.GlobalConfig
import com.base.scanqr.ads.AdsMgr
import com.base.scanqr.ads.AdsType
import com.base.scanqr.ads.LimitUtils
import com.base.scanqr.bean.config.AdConfigBean
import com.google.ads.mediation.admob.AdMobAdapter
import com.google.android.gms.ads.AdListener
import com.google.android.gms.ads.AdRequest
......@@ -25,7 +25,7 @@ class AdBannerMgr {
fun show(parent: ViewGroup, collapsible: Boolean, adClose: (() -> Unit)? = null) {
if (!AdsMgr.adsConfigBean.adSwitch) {
if (!AdConfigBean.adsConfigBean.adSwitch) {
return
}
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
import android.util.Base64
import com.base.scanqr.GlobalConfig
import java.security.SecureRandom
import javax.crypto.Cipher
import javax.crypto.spec.GCMParameterSpec
......@@ -8,7 +9,7 @@ import javax.crypto.spec.SecretKeySpec
object AESHelper {
private const val aesKey = "7vwdrlk6bp8rihe4"
private const val aesKey = GlobalConfig.KEY_AES
private val cipher by lazy {
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
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import com.base.scanqr.R
import com.base.scanqr.ads.AdsMgr
import com.base.scanqr.base.BaseActivity
import com.base.scanqr.bean.ConstObject.mainStartTimes
import com.base.scanqr.bean.HomeTabUIBean
import com.base.scanqr.databinding.ActivityMainBinding
import com.base.scanqr.databinding.ItemHomeTabBinding
......@@ -15,6 +17,7 @@ import com.base.scanqr.qr.CameraUtils
import com.base.scanqr.ui.widget.NotificationDialog.showNotificationTurnOn
import com.base.scanqr.utils.LogEx
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.OnTabSelectedListener
import com.gyf.immersionbar.ktx.immersionBar
......@@ -41,10 +44,25 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
val flag = changeLanguage()
if (flag) return
if (!bannerShowed.get()) {
bannerShowed.set(true)
mainStartTimes++
}
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()) {
showNotificationTurnOn(launcher)
}
......
......@@ -3,6 +3,8 @@ package com.base.scanqr.ui.start
import android.content.Intent
import androidx.lifecycle.ViewModelProvider
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.bean.ConstObject
import com.base.scanqr.bean.ConstObject.isFirstLauncher
......@@ -33,7 +35,26 @@ class StartActivity : BaseActivity<ActivityStartBinding>(ActivityStartBinding::i
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(lifecycleScope, ::jumpNext)
......
......@@ -3,6 +3,7 @@ package com.base.scanqr.ui.start
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.ViewModel
import com.base.scanqr.bean.ConstObject
import com.base.scanqr.bean.config.AdConfigBean
import com.base.scanqr.utils.LogEx
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
......@@ -14,7 +15,7 @@ class StartViewModel : ViewModel() {
private var jumpJob: Job? = null
private var loadingTime = 5
private var loadingTime = AdConfigBean.adsConfigBean.openAdLoading
var startJumpJob: Boolean = false
......
<resources>
<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>
......
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