Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Sign in / Register
Toggle navigation
L
location share white
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wanglei
location share white
Commits
257ed5db
Commit
257ed5db
authored
Dec 02, 2024
by
wanglei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
...
parent
9fb1d6e9
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
519 additions
and
354 deletions
+519
-354
AdsConfigBean.kt
...ain/java/com/base/locationsharewhite/ads/AdsConfigBean.kt
+0
-47
AdsMgr.kt
app/src/main/java/com/base/locationsharewhite/ads/AdsMgr.kt
+110
-25
NativeParentView.kt
.../java/com/base/locationsharewhite/ads/NativeParentView.kt
+51
-1
AdNativeMgr.kt
...java/com/base/locationsharewhite/ads/admob/AdNativeMgr.kt
+15
-11
NativeView.kt
.../java/com/base/locationsharewhite/ads/admob/NativeView.kt
+0
-65
AdMaxEvent.kt
...va/com/base/locationsharewhite/ads/applovin/AdMaxEvent.kt
+149
-0
MaxInsertMgr.kt
.../com/base/locationsharewhite/ads/applovin/MaxInsertMgr.kt
+21
-22
MaxNativeMgr.kt
.../com/base/locationsharewhite/ads/applovin/MaxNativeMgr.kt
+16
-9
MaxOpenMgr.kt
...va/com/base/locationsharewhite/ads/applovin/MaxOpenMgr.kt
+9
-15
AdConfigBean.kt
...n/java/com/base/locationsharewhite/config/AdConfigBean.kt
+10
-0
ConfigBean.kt
...ain/java/com/base/locationsharewhite/config/ConfigBean.kt
+16
-0
PopupConfigBean.kt
...ava/com/base/locationsharewhite/config/PopupConfigBean.kt
+36
-0
BatteryStatusReceiver.kt
.../com/base/locationsharewhite/fcm/BatteryStatusReceiver.kt
+5
-5
NotificationHoverUtils.kt
...com/base/locationsharewhite/fcm/NotificationHoverUtils.kt
+5
-8
NotificationUiUtil.kt
...ava/com/base/locationsharewhite/fcm/NotificationUiUtil.kt
+11
-18
PackageStatusReceiver.kt
.../com/base/locationsharewhite/fcm/PackageStatusReceiver.kt
+7
-6
PopupConstObject.kt
.../java/com/base/locationsharewhite/fcm/PopupConstObject.kt
+2
-67
ScreenStatusReceiver.kt
...a/com/base/locationsharewhite/fcm/ScreenStatusReceiver.kt
+6
-9
TimerManager.kt
...main/java/com/base/locationsharewhite/fcm/TimerManager.kt
+5
-8
MyApplication.kt
.../java/com/base/locationsharewhite/helper/MyApplication.kt
+20
-11
NewComUtils.kt
...in/java/com/base/locationsharewhite/helper/NewComUtils.kt
+20
-21
MainActivity.kt
.../java/com/base/locationsharewhite/ui/main/MainActivity.kt
+1
-1
SplashActivity.kt
...a/com/base/locationsharewhite/ui/splash/SplashActivity.kt
+1
-1
DialogView.kt
...n/java/com/base/locationsharewhite/ui/views/DialogView.kt
+0
-1
dialog_app_exit.xml
app/src/main/res/layout/dialog_app_exit.xml
+3
-3
No files found.
app/src/main/java/com/base/locationsharewhite/ads/AdsConfigBean.kt
deleted
100644 → 0
View file @
9fb1d6e9
package
com.base.locationsharewhite.ads
import
com.base.locationsharewhite.utils.AppPreferences
import
org.json.JSONObject
/**
* 广告限制配置
*
* @property isInBlackList 是否在黑名单
* @property numDisplayLimit 展示次数限制 -1为不限制,0为彻底关闭显示
* @property numRequestLimit 请求次数限制 -1为不限制,0为彻底关闭显示
* @property numClickLimit 点击次数限制 -1为不限制,0为彻底关闭显示
* @property timeInterval 广告间隔时间
*/
data class
AdsConfigBean
(
var
isInBlackList
:
Boolean
=
false
,
var
numDisplayLimit
:
Int
=
-
1
,
var
numRequestLimit
:
Int
=
-
1
,
var
numClickLimit
:
Int
=
-
1
,
var
timeInterval
:
Int
=
1
,
var
openAdLoading
:
Int
=
15
,
)
{
companion
object
{
fun
getSpConfigBean
():
AdsConfigBean
{
val
adsConfigBean
=
AdsConfigBean
()
adsConfigBean
.
apply
{
isInBlackList
=
AppPreferences
.
getInstance
().
getBoolean
(
"isInBlackList"
,
false
)
numDisplayLimit
=
AppPreferences
.
getInstance
().
getString
(
"numDisplayLimit"
,
"-1"
).
toInt
()
numRequestLimit
=
AppPreferences
.
getInstance
().
getString
(
"numRequestLimit"
,
"-1"
).
toInt
()
numClickLimit
=
AppPreferences
.
getInstance
().
getString
(
"numClickLimit"
,
"-1"
).
toInt
()
timeInterval
=
AppPreferences
.
getInstance
().
getString
(
"timeInterval"
,
"1"
).
toInt
()
openAdLoading
=
AppPreferences
.
getInstance
().
getString
(
"openAdLoading"
,
"15"
).
toInt
()
}
return
adsConfigBean
}
fun
createDefaultAdJson
():
JSONObject
{
val
json
=
JSONObject
()
json
.
put
(
"numDisplayLimit"
,
"-1"
)
json
.
put
(
"numRequestLimit"
,
"-1"
)
json
.
put
(
"numClickLimit"
,
"-1"
)
json
.
put
(
"timeInterval"
,
"1"
)
json
.
put
(
"openAdLoading"
,
"15"
)
return
json
}
}
}
\ No newline at end of file
app/src/main/java/com/base/locationsharewhite/ads/AdsMgr.kt
View file @
257ed5db
...
...
@@ -3,10 +3,21 @@ package com.base.locationsharewhite.ads
import
android.app.Activity
import
android.content.Context
import
android.view.ViewGroup
import
androidx.annotation.LayoutRes
import
com.applovin.sdk.AppLovinMediationProvider
import
com.applovin.sdk.AppLovinSdk
import
com.applovin.sdk.AppLovinSdkInitializationConfiguration
import
com.base.locationsharewhite.ads.admob.AdBannerMgr
import
com.base.locationsharewhite.ads.admob.AdInsertMgr
import
com.base.locationsharewhite.ads.admob.AdNativeMgr
import
com.base.locationsharewhite.ads.admob.AdOpenMgr
import
com.base.locationsharewhite.ads.admob.LimitUtils
import
com.base.locationsharewhite.ads.applovin.MaxInsertMgr
import
com.base.locationsharewhite.ads.applovin.MaxNativeMgr
import
com.base.locationsharewhite.ads.applovin.MaxOpenMgr
import
com.base.locationsharewhite.config.AdConfigBean
import
com.base.locationsharewhite.config.ConfigBean.Companion.configBean
import
com.base.locationsharewhite.helper.EventUtils
import
com.google.android.gms.ads.MobileAds
import
com.google.android.gms.ads.initialization.AdapterStatus
...
...
@@ -30,6 +41,17 @@ object AdsMgr {
AdBannerMgr
()
}
private
val
maxOpenMgr
by
lazy
{
MaxOpenMgr
()
}
private
val
maxInsertMgr
by
lazy
{
MaxInsertMgr
()
}
private
val
maxNativeMgr
by
lazy
{
MaxNativeMgr
()
}
/**
* 是否初始化
*/
...
...
@@ -39,26 +61,44 @@ object AdsMgr {
/**
* 广告配置项目
*/
var
adsConfigBean
:
Ad
sConfigBean
?
=
null
private
set
var
adsConfigBean
:
Ad
ConfigBean
=
AdConfigBean
()
/**
* Init 初始化
*
* @param context 这里最好是appContext,因为是耗时操作,等它初始化完毕马上加载开屏和插屏广告
*/
fun
init
(
context
:
Context
,
adsConfigBean
:
AdsConfigBean
)
{
if
(
adsConfigBean
.
isInBlackList
)
return
AdsMgr
.
adsConfigBean
=
adsConfigBean
MobileAds
.
initialize
(
context
)
{
val
readyAdapter
=
it
.
adapterStatusMap
.
entries
.
find
{
entry
->
entry
.
value
.
initializationState
==
AdapterStatus
.
State
.
READY
}
isInit
=
readyAdapter
!=
null
if
(
isInit
)
{
fun
init
(
context
:
Context
)
{
if
(
configBean
.
isInBlackList
)
{
EventUtils
.
event
(
"isInBlackList"
,
configBean
.
isInBlackList
.
toString
())
return
}
if
(
adsConfigBean
.
adSwitch
)
{
MobileAds
.
initialize
(
context
)
{
val
readyAdapter
=
it
.
adapterStatusMap
.
entries
.
find
{
entry
->
entry
.
value
.
initializationState
==
AdapterStatus
.
State
.
READY
}
isInit
=
readyAdapter
!=
null
EventUtils
.
event
(
"AdmobInit"
,
"AdmobInit"
)
//if (isInit) {
//成功初始化就提前预加载开屏广告和插页广告
adOpenMgr
.
loadAd
(
context
)
adInsertMgr
.
loadAd
(
context
)
// }
}
//据说可以初始化之前就预加载广告
adOpenMgr
.
loadAd
(
context
)
adInsertMgr
.
loadAd
(
context
)
}
else
{
val
initConfig
=
AppLovinSdkInitializationConfiguration
.
builder
(
ConstConfig
.
MAX_SDK_KEY
,
context
).
setMediationProvider
(
AppLovinMediationProvider
.
MAX
).
build
()
AppLovinSdk
.
getInstance
(
context
).
initialize
(
initConfig
)
{
isInit
=
true
maxOpenMgr
.
loadAd
(
context
)
maxInsertMgr
.
loadAd
(
context
)
}
}
}
...
...
@@ -69,8 +109,24 @@ object AdsMgr {
* @param activity 当前页面
* @param showCallBack 展示回调
*/
fun
showOpen
(
activity
:
Activity
,
isUnLimit
:
Boolean
=
false
,
showCallBack
:
AdsShowCallBack
?
=
null
)
{
adOpenMgr
.
show
(
activity
,
isUnLimit
,
showCallBack
)
fun
showOpen
(
activity
:
Activity
,
isUnLimit
:
Boolean
=
false
,
showCallBack
:
AdsShowCallBack
?
=
null
,
)
{
if
(
configBean
.
isInBlackList
)
{
return
}
if
((!
adsConfigBean
.
adSwitch
&&
!
isInit
))
{
showCallBack
?.
failed
()
return
}
if
(
adsConfigBean
.
adSwitch
)
{
adOpenMgr
.
show
(
activity
,
isUnLimit
,
showCallBack
)
}
else
{
maxOpenMgr
.
show
(
activity
,
isUnLimit
,
showCallBack
)
}
}
/**
...
...
@@ -78,36 +134,65 @@ object AdsMgr {
*
* @param activity 当前页面
* @param showCallBack 展示回调
* @param isUnLimit 是否不受限制 默认false 代表受到限制
*/
fun
showInsert
(
activity
:
Activity
,
isUnLimit
:
Boolean
=
false
,
showCallBack
:
AdsShowCallBack
?
=
null
showCallBack
:
AdsShowCallBack
?
=
null
,
isUnLimit
:
Boolean
=
false
)
{
if
(!
isInit
||
adsConfigBean
?.
isInBlackList
!=
false
)
{
if
(
configBean
.
isInBlackList
)
{
EventUtils
.
event
(
"isInBlackList"
,
configBean
.
isInBlackList
.
toString
())
return
}
if
((!
adsConfigBean
.
adSwitch
&&
!
isInit
))
{
showCallBack
?.
failed
()
return
}
adInsertMgr
.
show
(
activity
,
isUnLimit
,
showCallBack
)
if
(
adsConfigBean
.
adSwitch
)
adInsertMgr
.
show
(
activity
,
isUnLimit
,
showCallBack
)
else
maxInsertMgr
.
show
(
activity
,
isUnLimit
,
showCallBack
)
}
/**
* 展示原生广告
*
* @param
parent 需要展示广告的父
布局容器
* @param layout 原生广告布局 ,这里传入的layout要和NativeView里的id一致
* @param
nativeView 需要展示广告的
布局容器
* @param layout 原生广告布局 ,这里传入的layout要和
com.example.mydemo.strategy.ads.admob.
NativeView里的id一致
*/
fun
showNative
(
parent
:
ViewGroup
,
layout
:
Int
)
{
adNativeMgr
.
show
(
parent
,
layout
)
fun
showNative
(
nativeView
:
NativeParentView
,
@LayoutRes
layout
:
Int
,
nativeCallBack
:
((
Any
?)
->
Unit
)?
=
null
)
{
if
(
configBean
.
isInBlackList
)
{
EventUtils
.
event
(
"isInBlackList"
,
configBean
.
isInBlackList
.
toString
())
return
}
if
(!
isInit
)
return
if
(
adsConfigBean
.
adSwitch
)
{
adNativeMgr
.
show
(
nativeView
,
layout
,
nativeCallBack
)
}
else
{
maxNativeMgr
.
show
(
nativeView
,
layout
,
nativeCallBack
)
}
}
fun
isNativeShow
()
=
(
isInit
&&
!
configBean
.
isInBlackList
)
&&
LimitUtils
.
isAdShow
(
AdsType
.
NATIVE
)
/**
* 展示banner广告
*
* @param parent 展示广告的父布局容器
*/
fun
showBanner
(
parent
:
ViewGroup
)
{
if
(!
isInit
||
adsConfigBean
?.
isInBlackList
!=
false
)
return
adBannerMgr
.
show
(
parent
)
if
(
configBean
.
isInBlackList
)
{
EventUtils
.
event
(
"isInBlackList"
,
configBean
.
isInBlackList
.
toString
())
return
}
if
(!
isInit
)
{
adBannerMgr
.
show
(
parent
)
}
}
}
\ No newline at end of file
app/src/main/java/com/base/locationsharewhite/ads/
CustomParentNative
View.kt
→
app/src/main/java/com/base/locationsharewhite/ads/
NativeParent
View.kt
View file @
257ed5db
...
...
@@ -5,6 +5,7 @@ import android.content.Context
import
android.util.AttributeSet
import
android.view.LayoutInflater
import
android.view.View
import
android.view.ViewGroup
import
android.widget.Button
import
android.widget.FrameLayout
import
android.widget.ImageView
...
...
@@ -19,7 +20,7 @@ import com.google.android.gms.ads.nativead.NativeAd
import
com.google.android.gms.ads.nativead.NativeAdView
@SuppressLint
(
"ViewConstructor"
)
class
CustomParentNative
View
(
context
:
Context
,
attrs
:
AttributeSet
?
=
null
)
:
class
NativeParent
View
(
context
:
Context
,
attrs
:
AttributeSet
?
=
null
)
:
FrameLayout
(
context
,
attrs
)
{
fun
setNativeAd
(
...
...
@@ -82,6 +83,55 @@ class CustomParentNativeView(context: Context, attrs: AttributeSet? = null) :
val
adView
=
MaxNativeAdView
(
binder
,
context
)
nativeAdLoader
.
render
(
adView
,
nativeAd
)
setBackgroundResource
(
0
)
removeAllViews
()
addView
(
adView
)
}
}
@SuppressLint
(
"ViewConstructor"
)
class
CustomParentNativeView
(
context
:
Context
,
val
layout
:
Int
,
attrs
:
AttributeSet
?
=
null
)
:
FrameLayout
(
context
,
attrs
)
{
init
{
layoutParams
=
LayoutParams
(
ViewGroup
.
LayoutParams
.
MATCH_PARENT
,
ViewGroup
.
LayoutParams
.
WRAP_CONTENT
)
}
fun
setNativeAd
(
nativeAd
:
NativeAd
?)
{
nativeAd
?:
return
val
adView
=
LayoutInflater
.
from
(
context
)
.
inflate
(
layout
,
this
,
false
)
as
NativeAdView
adView
.
mediaView
=
adView
.
findViewById
(
R
.
id
.
ad_media
)
adView
.
headlineView
=
adView
.
findViewById
(
R
.
id
.
ad_headline
)
adView
.
bodyView
=
adView
.
findViewById
(
R
.
id
.
ad_body
)
adView
.
callToActionView
=
adView
.
findViewById
(
R
.
id
.
ad_call_to_action
)
adView
.
iconView
=
adView
.
findViewById
(
R
.
id
.
ad_app_icon
)
(
adView
.
headlineView
as
TextView
?)
?.
text
=
nativeAd
.
headline
adView
.
mediaView
!!
.
mediaContent
=
nativeAd
.
mediaContent
if
(
nativeAd
.
body
==
null
)
{
adView
.
bodyView
!!
.
visibility
=
INVISIBLE
}
else
{
adView
.
bodyView
!!
.
visibility
=
VISIBLE
(
adView
.
bodyView
as
TextView
?)
?.
text
=
nativeAd
.
body
}
if
(
nativeAd
.
callToAction
==
null
)
{
adView
.
callToActionView
!!
.
visibility
=
INVISIBLE
}
else
{
adView
.
callToActionView
!!
.
visibility
=
VISIBLE
(
adView
.
callToActionView
as
Button
?)
?.
text
=
nativeAd
.
callToAction
}
if
(
nativeAd
.
icon
==
null
)
{
adView
.
iconView
!!
.
visibility
=
GONE
}
else
{
(
adView
.
iconView
as
ImageView
?)
?.
setImageDrawable
(
nativeAd
.
icon
!!
.
drawable
)
adView
.
iconView
!!
.
visibility
=
VISIBLE
}
adView
.
setNativeAd
(
nativeAd
)
removeAllViews
()
addView
(
adView
)
}
...
...
app/src/main/java/com/base/locationsharewhite/ads/admob/AdNativeMgr.kt
View file @
257ed5db
...
...
@@ -3,6 +3,7 @@ package com.base.locationsharewhite.ads.admob
import
android.content.Context
import
android.view.ViewGroup
import
androidx.core.view.isVisible
import
com.base.locationsharewhite.ads.NativeParentView
import
com.base.locationsharewhite.ads.AdsType
import
com.base.locationsharewhite.ads.ConstConfig
import
com.base.locationsharewhite.helper.EventUtils
...
...
@@ -32,7 +33,11 @@ class AdNativeMgr {
*/
private
val
cacheItems
=
ConcurrentLinkedDeque
<
NativeAd
>()
fun
loadAd
(
context
:
Context
,
parent
:
ViewGroup
?
=
null
,
layout
:
Int
?
=
null
)
{
fun
loadAd
(
context
:
Context
,
parent
:
NativeParentView
?
=
null
,
layout
:
Int
?
=
null
)
{
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
NATIVE
))
return
val
reqId
=
UUID
.
randomUUID
().
toString
()
...
...
@@ -69,7 +74,11 @@ class AdNativeMgr {
adLoader
.
loadAds
(
AdRequest
.
Builder
().
build
(),
1
)
}
fun
show
(
parent
:
ViewGroup
,
layout
:
Int
)
{
fun
show
(
parent
:
NativeParentView
,
layout
:
Int
,
nativeCallBack
:
((
Any
?)
->
Unit
)?
=
null
)
{
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
NATIVE
))
{
cacheItems
.
clear
()
LogEx
.
logDebug
(
"AdNativeMgr"
,
"0"
)
...
...
@@ -98,21 +107,16 @@ class AdNativeMgr {
loadAd
(
parent
.
context
.
applicationContext
,
parent
,
layout
)
return
}
nativeCallBack
?.
invoke
(
nativeAd
)
LogEx
.
logDebug
(
"AdNativeMgr"
,
"3"
)
val
obj
=
JSONObject
()
obj
.
put
(
"ad_unit"
,
"nativeAd"
)
EventUtils
.
event
(
"ad_prepare_show_native"
,
ext
=
obj
)
NativeView
(
parent
.
context
,
layout
).
run
{
parent
.
removeAllViews
()
setNativeAd
(
nativeAd
)
parent
.
addView
(
this
)
parent
.
isVisible
=
true
AdmobEvent
.
showAd
(
nativeAd
?.
responseInfo
,
"nativeAd"
)
}
loadAd
(
parent
.
context
.
applicationContext
)
parent
.
setNativeAd
(
nativeAd
!!
,
layout
)
AdmobEvent
.
showAd
(
nativeAd
.
responseInfo
,
"nativeAd"
)
}
fun
adAvailable
():
Boolean
{
private
fun
adAvailable
():
Boolean
{
return
((
System
.
currentTimeMillis
()
-
lastTime
)
/
1000
/
60
).
toInt
()
<
30
}
}
\ No newline at end of file
app/src/main/java/com/base/locationsharewhite/ads/admob/NativeView.kt
deleted
100644 → 0
View file @
9fb1d6e9
package
com.base.locationsharewhite.ads.admob
import
android.annotation.SuppressLint
import
android.content.Context
import
android.util.AttributeSet
import
android.view.LayoutInflater
import
android.view.View
import
android.view.ViewGroup
import
android.widget.Button
import
android.widget.FrameLayout
import
android.widget.ImageView
import
android.widget.TextView
import
com.base.locationsharewhite.R
import
com.google.android.gms.ads.nativead.NativeAd
import
com.google.android.gms.ads.nativead.NativeAdView
@SuppressLint
(
"ViewConstructor"
)
class
NativeView
(
context
:
Context
,
val
layout
:
Int
,
attrs
:
AttributeSet
?
=
null
)
:
FrameLayout
(
context
,
attrs
)
{
init
{
layoutParams
=
LayoutParams
(
ViewGroup
.
LayoutParams
.
MATCH_PARENT
,
ViewGroup
.
LayoutParams
.
WRAP_CONTENT
)
}
fun
setNativeAd
(
nativeAd
:
NativeAd
?)
{
nativeAd
?:
return
val
adView
=
LayoutInflater
.
from
(
context
)
.
inflate
(
layout
,
this
,
false
)
as
NativeAdView
adView
.
mediaView
=
adView
.
findViewById
(
R
.
id
.
ad_media
)
adView
.
headlineView
=
adView
.
findViewById
(
R
.
id
.
ad_headline
)
adView
.
bodyView
=
adView
.
findViewById
(
R
.
id
.
ad_body
)
adView
.
callToActionView
=
adView
.
findViewById
(
R
.
id
.
ad_call_to_action
)
adView
.
iconView
=
adView
.
findViewById
(
R
.
id
.
ad_app_icon
)
(
adView
.
headlineView
as
TextView
?)
?.
text
=
nativeAd
.
headline
adView
.
mediaView
!!
.
mediaContent
=
nativeAd
.
mediaContent
if
(
nativeAd
.
body
==
null
)
{
adView
.
bodyView
!!
.
visibility
=
View
.
INVISIBLE
}
else
{
adView
.
bodyView
!!
.
visibility
=
View
.
VISIBLE
(
adView
.
bodyView
as
TextView
?)
?.
text
=
nativeAd
.
body
}
if
(
nativeAd
.
callToAction
==
null
)
{
adView
.
callToActionView
!!
.
visibility
=
View
.
INVISIBLE
}
else
{
adView
.
callToActionView
!!
.
visibility
=
View
.
VISIBLE
(
adView
.
callToActionView
as
Button
?)
?.
text
=
nativeAd
.
callToAction
}
if
(
nativeAd
.
icon
==
null
)
{
adView
.
iconView
!!
.
visibility
=
View
.
GONE
}
else
{
(
adView
.
iconView
as
ImageView
?)
?.
setImageDrawable
(
nativeAd
.
icon
!!
.
drawable
)
adView
.
iconView
!!
.
visibility
=
View
.
VISIBLE
}
adView
.
setNativeAd
(
nativeAd
)
removeAllViews
()
addView
(
adView
)
}
}
\ No newline at end of file
app/src/main/java/com/base/locationsharewhite/ads/applovin/AdMaxEvent.kt
0 → 100644
View file @
257ed5db
package
com.base.locationsharewhite.ads.applovin
import
android.os.Bundle
import
com.applovin.mediation.MaxAd
import
com.applovin.mediation.MaxAdRevenueListener
import
com.applovin.mediation.MaxError
import
com.applovin.sdk.AppLovinSdk
import
com.base.locationsharewhite.helper.EventUtils
import
com.base.locationsharewhite.helper.MyApplication
import
com.facebook.FacebookSdk
import
com.facebook.appevents.AppEventsConstants
import
com.facebook.appevents.AppEventsLogger
import
com.google.firebase.analytics.FirebaseAnalytics
import
org.json.JSONObject
object
AdMaxEvent
{
fun
pullAd
(
ad
:
MaxAd
?,
adUnit
:
String
,
reqId
:
String
?
=
null
,
error
:
MaxError
?
=
null
)
{
val
obj
=
JSONObject
()
obj
.
put
(
"UnitId"
,
ad
?.
adUnitId
)
obj
.
put
(
"ad_unit"
,
adUnit
)
obj
.
put
(
"creativeId"
,
ad
?.
creativeId
)
obj
.
put
(
"req_id"
,
reqId
)
obj
.
put
(
"status"
,
if
(
ad
==
null
)
"0"
else
"1"
)
obj
.
put
(
"networkname"
,
ad
?.
networkName
)
obj
.
put
(
"placement"
,
ad
?.
placement
)
obj
.
put
(
"networkplacement"
,
ad
?.
networkPlacement
)
obj
.
put
(
"latency"
,
ad
?.
requestLatencyMillis
)
obj
.
put
(
"valueMicros"
,
ad
?.
revenue
)
if
(
error
==
null
)
{
obj
.
put
(
"status"
,
"1"
)
}
else
{
obj
.
put
(
"errMsg"
,
error
)
obj
.
put
(
"status"
,
"2"
)
}
EventUtils
.
event
(
"ad_pull"
,
ext
=
obj
)
}
fun
clickAd
(
ad
:
MaxAd
?,
adUnit
:
String
)
{
val
obj
=
JSONObject
()
obj
.
put
(
"UnitId"
,
ad
?.
adUnitId
)
obj
.
put
(
"ad_unit"
,
adUnit
)
obj
.
put
(
"creativeId"
,
ad
?.
creativeId
)
obj
.
put
(
"networkname"
,
ad
?.
networkName
)
obj
.
put
(
"placement"
,
ad
?.
placement
)
obj
.
put
(
"networkplacement"
,
ad
?.
networkPlacement
)
obj
.
put
(
"latency"
,
ad
?.
requestLatencyMillis
)
obj
.
put
(
"valueMicros"
,
ad
?.
revenue
)
if
(!
adUnit
.
equals
(
"nativeAd"
))
{
EventUtils
.
event
(
"ad_click"
,
ext
=
obj
)
}
else
{
EventUtils
.
event
(
"ad_click"
,
ext
=
obj
)
}
}
fun
showAd
(
ad
:
MaxAd
?,
adUnit
:
String
,
activity
:
String
?)
{
val
obj
=
JSONObject
()
obj
.
put
(
"UnitId"
,
ad
?.
adUnitId
)
obj
.
put
(
"ad_unit"
,
adUnit
)
obj
.
put
(
"creativeId"
,
ad
?.
creativeId
)
obj
.
put
(
"networkname"
,
ad
?.
networkName
)
obj
.
put
(
"placement"
,
ad
?.
placement
)
obj
.
put
(
"networkplacement"
,
ad
?.
networkPlacement
)
obj
.
put
(
"latency"
,
ad
?.
requestLatencyMillis
)
obj
.
put
(
"valueMicros"
,
ad
?.
revenue
)
obj
.
put
(
"from"
,
activity
)
obj
.
put
(
"mediation"
,
"applovin"
)
if
(
adUnit
!=
"nativeAd"
)
{
EventUtils
.
event
(
"ad_show"
,
ext
=
obj
)
}
else
{
EventUtils
.
event
(
"ad_show"
,
ext
=
obj
)
}
}
private
val
taichiPref
=
FacebookSdk
.
getApplicationContext
()
.
getSharedPreferences
(
"TaichiTroasCache"
,
0
)
private
val
taichiSharedPreferencesEditor
=
taichiPref
.
edit
()
class
EventOnPaidEventListener
:
MaxAdRevenueListener
{
override
fun
onAdRevenuePaid
(
ad
:
MaxAd
)
{
val
params
=
Bundle
()
val
currentImpressionRevenue
:
Double
=
ad
.
revenue
// In USD
val
mFirebaseAnalytics
=
FirebaseAnalytics
.
getInstance
(
MyApplication
.
appContext
)
params
.
putString
(
FirebaseAnalytics
.
Param
.
AD_PLATFORM
,
"appLovin"
)
params
.
putString
(
FirebaseAnalytics
.
Param
.
AD_SOURCE
,
ad
.
networkName
)
params
.
putString
(
FirebaseAnalytics
.
Param
.
AD_FORMAT
,
ad
.
format
.
getDisplayName
())
params
.
putString
(
FirebaseAnalytics
.
Param
.
AD_UNIT_NAME
,
ad
.
adUnitId
)
params
.
putDouble
(
FirebaseAnalytics
.
Param
.
VALUE
,
currentImpressionRevenue
)
params
.
putString
(
FirebaseAnalytics
.
Param
.
CURRENCY
,
"USD"
)
mFirebaseAnalytics
.
logEvent
(
FirebaseAnalytics
.
Event
.
AD_IMPRESSION
,
params
)
mFirebaseAnalytics
.
logEvent
(
"Ad_Impression_Revenue"
,
params
)
val
previousTaichiTroasCache
=
taichiPref
.
getFloat
(
"TaichiTroasCache"
,
0f
)
val
currentTaichiTroasCache
=
previousTaichiTroasCache
+
currentImpressionRevenue
if
(
currentTaichiTroasCache
>=
0.01
)
{
val
roasbundle
=
Bundle
()
roasbundle
.
putDouble
(
FirebaseAnalytics
.
Param
.
VALUE
,
currentTaichiTroasCache
)
roasbundle
.
putString
(
FirebaseAnalytics
.
Param
.
CURRENCY
,
"USD"
)
///(Required)tROAS事件必须
mFirebaseAnalytics
.
logEvent
(
"Total_Ads_Revenue_001"
,
roasbundle
)
// 给Taichi用
taichiSharedPreferencesEditor
.
putFloat
(
"TaichiTroasCache"
,
0f
)
//重新清零,开始计算
val
logger
=
AppEventsLogger
.
newLogger
(
MyApplication
.
appContext
)
val
parameters
=
Bundle
()
parameters
.
putString
(
AppEventsConstants
.
EVENT_PARAM_CURRENCY
,
"USD"
)
logger
.
logEvent
(
"ad_value"
,
currentTaichiTroasCache
,
parameters
)
}
else
{
taichiSharedPreferencesEditor
.
putFloat
(
"TaichiTroasCache"
,
currentTaichiTroasCache
.
toFloat
()
)
taichiSharedPreferencesEditor
.
commit
()
}
val
obj
=
JSONObject
()
val
revenue
=
ad
.
revenue
val
countryCode
=
AppLovinSdk
.
getInstance
(
MyApplication
.
appContext
).
configuration
.
countryCode
val
networkName
=
ad
.
networkName
val
adUnitId
=
ad
.
adUnitId
val
adFormat
=
ad
.
format
val
placement
=
ad
.
placement
val
networkPlacement
=
ad
.
networkPlacement
obj
.
put
(
"valueMicros"
,
revenue
)
obj
.
put
(
"currencyCode"
,
countryCode
)
obj
.
put
(
"adUnitId"
,
adUnitId
)
obj
.
put
(
"networkName"
,
networkName
)
obj
.
put
(
"adFormat"
,
adFormat
)
obj
.
put
(
"placement"
,
placement
)
obj
.
put
(
"networkPlacement"
,
networkPlacement
)
EventUtils
.
event
(
"ad_price"
,
ext
=
obj
)
}
}
}
\ No newline at end of file
app/src/main/java/com/base/locationsharewhite/ads/applovin/MaxInsertMgr.kt
View file @
257ed5db
...
...
@@ -37,9 +37,8 @@ class MaxInsertMgr : BaseAdMgr<MaxInterstitialAd>() {
currentAd
=
MaxInterstitialAd
(
ConstConfig
.
MAX_INSERT_UNIT_ID
,
context
)
currentAd
?.
setListener
(
object
:
MaxAdListener
{
override
fun
onAdLoaded
(
p0
:
MaxAd
)
{
// AdmobEvent.pullAd(ad.responseInfo, "interAd", reqId = reqId)
// ad.onPaidEventListener = AdmobEvent.EventOnPaidEventListener(ad)
override
fun
onAdLoaded
(
ad
:
MaxAd
)
{
AdMaxEvent
.
pullAd
(
ad
,
"interAd"
,
reqId
=
reqId
)
// 开屏广告加载成功
loadingAd
=
false
lastTime
=
System
.
currentTimeMillis
()
...
...
@@ -58,13 +57,9 @@ class MaxInsertMgr : BaseAdMgr<MaxInterstitialAd>() {
override
fun
onAdClicked
(
p0
:
MaxAd
)
{
}
override
fun
onAdLoadFailed
(
p0
:
String
,
p1
:
MaxError
)
{
// AdmobEvent.pullAd(
// loadAdError.responseInfo,
// "interAd",
// loadAdError.message,
// reqId = reqId
// )
override
fun
onAdLoadFailed
(
ad
:
String
,
error
:
MaxError
)
{
AdMaxEvent
.
pullAd
(
null
,
"interAd"
,
reqId
,
error
)
// 广告加载失败
// 官方不建议在此回调中重新加载广告
loadingAd
=
false
...
...
@@ -87,13 +82,16 @@ class MaxInsertMgr : BaseAdMgr<MaxInterstitialAd>() {
showCallBack
?.
failed
()
return
}
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
INSERT
))
{
showCallBack
?.
failed
()
return
}
if
(
LimitUtils
.
isIntervalLimited
(
lastOpenDate
))
{
showCallBack
?.
failed
()
return
if
(!
isUnLimit
)
{
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
INSERT
))
{
showCallBack
?.
failed
()
return
}
if
(
LimitUtils
.
isIntervalLimited
(
lastOpenDate
))
{
showCallBack
?.
failed
()
return
}
}
if
(
showingAd
)
{
// 开屏广告正在展示
...
...
@@ -120,7 +118,7 @@ class MaxInsertMgr : BaseAdMgr<MaxInterstitialAd>() {
if
(
activityRef
==
null
)
{
activityRef
=
WeakReference
(
activity
)
// 开屏广告不可用或者缓存超时过期,重新加载
loadAd
(
activity
.
applicationContext
,
isUnLimit
)
loadAd
(
activity
,
isUnLimit
)
}
else
{
activityRef
=
null
this
.
showCallBack
?.
failed
()
...
...
@@ -140,13 +138,13 @@ class MaxInsertMgr : BaseAdMgr<MaxInterstitialAd>() {
override
fun
onAdLoaded
(
p0
:
MaxAd
)
{
}
override
fun
onAdDisplayed
(
p0
:
MaxAd
)
{
override
fun
onAdDisplayed
(
ad
:
MaxAd
)
{
lastOpenDate
=
System
.
currentTimeMillis
()
// 广告展示
currentAd
=
null
activityRef
=
null
this
@MaxInsertMgr
.
showCallBack
?.
show
()
// AdmobEvent.showAd(this@run.responseInfo, "interAd", activity
)
AdMaxEvent
.
showAd
(
ad
,
"interAd"
,
activity
::
class
.
simpleName
)
//计数
LimitUtils
.
addDisplayNum
()
}
...
...
@@ -160,8 +158,8 @@ class MaxInsertMgr : BaseAdMgr<MaxInterstitialAd>() {
loadAd
(
activity
.
applicationContext
)
}
override
fun
onAdClicked
(
p0
:
MaxAd
)
{
// AdmobEvent.clickAd(this@run.responseInfo
, "interAd")
override
fun
onAdClicked
(
ad
:
MaxAd
)
{
AdMaxEvent
.
clickAd
(
ad
,
"interAd"
)
//计数
LimitUtils
.
addClickNum
()
}
...
...
@@ -185,6 +183,7 @@ class MaxInsertMgr : BaseAdMgr<MaxInterstitialAd>() {
}
})
setRevenueListener
(
AdMaxEvent
.
EventOnPaidEventListener
())
showingAd
=
true
showAd
(
activity
)
}
...
...
app/src/main/java/com/base/locationsharewhite/ads/applovin/MaxNativeMgr.kt
View file @
257ed5db
...
...
@@ -9,7 +9,7 @@ import com.applovin.mediation.nativeAds.MaxNativeAdLoader
import
com.applovin.mediation.nativeAds.MaxNativeAdView
import
com.base.locationsharewhite.ads.AdsType
import
com.base.locationsharewhite.ads.ConstConfig
import
com.base.locationsharewhite.ads.
CustomParentNative
View
import
com.base.locationsharewhite.ads.
NativeParent
View
import
com.base.locationsharewhite.ads.admob.LimitUtils
import
com.base.locationsharewhite.helper.EventUtils
import
org.json.JSONObject
...
...
@@ -31,7 +31,8 @@ class MaxNativeMgr {
private
var
currentAd
:
MaxAd
?
=
null
private
var
currentLoader
:
MaxNativeAdLoader
?
=
null
fun
loadAd
(
context
:
Context
,
parent
:
CustomParentNativeView
?
=
null
,
@LayoutRes
layout
:
Int
?
=
null
)
{
fun
loadAd
(
context
:
Context
,
parent
:
NativeParentView
?
=
null
,
@LayoutRes
layout
:
Int
?
=
null
)
{
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
NATIVE
))
return
val
reqId
=
UUID
.
randomUUID
().
toString
()
...
...
@@ -40,29 +41,35 @@ class MaxNativeMgr {
obj
.
put
(
"ad_type"
,
"nativeAd"
)
val
nativeAdLoader
=
MaxNativeAdLoader
(
ConstConfig
.
MAX_NATIVE_UNIT_ID
,
context
)
nativeAdLoader
.
setNativeAdListener
(
object
:
MaxNativeAdListener
()
{
override
fun
onNativeAdLoaded
(
nativeAdView
:
MaxNativeAdView
?,
ad
:
MaxAd
)
{
currentLoader
=
nativeAdLoader
currentAd
=
ad
lastTime
=
System
.
currentTimeMillis
()
// nativeAd.setOnPaidEventListener(AdmobEvent.EventOnPaidEventListener(nativeAd)
)
// AdmobEvent.pullAd(nativeAd.responseInfo, "nativeAd", reqId = reqId
)
AdMaxEvent
.
pullAd
(
ad
,
"nativeAd"
,
reqId
=
reqId
)
nativeAdLoader
.
setRevenueListener
(
AdMaxEvent
.
EventOnPaidEventListener
()
)
if
(
parent
!=
null
&&
layout
!=
null
)
show
(
parent
,
layout
)
}
override
fun
onNativeAdLoadFailed
(
adUnitId
:
String
,
error
:
MaxError
)
{
AdMaxEvent
.
pullAd
(
null
,
"nativeAd"
,
reqId
=
reqId
,
error
)
}
override
fun
onNativeAdClicked
(
ad
:
MaxAd
)
{
}
})
nativeAdLoader
.
loadAd
()
}
fun
show
(
parent
:
CustomParentNativeView
,
@LayoutRes
layout
:
Int
?
=
null
)
{
fun
show
(
parent
:
NativeParentView
,
@LayoutRes
layout
:
Int
,
nativeCallBack
:
((
Any
?)
->
Unit
)?
=
null
)
{
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
NATIVE
))
{
currentLoader
=
null
currentAd
=
null
...
...
@@ -92,12 +99,12 @@ class MaxNativeMgr {
}
val
obj
=
JSONObject
()
obj
.
put
(
"ad_unit"
,
"nativeAd"
)
EventUtils
.
event
(
"ad_prepare_show
_native
"
,
ext
=
obj
)
EventUtils
.
event
(
"ad_prepare_show"
,
ext
=
obj
)
parent
.
setNativeAd
(
nativeLoader
!!
,
nativeAd
!!
,
layout
)
// loadAd(parent.context.applicationContext
)
nativeCallBack
?.
invoke
(
nativeAd
)
}
fun
adAvailable
():
Boolean
{
private
fun
adAvailable
():
Boolean
{
return
((
System
.
currentTimeMillis
()
-
lastTime
)
/
1000
/
60
).
toInt
()
<
30
}
}
\ No newline at end of file
app/src/main/java/com/base/locationsharewhite/ads/applovin/MaxOpenMgr.kt
View file @
257ed5db
...
...
@@ -36,16 +36,14 @@ class MaxOpenMgr : BaseAdMgr<MaxAppOpenAd>() {
currentAd
=
MaxAppOpenAd
(
ConstConfig
.
MAX_OPEN_UNIT_ID
,
context
)
currentAd
?.
setListener
(
object
:
MaxAdListener
{
override
fun
onAdLoaded
(
p0
:
MaxAd
)
{
override
fun
onAdLoaded
(
ad
:
MaxAd
)
{
loadingAd
=
false
lastTime
=
System
.
currentTimeMillis
()
val
ac
=
activityRef
?.
get
()
if
(
ac
!=
null
)
{
show
(
ac
,
isUnLimit
=
isUnLimit
)
}
// AdmobEvent.pullAd(appOpenAd.responseInfo, "openAd", reqId = reqId)
// appOpenAd.onPaidEventListener =
// AdmobEvent.EventOnPaidEventListener(appOpenAd)
AdMaxEvent
.
pullAd
(
ad
,
"openAd"
,
reqId
)
}
override
fun
onAdDisplayed
(
p0
:
MaxAd
)
{
...
...
@@ -59,18 +57,13 @@ class MaxOpenMgr : BaseAdMgr<MaxAppOpenAd>() {
override
fun
onAdClicked
(
p0
:
MaxAd
)
{
}
override
fun
onAdLoadFailed
(
p0
:
String
,
p1
:
MaxError
)
{
override
fun
onAdLoadFailed
(
p0
:
String
,
error
:
MaxError
)
{
loadingAd
=
false
if
(
activityRef
!=
null
&&
!
showingAd
&&
showCallBack
!=
null
)
{
showCallBack
?.
googleFailed
()
showCallBack
=
null
}
// AdmobEvent.pullAd(
// loadAdError.responseInfo,
// "openAd",
// loadAdError.message,
// reqId = reqId
// )
AdMaxEvent
.
pullAd
(
null
,
"openAd"
,
reqId
,
error
)
}
override
fun
onAdDisplayFailed
(
p0
:
MaxAd
,
p1
:
MaxError
)
{
...
...
@@ -145,7 +138,7 @@ class MaxOpenMgr : BaseAdMgr<MaxAppOpenAd>() {
}
override
fun
onAdDisplayed
(
p0
:
MaxAd
)
{
override
fun
onAdDisplayed
(
ad
:
MaxAd
)
{
lastOpenDate
=
System
.
currentTimeMillis
()
// 广告展示
currentAd
=
null
...
...
@@ -153,7 +146,8 @@ class MaxOpenMgr : BaseAdMgr<MaxAppOpenAd>() {
this
@MaxOpenMgr
.
showCallBack
?.
show
()
//计数
LimitUtils
.
addDisplayNum
()
// AdmobEvent.showAd(this@run.responseInfo, "openAd", activity)
AdMaxEvent
.
showAd
(
ad
,
"openAd"
,
activity
::
class
.
simpleName
)
currentAd
?.
setRevenueListener
(
AdMaxEvent
.
EventOnPaidEventListener
())
}
override
fun
onAdHidden
(
p0
:
MaxAd
)
{
...
...
@@ -164,8 +158,8 @@ class MaxOpenMgr : BaseAdMgr<MaxAppOpenAd>() {
loadAd
(
activity
.
applicationContext
)
}
override
fun
onAdClicked
(
p0
:
MaxAd
)
{
// AdmobEvent.clickAd(this@run.responseInfo
, "openAd")
override
fun
onAdClicked
(
ad
:
MaxAd
)
{
AdMaxEvent
.
clickAd
(
ad
,
"openAd"
)
//计数
LimitUtils
.
addClickNum
()
}
...
...
app/src/main/java/com/base/locationsharewhite/config/AdConfigBean.kt
0 → 100644
View file @
257ed5db
package
com.base.locationsharewhite.config
class
AdConfigBean
(
var
adSwitch
:
Boolean
=
true
,
var
numDisplayLimit
:
Int
=
-
1
,
var
numRequestLimit
:
Int
=
-
1
,
var
numClickLimit
:
Int
=
-
1
,
var
timeInterval
:
Int
=
1
,
var
openAdLoading
:
Int
=
15
,
)
\ No newline at end of file
app/src/main/java/com/base/locationsharewhite/config/ConfigBean.kt
0 → 100644
View file @
257ed5db
package
com.base.locationsharewhite.config
/**
* 后台配置
*/
data class
ConfigBean
(
var
isInBlackList
:
Boolean
=
false
,
val
ut
:
Int
=
0
,
val
adConfigBean
:
AdConfigBean
=
AdConfigBean
(),
val
popupConfigBean
:
PopupConfigBean
=
PopupConfigBean
(),
)
{
companion
object
{
var
configBean
:
ConfigBean
=
ConfigBean
()
}
}
\ No newline at end of file
app/src/main/java/com/base/locationsharewhite/config/PopupConfigBean.kt
0 → 100644
View file @
257ed5db
package
com.base.locationsharewhite.config
class
PopupConfigBean
(
var
popupStatus
:
Boolean
=
true
,
var
popupCount
:
Int
=
0
,
var
popupStart
:
Int
=
0
,
var
popupEnd
:
Int
=
24
,
var
popupInterval
:
Int
=
1
,
var
popupTimerInterval
:
Int
=
1
,
var
popupFcmInterval
:
Int
=
1
,
var
popupHoverStatus
:
Boolean
=
true
,
var
popupHoverCount
:
Int
=
5
,
var
popupHoverDelay
:
Int
=
5000
,
//定时器
var
timerS
:
Boolean
=
true
,
var
timerDelay
:
Int
=
1
,
var
timerInterval
:
Int
=
1
,
//解锁
var
screenS
:
Boolean
=
true
,
var
popupScreenCount
:
Int
=
20
,
var
popupScreenInterval
:
Int
=
1
,
//电量
var
batteryS
:
Boolean
=
true
,
var
popupBatteryValue
:
Int
=
20
,
var
popupBatteryInterval
:
Int
=
1
,
//安装卸载
var
packageS
:
Boolean
=
true
,
var
popupPackageCount
:
Int
=
20
,
var
popupPackageInterval
:
Int
=
1
)
\ No newline at end of file
app/src/main/java/com/base/locationsharewhite/fcm/BatteryStatusReceiver.kt
View file @
257ed5db
...
...
@@ -7,8 +7,7 @@ import android.content.IntentFilter
import
android.os.BatteryManager
import
android.os.Build
import
com.base.locationsharewhite.fcm.PopupConstObject.POPUP_WHERE_BATTERY
import
com.base.locationsharewhite.fcm.PopupConstObject.popup_battery_count
import
com.base.locationsharewhite.fcm.PopupConstObject.popup_battery_interval
import
com.base.locationsharewhite.fcm.PopupConstObject.popupConfigBean
import
com.base.locationsharewhite.helper.EventUtils
import
com.base.locationsharewhite.utils.AppPreferences
import
com.base.locationsharewhite.utils.KotlinExt.currentDate
...
...
@@ -72,13 +71,14 @@ class BatteryStatusReceiver() : BroadcastReceiver() {
*/
fun
canBatteryStatusReceiverPush
():
Boolean
{
val
popupBatteryCount
=
AppPreferences
.
getInstance
().
getString
(
popup_battery_count
,
"20"
).
toInt
()
if
(!
popupConfigBean
.
batteryS
)
return
false
val
popupBatteryCount
=
popupConfigBean
.
popupBatteryValue
val
flag1
=
todayBatteryPush
<=
popupBatteryCount
val
minute
=
60
*
1000L
val
default
=
60
*
minute
val
interval
=
AppPreferences
.
getInstance
().
getString
(
popup_battery_interval
,
default
.
toString
()).
toLong
()
val
interval
=
popupConfigBean
.
popupBatteryInterval
val
passTime
=
System
.
currentTimeMillis
()
-
batteryLastPushTime
val
flag2
=
batteryLastPushTime
==
0L
||
passTime
>
interval
*
minute
...
...
app/src/main/java/com/base/locationsharewhite/fcm/NotificationHoverUtils.kt
View file @
257ed5db
...
...
@@ -3,11 +3,8 @@ package com.base.locationsharewhite.fcm
import
android.content.Context
import
android.os.Handler
import
android.os.HandlerThread
import
com.base.locationsharewhite.fcm.PopupConstObject.popup_hover_count
import
com.base.locationsharewhite.fcm.PopupConstObject.popup_hover_delay
import
com.base.locationsharewhite.fcm.PopupConstObject.popup_hover_status
import
com.base.locationsharewhite.fcm.PopupConstObject.popupConfigBean
import
com.base.locationsharewhite.helper.MyApplication
import
com.base.locationsharewhite.utils.AppPreferences
import
com.base.locationsharewhite.utils.LogEx
object
NotificationHoverUtils
{
...
...
@@ -21,10 +18,10 @@ object NotificationHoverUtils {
*/
fun
sendHoverNotification
(
context
:
Context
,
where
:
String
=
""
)
{
val
hover
Count
=
AppPreferences
.
getInstance
().
getString
(
popup_hover_count
,
"0"
).
toInt
()
val
hover
Delay
=
AppPreferences
.
getInstance
().
getString
(
popup_hover_delay
,
"0"
).
toLong
()
val
hover
Status
=
AppPreferences
.
getInstance
().
getString
(
popup_hover_status
,
"0"
).
toInt
()
if
(
hoverStatus
==
0
)
return
val
hover
Status
=
popupConfigBean
.
popupHoverStatus
val
hover
Count
=
popupConfigBean
.
popupHoverCount
val
hover
Delay
=
popupConfigBean
.
popupHoverDelay
.
toLong
()
if
(
hoverStatus
)
return
if
(
handlerThread
==
null
)
{
handlerThread
=
HandlerThread
(
"NotificationHandlerThread"
)
...
...
app/src/main/java/com/base/locationsharewhite/fcm/NotificationUiUtil.kt
View file @
257ed5db
...
...
@@ -25,13 +25,7 @@ import com.base.locationsharewhite.fcm.PopupConstObject.POPUP_WHERE_FCM
import
com.base.locationsharewhite.fcm.PopupConstObject.POPUP_WHERE_LOCK
import
com.base.locationsharewhite.fcm.PopupConstObject.POPUP_WHERE_PACKAGE
import
com.base.locationsharewhite.fcm.PopupConstObject.POPUP_WHERE_TIMBER
import
com.base.locationsharewhite.fcm.PopupConstObject.popup_count
import
com.base.locationsharewhite.fcm.PopupConstObject.popup_end
import
com.base.locationsharewhite.fcm.PopupConstObject.popup_fcm_interval
import
com.base.locationsharewhite.fcm.PopupConstObject.popup_interval
import
com.base.locationsharewhite.fcm.PopupConstObject.popup_start
import
com.base.locationsharewhite.fcm.PopupConstObject.popup_status
import
com.base.locationsharewhite.fcm.PopupConstObject.popup_timer_interval
import
com.base.locationsharewhite.fcm.PopupConstObject.popupConfigBean
import
com.base.locationsharewhite.helper.EventUtils
import
com.base.locationsharewhite.helper.MyApplication
import
com.base.locationsharewhite.ui.main.MainActivity
...
...
@@ -81,22 +75,22 @@ object NotificationUiUtil {
private
fun
canSendNotification
(
where
:
String
,
actionId
:
String
):
Boolean
{
//是否开启推送
val
status
=
AppPreferences
.
getInstance
().
getString
(
popup_status
,
"1"
).
toInt
()
if
(
status
==
0
)
{
EventUtils
.
event
(
"Notification_Error"
,
"status=$
status
"
)
if
(
!
popupConfigBean
.
popupStatus
)
{
EventUtils
.
event
(
"Notification_Error"
,
"status=$
{popupConfigBean.popupStatus}
"
)
LogEx
.
logDebug
(
"canSendNotification"
,
"status"
)
return
false
}
//当天推送次数
val
count
=
AppPreferences
.
getInstance
().
getString
(
popup_count
,
"20"
).
toInt
()
val
count
=
popupConfigBean
.
popupCount
if
(
dayPopupCount
>
count
)
{
LogEx
.
logDebug
(
"canSendNotification"
,
"count"
)
EventUtils
.
event
(
"Notification_Error"
,
"dayPopupCount=$dayPopupCount count=$count where=$where actionId=$actionId"
)
return
false
}
//判断是否在时间区域
val
start
=
AppPreferences
.
getInstance
().
getString
(
popup_start
,
"0"
).
toInt
()
val
end
=
AppPreferences
.
getInstance
().
getString
(
popup_end
,
"24"
).
toInt
()
val
start
=
popupConfigBean
.
popupStart
val
end
=
popupConfigBean
.
popupEnd
val
calendar
=
Calendar
.
getInstance
()
val
currentHour
=
calendar
.
get
(
Calendar
.
HOUR_OF_DAY
)
if
(
currentHour
!
in
start
until
end
)
{
...
...
@@ -106,12 +100,12 @@ object NotificationUiUtil {
}
//单位分钟
var
interval
=
AppPreferences
.
getInstance
().
getString
(
popup_interval
,
"1"
).
toInt
()
var
interval
=
popupConfigBean
.
popupInterval
if
(
where
==
POPUP_WHERE_TIMBER
)
{
interval
=
AppPreferences
.
getInstance
().
getString
(
popup_timer_interval
,
"7"
).
toInt
()
interval
=
popupConfigBean
.
popupTimerInterval
}
if
(
where
==
POPUP_WHERE_FCM
)
{
interval
=
AppPreferences
.
getInstance
().
getString
(
popup_fcm_interval
,
"1"
).
toInt
()
interval
=
popupConfigBean
.
popupFcmInterval
}
val
passedTime
=
System
.
currentTimeMillis
()
-
lastPopupTime
if
(
passedTime
<
interval
*
60
*
1000L
)
{
...
...
@@ -166,7 +160,6 @@ object NotificationUiUtil {
private
fun
canOtherSend
(
where
:
String
,
actionId
:
String
):
Boolean
{
var
canPush
=
true
if
(
where
==
POPUP_WHERE_BATTERY
)
{
canPush
=
BatteryStatusReceiver
.
canBatteryStatusReceiverPush
()
}
...
...
@@ -193,7 +186,7 @@ object NotificationUiUtil {
val
intent
=
Intent
(
context
,
SplashActivity
::
class
.
java
)
intent
.
putExtra
(
"actionId"
,
actionId
)
//
when
(
actionId
)
{
ACTION_1
->
{
val
desc
=
"Your journey awaits! Share your adventures and reconnect with friends."
...
...
app/src/main/java/com/base/locationsharewhite/fcm/PackageStatusReceiver.kt
View file @
257ed5db
...
...
@@ -6,8 +6,7 @@ import android.content.Intent
import
android.content.IntentFilter
import
android.os.Build
import
com.base.locationsharewhite.fcm.PopupConstObject.POPUP_WHERE_PACKAGE
import
com.base.locationsharewhite.fcm.PopupConstObject.popup_package_count
import
com.base.locationsharewhite.fcm.PopupConstObject.popup_package_interval
import
com.base.locationsharewhite.fcm.PopupConstObject.popupConfigBean
import
com.base.locationsharewhite.helper.EventUtils
import
com.base.locationsharewhite.utils.AppPreferences
import
com.base.locationsharewhite.utils.KotlinExt.currentDate
...
...
@@ -20,7 +19,7 @@ class PackageStatusReceiver() : BroadcastReceiver() {
private
val
TAG
=
"PackageStatusReceiver"
fun
registerPackageStatusReceiver
(
context
:
Context
)
{
LogEx
.
logDebug
(
TAG
,
"registerPackageStatusReceiver"
)
LogEx
.
logDebug
(
TAG
,
"registerPackageStatusReceiver"
)
val
intentFilter
=
IntentFilter
().
apply
{
addAction
(
Intent
.
ACTION_PACKAGE_ADDED
)
addAction
(
Intent
.
ACTION_PACKAGE_REMOVED
)
...
...
@@ -67,12 +66,14 @@ class PackageStatusReceiver() : BroadcastReceiver() {
* 总的限制条件判断后才判断
*/
fun
canPackageStatusReceiverPush
():
Boolean
{
val
popupPackageCount
=
AppPreferences
.
getInstance
().
getString
(
popup_package_count
,
"20"
).
toInt
()
if
(!
popupConfigBean
.
packageS
)
return
false
val
popupPackageCount
=
popupConfigBean
.
popupPackageCount
val
flag1
=
todayPackagePush
<=
popupPackageCount
val
minute
=
60
*
1000L
val
default
=
1
*
minute
val
interval
=
AppPreferences
.
getInstance
().
getString
(
popup_package_interval
,
default
.
toString
()).
toLong
()
val
interval
=
popupConfigBean
.
popupPackageInterval
val
passTime
=
System
.
currentTimeMillis
()
-
packageLastPushTime
val
flag2
=
packageLastPushTime
==
0L
||
passTime
>
interval
*
minute
...
...
app/src/main/java/com/base/locationsharewhite/fcm/PopupConstObject.kt
View file @
257ed5db
package
com.base.locationsharewhite.fcm
import
com.base.locationsharewhite.config.PopupConfigBean
import
org.json.JSONObject
object
PopupConstObject
{
...
...
@@ -11,43 +12,7 @@ object PopupConstObject {
const
val
POPUP_WHERE_ALARM
=
"Alarm"
const
val
POPUP_WHERE_BATTERY
=
"battery"
const
val
POPUP_WHERE_PACKAGE
=
"package"
const
val
POPUP_WHERE_WORK_MANAGER
=
"workmanager"
const
val
POPUP_WHERE_HOVER_HANDLE
=
"hover_handle"
//悬停调用
//推送总开关 0 关 1开
const
val
popup_status
=
"popup_status"
//推送总数量现在
const
val
popup_count
=
"popup_count"
//所有常规推送的当日推送次数限制,0 为不限制
const
val
popup_start
=
"popup_start"
const
val
popup_end
=
"popup_end"
const
val
popup_interval
=
"popup_interval"
const
val
popup_timer_interval
=
"popup_timber_interval"
const
val
popup_fcm_interval
=
"popup_fcm_interval"
const
val
popup_hover_status
=
"popup_hover_status"
const
val
popup_hover_count
=
"popup_hover_count"
const
val
popup_hover_delay
=
"popup_hover_delay"
//定时器
const
val
timerS
=
"timerS"
const
val
timerDelay
=
"timerDelay"
const
val
timerInterval
=
"timerInterval"
//电量可配置值
const
val
popup_battery_count
=
"popup_battery_count"
const
val
popup_battery_interval
=
"popup_battery_interval"
//安装卸载可配置值
const
val
popup_package_count
=
"popup_package_count"
const
val
popup_package_interval
=
"popup_package_interval"
//解锁可配置值
const
val
lockS
=
"lockS"
const
val
popup_screen_count
=
"popup_screen_count"
const
val
popup_screen_interval
=
"popup_screen_interval"
const
val
ACTION_STAY_HOME
=
"action_stay_home"
...
...
@@ -64,35 +29,5 @@ object PopupConstObject {
const
val
ACTION_6
=
"action_6"
const
val
ACTION_7
=
"action_7"
fun
createDefaultPopupJson
():
JSONObject
{
val
json
=
JSONObject
()
//通知总的条件
json
.
put
(
popup_status
,
"1"
)
json
.
put
(
popup_start
,
"0"
)
json
.
put
(
popup_end
,
"24"
)
json
.
put
(
popup_interval
,
"1"
)
json
.
put
(
popup_timer_interval
,
"7"
)
json
.
put
(
popup_fcm_interval
,
"1"
)
json
.
put
(
popup_hover_status
,
"1"
)
json
.
put
(
popup_hover_count
,
"4"
)
json
.
put
(
popup_hover_delay
,
"1000"
)
json
.
put
(
timerS
,
"1"
)
json
.
put
(
timerDelay
,
"1"
)
json
.
put
(
timerInterval
,
"1"
)
json
.
put
(
popup_battery_count
,
"20"
)
json
.
put
(
popup_battery_interval
,
"60"
)
json
.
put
(
popup_package_count
,
"20"
)
json
.
put
(
popup_package_interval
,
"1"
)
json
.
put
(
lockS
,
"1"
)
json
.
put
(
popup_screen_count
,
"20"
)
json
.
put
(
popup_screen_interval
,
"1"
)
return
json
}
var
popupConfigBean
:
PopupConfigBean
=
PopupConfigBean
()
}
\ No newline at end of file
app/src/main/java/com/base/locationsharewhite/fcm/ScreenStatusReceiver.kt
View file @
257ed5db
...
...
@@ -7,9 +7,7 @@ import android.content.IntentFilter
import
android.os.Build
import
com.base.locationsharewhite.fcm.NotificationUiUtil.sendNotificationIfCan
import
com.base.locationsharewhite.fcm.PopupConstObject.POPUP_WHERE_LOCK
import
com.base.locationsharewhite.fcm.PopupConstObject.lockS
import
com.base.locationsharewhite.fcm.PopupConstObject.popup_screen_count
import
com.base.locationsharewhite.fcm.PopupConstObject.popup_screen_interval
import
com.base.locationsharewhite.fcm.PopupConstObject.popupConfigBean
import
com.base.locationsharewhite.helper.EventUtils
import
com.base.locationsharewhite.utils.AppPreferences
import
com.base.locationsharewhite.utils.KotlinExt.currentDate
...
...
@@ -31,8 +29,7 @@ class ScreenStatusReceiver : BroadcastReceiver() {
Intent
.
ACTION_USER_PRESENT
->
{
isSecureLockActive
=
false
if
(
isDeviceInteractive
&&
!
isSecureLockActive
)
{
val
secureSetting
=
AppPreferences
.
getInstance
().
getString
(
lockS
,
"1"
).
toInt
()
if
(
secureSetting
==
1
)
{
if
(
popupConfigBean
.
screenS
)
{
sendNotificationIfCan
(
context
,
POPUP_WHERE_LOCK
,
null
)
}
}
...
...
@@ -92,13 +89,13 @@ class ScreenStatusReceiver : BroadcastReceiver() {
* 总的限制条件判断后才判断
*/
fun
canScreenStatusReceiverPush
():
Boolean
{
val
popupScreenCount
=
AppPreferences
.
getInstance
().
getString
(
popup_screen_count
,
"20"
).
toInt
()
if
(!
popupConfigBean
.
popupStatus
)
return
false
val
popupScreenCount
=
popupConfigBean
.
popupScreenCount
val
flag1
=
todayScreenPush
<=
popupScreenCount
val
minute
=
60
*
1000L
val
default
=
1
*
minute
val
interval
=
AppPreferences
.
getInstance
().
getString
(
popup_screen_interval
,
default
.
toString
()).
toLong
()
val
interval
=
popupConfigBean
.
popupScreenInterval
val
passTime
=
System
.
currentTimeMillis
()
-
screenLastPushTime
val
flag2
=
screenLastPushTime
==
0L
||
passTime
>
interval
*
minute
...
...
app/src/main/java/com/base/locationsharewhite/fcm/TimerManager.kt
View file @
257ed5db
package
com.base.locationsharewhite.fcm
import
com.base.locationsharewhite.fcm.NotificationUiUtil.sendNotificationIfCan
import
com.base.locationsharewhite.fcm.PopupConstObject.timerDelay
import
com.base.locationsharewhite.fcm.PopupConstObject.timerInterval
import
com.base.locationsharewhite.fcm.PopupConstObject.timerS
import
com.base.locationsharewhite.fcm.PopupConstObject.popupConfigBean
import
com.base.locationsharewhite.helper.MyApplication
import
com.base.locationsharewhite.utils.AppPreferences
import
com.base.locationsharewhite.utils.LogEx.logDebug
import
java.util.Timer
import
java.util.TimerTask
...
...
@@ -62,12 +59,12 @@ class TimerManager private constructor() {
fun
changeTimer
()
{
val
timerStatus
:
Int
=
AppPreferences
.
getInstance
().
getString
(
timerS
,
"1"
).
toIntOrNull
()
?:
1
if
(
timerStatus
==
0
)
{
if
(
!
popupConfigBean
.
timerS
)
{
instance
.
stopTaskTimer
()
}
else
{
val
timerDelay
:
Int
=
AppPreferences
.
getInstance
().
getString
(
timerDelay
,
"1"
).
toIntOrNull
()
?:
1
val
timerInterval
:
Int
=
AppPreferences
.
getInstance
().
getString
(
timerInterval
,
"1"
).
toIntOrNull
()
?:
1
val
timerDelay
:
Int
=
popupConfigBean
.
timerDelay
val
timerInterval
:
Int
=
popupConfigBean
.
timerInterval
val
isTaskTimerActive
=
instance
.
isTaskTimerActive
if
(!
isTaskTimerActive
)
{
...
...
app/src/main/java/com/base/locationsharewhite/helper/MyApplication.kt
View file @
257ed5db
...
...
@@ -8,7 +8,7 @@ import android.content.Intent
import
android.os.Bundle
import
android.text.TextUtils
import
android.util.Log
import
com.base.locationsharewhite.
ads.Ads
ConfigBean
import
com.base.locationsharewhite.
config.
ConfigBean
import
com.base.locationsharewhite.ads.AdsMgr
import
com.base.locationsharewhite.bean.ConstObject.appLanguageCountrySp
import
com.base.locationsharewhite.bean.ConstObject.appLanguageSp
...
...
@@ -22,8 +22,10 @@ import com.base.locationsharewhite.ui.splash.SplashActivity
import
com.base.locationsharewhite.utils.AppPreferences
import
com.base.locationsharewhite.utils.LogEx
import
com.facebook.FacebookSdk
import
com.google.gson.Gson
import
com.hjq.language.MultiLanguages
import
com.hjq.language.OnLanguageListener
import
org.json.JSONObject
import
java.util.Locale
import
java.util.UUID
...
...
@@ -98,13 +100,6 @@ class MyApplication : Application() {
startJob
()
startAlarm
(
appContext
)
// val popupJson = createDefaultPopupJson()
// val adJson = createDefaultAdJson()
// val allJons = adJson.pullAll(popupJson)
// LogEx.logDebug(TAG, "allJons=$allJons")
}
...
...
@@ -177,9 +172,23 @@ class MyApplication : Application() {
}
private
fun
initAdSdk
()
{
val
adsConfigBean
=
AdsConfigBean
.
getSpConfigBean
()
//初始化广告相关业务
AdsMgr
.
init
(
appContext
,
adsConfigBean
)
NewComUtils
.
requestCfg
{
config
->
Log
.
e
(
"requestCfg"
,
"config=$config"
)
val
configBean
=
Gson
().
fromJson
(
config
,
ConfigBean
::
class
.
java
)
Log
.
e
(
"requestCfg"
,
"configBean=$configBean"
)
val
jsonObject
=
JSONObject
()
jsonObject
.
put
(
"ut"
,
configBean
.
ut
)
EventUtils
.
event
(
"user_type"
,
ext
=
jsonObject
)
//广告
AdsMgr
.
adsConfigBean
=
configBean
.
adConfigBean
//初始化广告相关业务
AdsMgr
.
init
(
appContext
)
}
}
}
\ No newline at end of file
app/src/main/java/com/base/locationsharewhite/helper/NewComUtils.kt
View file @
257ed5db
...
...
@@ -37,17 +37,17 @@ object NewComUtils {
AppPreferences
.
getInstance
().
getString
(
"gid"
,
""
)
}&
aid
=
$
{
AppPreferences
.
getInstance
().
getString
(
"uuid"
,
""
)}
"
// mode =3 google mode=2 facebook mode=1 自然,mode=4 测试
// &mode=3
}
fun
requestCfg
(
callback
:
()
->
Unit
)
{
fun
requestCfg
(
callback
:
(
json
:
String
?
)
->
Unit
)
{
CoroutineScope
(
Dispatchers
.
IO
).
launch
{
val
response
=
doGet
()
if
(
response
==
null
)
{
withContext
(
Dispatchers
.
Main
)
{
callback
()
callback
(
null
)
}
return
@launch
}
...
...
@@ -55,15 +55,14 @@ object NewComUtils {
val
data
=
extractData
(
response
)
if
(
data
==
null
)
{
withContext
(
Dispatchers
.
Main
)
{
callback
()
callback
(
null
)
}
return
@launch
}
val
decryptedData
=
AESHelper
.
decrypt
(
data
)
parseConfigBean
(
decryptedData
)
withContext
(
Dispatchers
.
Main
)
{
callback
()
callback
(
decryptedData
)
}
}
}
...
...
@@ -93,20 +92,20 @@ object NewComUtils {
return
match
?.
groupValues
?.
get
(
1
)
}
private
fun
parseConfigBean
(
json
:
String
)
{
val
gson
=
Gson
()
val
type
=
object
:
TypeToken
<
Map
<
String
,
String
>>()
{}.
type
val
configMap
=
gson
.
fromJson
<
Map
<
String
,
String
>>(
json
,
type
)
configMap
.
forEach
{
t
,
u
->
// 对于整型值使用parseInt, 长整型使用parseLong
AppPreferences
.
getInstance
().
put
(
t
,
u
)
LogEx
.
logDebug
(
TAG
,
"t=$t u=$u"
)
}
val
jsonObject
=
JSONObject
()
jsonObject
.
put
(
"ut"
,
AppPreferences
.
getInstance
().
getString
(
"ut"
,
""
))
EventUtils
.
event
(
"user_type"
,
ext
=
jsonObject
)
}
//
private fun parseConfigBean(json: String) {
//
val gson = Gson()
//
val type = object : TypeToken<Map<String, String>>() {}.type
//
val configMap = gson.fromJson<Map<String, String>>(json, type)
//
//
configMap.forEach { t, u ->
//
// 对于整型值使用parseInt, 长整型使用parseLong
//
AppPreferences.getInstance().put(t, u)
//
LogEx.logDebug(TAG, "t=$t u=$u")
//
}
//
//
val jsonObject = JSONObject()
//
jsonObject.put("ut", AppPreferences.getInstance().getString("ut", ""))
//
EventUtils.event("user_type", ext = jsonObject)
//
}
}
app/src/main/java/com/base/locationsharewhite/ui/main/MainActivity.kt
View file @
257ed5db
...
...
@@ -200,7 +200,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), OnMapReadyCallback {
}
private
fun
showAdJump
(
jumpAction
:
()
->
Unit
)
{
AdInsertMgr
().
show
(
this
,
object
:
AdsShowCallBack
()
{
AdInsertMgr
().
show
(
this
,
false
,
object
:
AdsShowCallBack
()
{
override
fun
close
()
{
jumpAction
.
invoke
()
}
...
...
app/src/main/java/com/base/locationsharewhite/ui/splash/SplashActivity.kt
View file @
257ed5db
...
...
@@ -63,7 +63,7 @@ class SplashActivity : BaseActivity<ActivitySplashBinding>(), SplashView {
}
override
fun
agreePrivacy
()
{
AdsMgr
.
showOpen
(
this
,
object
:
AdsShowCallBack
()
{
AdsMgr
.
showOpen
(
this
,
false
,
object
:
AdsShowCallBack
()
{
override
fun
show
()
{
LogEx
.
logDebug
(
TAG
,
"AdsShowCallBack show"
)
splashPresenter
.
cancelJumpJob
()
...
...
app/src/main/java/com/base/locationsharewhite/ui/views/DialogView.kt
View file @
257ed5db
...
...
@@ -12,7 +12,6 @@ import android.widget.LinearLayout
import
androidx.core.content.ContextCompat
import
com.base.locationsharewhite.R
import
com.base.locationsharewhite.ads.AdsMgr
import
com.base.locationsharewhite.ads.admob.AdNativeMgr
import
com.base.locationsharewhite.databinding.DialogAppExitBinding
import
com.base.locationsharewhite.databinding.DialogMapTypeBinding
import
com.base.locationsharewhite.databinding.DialogViewerMoreBinding
...
...
app/src/main/res/layout/dialog_app_exit.xml
View file @
257ed5db
...
...
@@ -65,11 +65,11 @@
</LinearLayout>
<FrameLayout
android:layout_marginTop=
"16dp"
<com.base.locationsharewhite.ads.NativeParentView
android:id=
"@+id/fl_ad"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"16dp"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@id/ll"
>
...
...
@@ -77,7 +77,7 @@
layout=
"@layout/layout_admob_app_exit"
android:layout_width=
"match_parent"
android:layout_height=
"250dp"
/>
</
FrameLayout
>
</
com.base.locationsharewhite.ads.NativeParentView
>
</androidx.constraintlayout.widget.ConstraintLayout>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment