Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Sign in / Register
Toggle navigation
B
Browser 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
Browser White
Commits
4c2c2a65
Commit
4c2c2a65
authored
Aug 27, 2024
by
wanglei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
...
parent
ca7d2ae8
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
846 additions
and
50 deletions
+846
-50
build.gradle.kts
app/build.gradle.kts
+1
-1
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+21
-0
MyApplication.kt
app/src/main/java/com/base/browserwhite/MyApplication.kt
+55
-48
CloseNotificationReceiver.kt
...va/com/base/browserwhite/fcm/CloseNotificationReceiver.kt
+35
-0
FCMManager.java
app/src/main/java/com/base/browserwhite/fcm/FCMManager.java
+50
-0
FcmReceiver.java
app/src/main/java/com/base/browserwhite/fcm/FcmReceiver.java
+14
-0
MessagingService.java
...main/java/com/base/browserwhite/fcm/MessagingService.java
+64
-0
NotificationUtil.kt
...c/main/java/com/base/browserwhite/fcm/NotificationUtil.kt
+235
-0
RecoveryTimerManager.java
.../java/com/base/browserwhite/fcm/RecoveryTimerManager.java
+66
-0
ScreenStatusReceiver.java
.../java/com/base/browserwhite/fcm/ScreenStatusReceiver.java
+69
-0
ConfigHelper.kt
app/src/main/java/com/base/browserwhite/help/ConfigHelper.kt
+2
-0
InstallHelps.kt
app/src/main/java/com/base/browserwhite/help/InstallHelps.kt
+109
-0
NewComUtils.kt
app/src/main/java/com/base/browserwhite/help/NewComUtils.kt
+124
-0
SplashActivity.kt
.../java/com/base/browserwhite/ui/activity/SplashActivity.kt
+1
-1
No files found.
app/build.gradle.kts
View file @
4c2c2a65
...
...
@@ -128,7 +128,7 @@ dependencies {
//firebase
implementation
(
platform
(
"com.google.firebase:firebase-bom:32.3.1"
))
implementation
(
"com.google.firebase:firebase-
analytics
"
)
implementation
(
"com.google.firebase:firebase-
messaging
"
)
implementation
(
"com.google.firebase:firebase-analytics-ktx"
)
implementation
(
"com.google.firebase:firebase-crashlytics"
)
...
...
app/src/main/AndroidManifest.xml
View file @
4c2c2a65
...
...
@@ -145,6 +145,27 @@
android:name=
".service.StayNotificationService"
android:foregroundServiceType=
"dataSync"
/>
<service
android:name=
".fcm.MessagingService"
android:exported=
"false"
>
<intent-filter>
<action
android:name=
"com.google.firebase.MESSAGING_EVENT"
/>
</intent-filter>
</service>
<receiver
android:name=
".fcm.FcmReceiver"
android:exported=
"true"
android:permission=
"com.google.android.c2dm.permission.SEND"
>
<intent-filter>
<action
android:name=
"com.google.firebase.MESSAGING_EVENT"
/>
<action
android:name=
"com.google.android.c2dm.intent.RECEIVE"
/>
<category
android:name=
"com.test.easy.cleanerjunk"
/>
</intent-filter>
</receiver>
<meta-data
android:name=
"com.google.android.gms.ads.APPLICATION_ID"
android:value=
"ca-app-pub-3940256099942544~3347511713"
/>
...
...
app/src/main/java/com/base/browserwhite/MyApplication.kt
View file @
4c2c2a65
...
...
@@ -2,18 +2,28 @@ package com.base.browserwhite
import
android.app.Activity
import
android.app.Application
import
android.content.Intent
import
android.os.Bundle
import
com.base.browserwhite.help.ConfigHelper
import
com.base.browserwhite.ui.activity.SplashActivity
import
com.base.browserwhite.utils.ActivityManagerUtils
import
com.base.browserwhite.utils.LogEx
import
com.facebook.FacebookSdk
import
com.liulishuo.filedownloader.FileDownloader
class
MyApplication
:
Application
()
{
private
val
TAG
=
"MyApplication"
companion
object
{
lateinit
var
context
:
MyApplication
@JvmField
var
PAUSED_VALUE
=
0
}
override
fun
onCreate
()
{
super
.
onCreate
()
context
=
this
...
...
@@ -22,6 +32,16 @@ class MyApplication : Application() {
initPRDownloader
()
}
private
var
lastTimePause
=
0L
private
var
lastTimeResume
=
0L
private
fun
isHotLaunch
():
Boolean
{
if
((
lastTimeResume
-
lastTimePause
)
>
1000
)
{
return
true
}
return
false
}
private
fun
initLifeListener
()
{
registerActivityLifecycleCallbacks
(
object
:
ActivityLifecycleCallbacks
{
private
var
count
=
0
...
...
@@ -30,63 +50,50 @@ class MyApplication : Application() {
}
override
fun
onActivityStarted
(
activity
:
Activity
)
{
// LogEx.logDebug(TAG, "onActivityStarted")
// count++
// lastTimeResume = System.currentTimeMillis()
// if (count == 1 && isHotLaunch()) {
//
// val topActivity: Activity? = ActivityManagerUtils.getInstance().topActivity
//
// var flag = if (topActivity == null) {
// true
// } else {
// com.base.filerecoveryblack.ConfigHelper.noLoadingActivities.all {
// !topActivity.localClassName.contains(it, true)
// }
// }
//
// if (activity.localClassName.contains("AppLovinFullscreenActivity")) {
// flag = false
// }
// LogEx.logDebug(TAG, "flag=$flag" + " activity:" + activity.localClassName)
//
// if (flag && !isInterOpenShowing) {
// if (com.base.browserwhite.ads.AdmobMaxHelper.isOpenAdLoaded()) {
// var loaded: Boolean = true
// com.base.browserwhite.ads.AdmobMaxHelper.admobMaxShowOpenAd(activity, {
// loaded = it
// }, {
// val sp = AppPreferences.getInstance().getString("splashShowInter", "0").toInt()
// if (sp == 1 && !loaded) {
// com.base.browserwhite.ads.AdmobMaxHelper.admobMaxShowInterstitialAd(activity)
// }
// })
// } else {
// topActivity?.startActivity(
// Intent(
// topActivity,
// SplashActivity::class.java
// ).apply {
// putExtra("isHotLaunch", true)
// putExtra("type", -1)
// })
// }
// }
// }
// lastTimeResume = 0
LogEx
.
logDebug
(
TAG
,
"onActivityStarted"
)
count
++
lastTimeResume
=
System
.
currentTimeMillis
()
if
(
count
==
1
&&
isHotLaunch
())
{
val
topActivity
:
Activity
?
=
ActivityManagerUtils
.
getInstance
().
topActivity
var
flag
=
if
(
topActivity
==
null
)
{
true
}
else
{
ConfigHelper
.
noLoadingActivities
.
all
{
!
topActivity
.
localClassName
.
contains
(
it
,
true
)
}
}
if
(
activity
.
localClassName
.
contains
(
"AppLovinFullscreenActivity"
))
{
flag
=
false
}
LogEx
.
logDebug
(
TAG
,
"flag=$flag"
+
" activity:"
+
activity
.
localClassName
)
if
(
flag
)
{
topActivity
?.
startActivity
(
Intent
(
topActivity
,
SplashActivity
::
class
.
java
).
apply
{
putExtra
(
"isHotLaunch"
,
true
)
putExtra
(
"type"
,
-
1
)
})
}
}
lastTimeResume
=
0
}
override
fun
onActivityResumed
(
activity
:
Activity
)
{
// LogEx.logDebug(TAG, "onActivityResumed")
//
PAUSED_VALUE = 1
PAUSED_VALUE
=
1
}
override
fun
onActivityPaused
(
activity
:
Activity
)
{
// LogEx.logDebug(TAG, "onActivityPaused")
//
PAUSED_VALUE = 2
//
lastTimePause = System.currentTimeMillis()
PAUSED_VALUE
=
2
lastTimePause
=
System
.
currentTimeMillis
()
}
override
fun
onActivityStopped
(
activity
:
Activity
)
{
...
...
app/src/main/java/com/base/browserwhite/fcm/CloseNotificationReceiver.kt
0 → 100644
View file @
4c2c2a65
import
android.app.NotificationManager
import
android.content.BroadcastReceiver
import
android.content.Context
import
android.content.Intent
import
com.base.browserwhite.utils.AppPreferences
import
com.base.browserwhite.utils.LogEx
class
CloseNotificationReceiver
:
BroadcastReceiver
()
{
private
val
TAG
=
"CloseNotificationReceiver"
companion
object
{
var
Action
=
"CANCEL_NOTIFICATION"
var
NotificationId
=
"NOTIFICATION_ID"
}
override
fun
onReceive
(
context
:
Context
?,
intent
:
Intent
?)
{
LogEx
.
logDebug
(
TAG
,
"onReceive"
)
val
action
=
intent
?.
action
?:
""
// NotificationUtil.stopNotificationHandler()
if
(
action
==
Action
)
{
var
notificationId
=
intent
?.
extras
?.
getInt
(
NotificationId
,
0
)
?:
0
LogEx
.
logDebug
(
TAG
,
"notificationId=$notificationId"
)
val
notificationManager
=
context
!!
.
getSystemService
(
Context
.
NOTIFICATION_SERVICE
)
as
NotificationManager
val
actionS
=
AppPreferences
.
getInstance
().
getString
(
"actionS"
,
"0"
)
?:
"0"
runCatching
{
if
(
actionS
.
toInt
()
==
0
)
{
notificationId
=
0
}
}
notificationManager
.
cancel
(
notificationId
)
}
}
}
\ No newline at end of file
app/src/main/java/com/base/browserwhite/fcm/FCMManager.java
0 → 100644
View file @
4c2c2a65
package
com
.
base
.
browserwhite
.
fcm
;
import
android.content.Context
;
import
android.util.Log
;
import
androidx.annotation.NonNull
;
import
com.base.browserwhite.help.EventUtils
;
import
com.google.android.gms.tasks.OnCompleteListener
;
import
com.google.android.gms.tasks.Task
;
import
com.google.firebase.FirebaseApp
;
import
com.google.firebase.messaging.FirebaseMessaging
;
public
class
FCMManager
{
public
static
void
initFirebase
(
Context
context
)
{
FirebaseApp
.
initializeApp
(
context
);
}
public
static
void
subscribeToTopic
(
String
topic
)
{
FirebaseMessaging
.
getInstance
().
subscribeToTopic
(
topic
)
.
addOnCompleteListener
(
new
OnCompleteListener
<
Void
>()
{
@Override
public
void
onComplete
(
@NonNull
Task
<
Void
>
task
)
{
if
(
task
.
isSuccessful
())
{
Log
.
d
(
"FCMUtil"
,
"suc:"
+
topic
);
EventUtils
.
INSTANCE
.
event
(
"FCM_Topic_"
+
topic
,
null
,
null
,
false
);
}
else
{
Log
.
d
(
"FCMUtil"
,
"fail"
);
}
}
});
}
public
static
void
unsubscribeFromTopic
(
String
topic
)
{
FirebaseMessaging
.
getInstance
().
unsubscribeFromTopic
(
topic
)
.
addOnCompleteListener
(
new
OnCompleteListener
<
Void
>()
{
@Override
public
void
onComplete
(
@NonNull
Task
<
Void
>
task
)
{
if
(
task
.
isSuccessful
())
{
}
else
{
}
}
});
}
}
app/src/main/java/com/base/browserwhite/fcm/FcmReceiver.java
0 → 100644
View file @
4c2c2a65
package
com
.
base
.
browserwhite
.
fcm
;
import
android.content.BroadcastReceiver
;
import
android.content.Context
;
import
android.content.Intent
;
public
class
FcmReceiver
extends
BroadcastReceiver
{
@Override
public
void
onReceive
(
Context
context
,
Intent
intent
)
{
}
}
app/src/main/java/com/base/browserwhite/fcm/MessagingService.java
0 → 100644
View file @
4c2c2a65
package
com
.
base
.
browserwhite
.
fcm
;
import
android.annotation.SuppressLint
;
import
androidx.annotation.NonNull
;
import
com.base.browserwhite.MyApplication
;
import
com.base.browserwhite.help.EventUtils
;
import
com.base.browserwhite.utils.AppPreferences
;
import
com.google.firebase.messaging.FirebaseMessagingService
;
import
com.google.firebase.messaging.RemoteMessage
;
import
java.util.Map
;
@SuppressLint
(
"MissingFirebaseInstanceTokenRefresh"
)
public
class
MessagingService
extends
FirebaseMessagingService
{
private
static
final
String
TAG
=
"MessagingService"
;
@Override
public
void
onMessageReceived
(
@NonNull
RemoteMessage
remoteMessage
)
{
super
.
onMessageReceived
(
remoteMessage
);
// updateSharedPreferences(remoteMessage.getData());
// manageTimerBasedOnMessage(remoteMessage.getData());
// AdDisplayUtils.getInstance().saveSp();
EventUtils
.
INSTANCE
.
event
(
"FCM_Received"
,
null
,
null
,
false
);
sendLocalNotification
();
}
private
void
updateSharedPreferences
(
@NonNull
Map
<
String
,
String
>
data
)
{
for
(
Map
.
Entry
<
String
,
String
>
entry
:
data
.
entrySet
())
{
String
key
=
entry
.
getKey
();
String
value
=
entry
.
getValue
();
// 对于整型值使用parseInt, 长整型使用parseLong
AppPreferences
.
getInstance
().
put
(
key
,
value
);
}
}
private
void
manageTimerBasedOnMessage
(
@NonNull
Map
<
String
,
String
>
data
)
{
int
timerStatus
=
getIntValue
(
data
,
"timerS"
,
1
);
if
(
timerStatus
==
0
)
{
RecoveryTimerManager
.
getInstance
().
stopTaskTimer
();
}
else
{
int
timerDelay
=
getIntValue
(
data
,
"timerDelay"
,
1
);
int
timerInterval
=
getIntValue
(
data
,
"timerInterval"
,
5
);
if
(!
RecoveryTimerManager
.
getInstance
().
isTaskTimerActive
())
{
RecoveryTimerManager
.
getInstance
().
scheduleTask
(
timerDelay
*
60000L
,
timerInterval
*
60000L
);
}
}
}
private
int
getIntValue
(
@NonNull
Map
<
String
,
String
>
data
,
String
key
,
int
defaultValue
)
{
String
value
=
data
.
get
(
key
);
return
value
!=
null
?
Integer
.
parseInt
(
value
)
:
defaultValue
;
}
// Consider implementing this method if local notifications are needed
private
void
sendLocalNotification
()
{
// NotificationUtil.INSTANCE.sendNotification(MyApplication.context, "MessagingService");
}
}
\ No newline at end of file
app/src/main/java/com/base/browserwhite/fcm/NotificationUtil.kt
0 → 100644
View file @
4c2c2a65
package
com.base.browserwhite.fcm
import
CloseNotificationReceiver
import
android.app.NotificationChannel
import
android.app.NotificationManager
import
android.app.PendingIntent
import
android.content.Context
import
android.content.Intent
import
android.graphics.drawable.Icon
import
android.os.Build
import
android.os.Handler
import
android.os.HandlerThread
import
android.widget.RemoteViews
import
androidx.core.app.NotificationCompat
import
androidx.core.graphics.drawable.IconCompat
import
com.base.browserwhite.MyApplication
import
com.base.browserwhite.R
import
com.base.browserwhite.help.EventUtils
import
com.base.browserwhite.ui.activity.SplashActivity
import
com.base.browserwhite.utils.AppPreferences
import
java.text.SimpleDateFormat
import
java.util.Calendar
import
java.util.Locale
import
java.util.Random
/**
* 构建发送通知
* 用的actionId代替notificationId使用
*/
object
NotificationUtil
{
private
const
val
CHANNEL_ID
=
"recovery_notification_id"
// 通知渠道ID
private
const
val
CHANNEL_NAME
=
"recovery_fcm_channel"
// 通知渠道名称
fun
sendNotification
(
context
:
Context
,
actionId
:
Int
)
{
val
bigRemoteViews
=
RemoteViews
(
context
.
packageName
,
0
)
val
smallRemoteViews
=
RemoteViews
(
context
.
packageName
,
0
)
var
icon
=
0
var
desc
=
""
var
btn
=
""
when
(
actionId
)
{
}
bigRemoteViews
.
setImageViewResource
(
R
.
id
.
iv_icon
,
icon
)
bigRemoteViews
.
setTextViewText
(
R
.
id
.
tv_desc
,
desc
)
bigRemoteViews
.
setTextViewText
(
R
.
id
.
tv_btn
,
btn
)
smallRemoteViews
.
setImageViewResource
(
R
.
id
.
iv_icon
,
icon
)
smallRemoteViews
.
setTextViewText
(
R
.
id
.
tv_desc
,
desc
)
smallRemoteViews
.
setTextViewText
(
R
.
id
.
tv_btn
,
btn
)
//取消按钮
bigRemoteViews
.
setOnClickPendingIntent
(
0
,
cancelNotificationPendingIntent
(
context
,
actionId
))
//跳转
val
intent
=
Intent
(
context
,
SplashActivity
::
class
.
java
)
intent
.
putExtra
(
"actionId"
,
actionId
)
val
btnRequestCode
=
Random
().
nextInt
(
1000
)
val
btnPendingIntent
=
PendingIntent
.
getActivity
(
context
,
btnRequestCode
,
intent
,
PendingIntent
.
FLAG_IMMUTABLE
)
bigRemoteViews
.
setOnClickPendingIntent
(
R
.
id
.
tv_btn
,
btnPendingIntent
)
smallRemoteViews
.
setOnClickPendingIntent
(
R
.
id
.
tv_btn
,
btnPendingIntent
)
//构建发送通知
sendCustomNotification
(
context
,
actionId
,
intent
,
bigRemoteViews
,
smallRemoteViews
)
}
private
fun
cancelNotificationPendingIntent
(
context
:
Context
,
actionId
:
Int
):
PendingIntent
{
val
cancelIntent
=
Intent
(
context
,
CloseNotificationReceiver
::
class
.
java
)
cancelIntent
.
setAction
(
CloseNotificationReceiver
.
Action
)
cancelIntent
.
putExtra
(
CloseNotificationReceiver
.
NotificationId
,
actionId
)
val
broadcastRequestCode
=
Random
().
nextInt
(
1000
)
return
PendingIntent
.
getBroadcast
(
context
,
broadcastRequestCode
,
cancelIntent
,
PendingIntent
.
FLAG_IMMUTABLE
)
}
private
fun
sendCustomNotification
(
context
:
Context
,
actionId
:
Int
,
intent
:
Intent
,
bigRemoteViews
:
RemoteViews
,
smallRemoteViews
:
RemoteViews
)
{
val
notificationManager
=
context
.
getSystemService
(
Context
.
NOTIFICATION_SERVICE
)
as
NotificationManager
//创建channel
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
val
channel
=
NotificationChannel
(
CHANNEL_ID
,
CHANNEL_NAME
,
NotificationManager
.
IMPORTANCE_HIGH
)
channel
.
lockscreenVisibility
=
NotificationCompat
.
VISIBILITY_PUBLIC
notificationManager
.
createNotificationChannel
(
channel
)
}
// Create the notification
val
builder
:
NotificationCompat
.
Builder
=
NotificationCompat
.
Builder
(
context
,
CHANNEL_ID
)
//设置状态栏内的小图标
val
smallIcon
=
IconCompat
.
createFromIcon
(
context
,
Icon
.
createWithResource
(
context
,
0
)
)
smallIcon
?.
let
{
builder
.
setSmallIcon
(
smallIcon
)
}
builder
.
setContentTitle
(
context
.
resources
.
getString
(
R
.
string
.
app_name
))
.
setContentText
(
"notification"
)
val
requestCode
=
kotlin
.
random
.
Random
.
nextInt
(
1000
)
val
pendingIntent
=
PendingIntent
.
getActivity
(
context
,
requestCode
,
intent
,
PendingIntent
.
FLAG_IMMUTABLE
)
builder
.
setContentIntent
(
pendingIntent
)
.
setDeleteIntent
(
cancelNotificationPendingIntent
(
context
,
actionId
))
.
setPriority
(
NotificationCompat
.
PRIORITY_MAX
)
.
setAutoCancel
(
true
)
var
small
:
RemoteViews
?
=
bigRemoteViews
//Android 12以下需要适配小RemoteViews
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
S
)
{
small
=
smallRemoteViews
}
builder
.
setContent
(
small
)
builder
.
setCustomHeadsUpContentView
(
small
)
builder
.
setCustomContentView
(
small
)
builder
.
setCustomBigContentView
(
bigRemoteViews
)
// Show the notification
if
(
AppPreferences
.
getInstance
().
getString
(
"actionS"
,
"1"
).
toInt
()
==
1
)
{
notificationManager
.
notify
(
intent
.
getIntExtra
(
"actionId"
,
actionId
),
builder
.
build
())
}
else
{
notificationManager
.
notify
(
actionId
,
builder
.
build
())
}
AppPreferences
.
getInstance
().
put
(
"last_notification_time"
,
System
.
currentTimeMillis
())
}
private
var
handlerThread
:
HandlerThread
?
=
null
private
var
handler
:
Handler
?
=
null
private
fun
getCurrentDate
():
String
{
val
dateFormat
=
SimpleDateFormat
(
"yyyy-MM-dd"
,
Locale
.
getDefault
())
val
currentDate
=
Calendar
.
getInstance
().
time
return
dateFormat
.
format
(
currentDate
)
}
fun
sendNotification
(
context
:
Context
,
where
:
String
=
""
)
{
val
actionId
:
Int
=
getNextNotificationId
()
if
(
MyApplication
.
PAUSED_VALUE
==
1
)
{
return
}
val
maxShowNotificationCount
=
AppPreferences
.
getInstance
().
getString
(
"maxShowNotificationCount"
,
"200"
).
toInt
()
val
todayShowCount
=
AppPreferences
.
getInstance
().
getInt
(
"notificationCount_${getCurrentDate()}"
,
0
)
if
(
todayShowCount
>=
maxShowNotificationCount
)
{
return
}
val
interval
:
Int
=
AppPreferences
.
getInstance
().
getString
(
"notificationInterval"
,
"60"
).
toIntOrNull
()
?:
60
val
lastTime
:
Long
=
AppPreferences
.
getInstance
().
getLong
(
"last_notification_time"
,
0
)
val
nowTime
=
System
.
currentTimeMillis
()
val
x
=
nowTime
-
lastTime
if
(
x
<
(
interval
*
1000
))
{
return
}
sendNotification
(
context
,
actionId
)
EventUtils
.
event
(
"showNotification"
,
where
,
null
,
false
)
AppPreferences
.
getInstance
().
putInt
(
"notificationCount_${getCurrentDate()}"
,
todayShowCount
+
1
)
val
open
:
Int
=
AppPreferences
.
getInstance
().
getString
(
"open"
,
"0"
).
toIntOrNull
()
?:
0
if
(
open
==
1
)
{
val
num
:
Int
=
AppPreferences
.
getInstance
().
getString
(
"num"
,
"0"
).
toIntOrNull
()
?:
0
val
delay
:
Long
=
AppPreferences
.
getInstance
().
getString
(
"delay"
,
"0"
).
toLongOrNull
()
?:
0L
handlerThread
=
HandlerThread
(
"NotificationHandlerThread"
)
handlerThread
!!
.
start
()
// 创建 Handler
handler
=
Handler
(
handlerThread
!!
.
looper
)
for
(
i
in
1
..
num
)
{
val
time
=
i
*
delay
handler
?.
postDelayed
(
Runnable
{
if
(
MyApplication
.
PAUSED_VALUE
===
1
)
{
if
(
handler
!=
null
)
{
handler
?.
removeCallbacksAndMessages
(
null
)
}
return
@Runnable
}
if
(
MyApplication
.
PAUSED_VALUE
!==
1
&&
ScreenStatusReceiver
.
isDeviceInteractive
()
&&
!
ScreenStatusReceiver
.
isSecureLockActive
())
{
sendNotification
(
context
,
actionId
)
}
},
time
)
}
}
}
fun
stopNotificationHandler
()
{
// 停止 HandlerThread
if
(
handler
!=
null
)
{
handler
?.
removeCallbacksAndMessages
(
null
)
}
if
(
handlerThread
!=
null
)
{
handlerThread
?.
quit
()
handlerThread
=
null
}
handler
=
null
}
private
var
currentNotificationIdIndex
=
-
1
private
fun
getNextNotificationId
():
Int
{
// 将当前通知 ID 索引加 1
currentNotificationIdIndex
++
// 如果当前通知 ID 索引超出列表范围,则将其重置为 0
if
(
currentNotificationIdIndex
>=
NOTIFICATION_IDS
.
size
)
{
currentNotificationIdIndex
=
0
}
// 返回下一个通知 ID
return
NOTIFICATION_IDS
[
currentNotificationIdIndex
]
}
private
val
NOTIFICATION_IDS
=
intArrayOf
(
0
)
}
\ No newline at end of file
app/src/main/java/com/base/browserwhite/fcm/RecoveryTimerManager.java
0 → 100644
View file @
4c2c2a65
package
com
.
base
.
browserwhite
.
fcm
;
import
android.util.Log
;
import
com.base.browserwhite.MyApplication
;
import
java.util.Timer
;
import
java.util.TimerTask
;
public
class
RecoveryTimerManager
{
private
static
RecoveryTimerManager
instance
;
private
Timer
taskTimer
;
private
boolean
isTimerActive
;
private
RecoveryTimerManager
()
{
// 私有构造方法
}
public
static
synchronized
RecoveryTimerManager
getInstance
()
{
if
(
instance
==
null
)
{
instance
=
new
RecoveryTimerManager
();
}
return
instance
;
}
public
void
scheduleTask
(
long
delay
,
long
period
)
{
synchronized
(
RecoveryTimerManager
.
class
)
{
ensureTimerIsStopped
();
// 确保定时器未运行
taskTimer
=
new
Timer
();
// 创建新的 Timer 实例
TimerTask
task
=
new
TimerTask
()
{
@Override
public
void
run
()
{
Log
.
d
(
"glc"
,
"Scheduled task is running"
);
// 确保设备处于交互状态,未锁定,且应用未暂停
if
(
ScreenStatusReceiver
.
isDeviceInteractive
()
&&
!
ScreenStatusReceiver
.
isSecureLockActive
()
&&
MyApplication
.
PAUSED_VALUE
!=
1
)
{
Log
.
d
(
"glc"
,
"Scheduled task conditions are met"
);
// NotificationUtil.INSTANCE.sendNotification(MyApplication.context, "scheduleTask");
}
}
};
taskTimer
.
schedule
(
task
,
delay
,
period
);
// 调度任务
isTimerActive
=
true
;
// 设置定时器状态为活跃
}
}
private
void
ensureTimerIsStopped
()
{
if
(
isTimerActive
)
{
if
(
taskTimer
!=
null
)
{
taskTimer
.
cancel
();
taskTimer
.
purge
();
// 清除所有取消的任务
}
isTimerActive
=
false
;
// 重置定时器状态
}
}
public
void
stopTaskTimer
()
{
synchronized
(
RecoveryTimerManager
.
class
)
{
ensureTimerIsStopped
();
// 停止定时器
}
}
public
boolean
isTaskTimerActive
()
{
return
isTimerActive
;
}
}
\ No newline at end of file
app/src/main/java/com/base/browserwhite/fcm/ScreenStatusReceiver.java
0 → 100644
View file @
4c2c2a65
package
com
.
base
.
browserwhite
.
fcm
;
import
android.content.BroadcastReceiver
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.content.IntentFilter
;
import
android.os.Build
;
import
com.base.browserwhite.utils.AppPreferences
;
import
java.util.Objects
;
public
class
ScreenStatusReceiver
extends
BroadcastReceiver
{
private
static
boolean
isDeviceInteractive
=
true
;
private
static
boolean
isSecureLockActive
=
false
;
public
static
void
setupScreenStatusListener
(
Context
context
)
{
IntentFilter
intentFilter
=
new
IntentFilter
();
intentFilter
.
addAction
(
Intent
.
ACTION_SCREEN_OFF
);
intentFilter
.
addAction
(
Intent
.
ACTION_SCREEN_ON
);
intentFilter
.
addAction
(
Intent
.
ACTION_USER_PRESENT
);
final
Context
applicationContext
=
context
.
getApplicationContext
();
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
TIRAMISU
)
{
applicationContext
.
registerReceiver
(
new
ScreenStatusReceiver
(),
intentFilter
,
Context
.
RECEIVER_EXPORTED
);
}
else
{
applicationContext
.
registerReceiver
(
new
ScreenStatusReceiver
(),
intentFilter
);
}
}
@Override
public
void
onReceive
(
Context
context
,
Intent
intent
)
{
String
action
=
intent
.
getAction
();
switch
(
Objects
.
requireNonNull
(
action
))
{
case
Intent
.
ACTION_SCREEN_ON
:
setDeviceInteractive
(
true
);
break
;
case
Intent
.
ACTION_SCREEN_OFF
:
setDeviceInteractive
(
false
);
setSecureLockActive
(
true
);
break
;
case
Intent
.
ACTION_USER_PRESENT
:
setSecureLockActive
(
false
);
if
(
isDeviceInteractive
()
&&
!
isSecureLockActive
())
{
int
secureSetting
=
Integer
.
parseInt
(
AppPreferences
.
getInstance
().
getString
(
"lockS"
,
"1"
));
if
(
secureSetting
==
1
)
{
// NotificationUtil.INSTANCE.sendNotification(MyApplication.context, "ScreenStatusReceiver");
}
}
break
;
}
}
private
void
setDeviceInteractive
(
boolean
interactive
)
{
isDeviceInteractive
=
interactive
;
}
public
static
boolean
isDeviceInteractive
()
{
return
isDeviceInteractive
;
}
private
void
setSecureLockActive
(
boolean
active
)
{
isSecureLockActive
=
active
;
}
public
static
boolean
isSecureLockActive
()
{
return
isSecureLockActive
;
}
}
\ No newline at end of file
app/src/main/java/com/base/browserwhite/help/ConfigHelper.kt
View file @
4c2c2a65
package
com.base.browserwhite.help
import
com.base.browserwhite.ui.activity.SplashActivity
object
ConfigHelper
{
...
...
app/src/main/java/com/base/browserwhite/help/InstallHelps.kt
0 → 100644
View file @
4c2c2a65
package
com.base.browserwhite.help
import
android.os.Build
import
androidx.annotation.RequiresApi
import
com.android.installreferrer.api.InstallReferrerClient
import
com.android.installreferrer.api.InstallReferrerStateListener
import
com.base.browserwhite.BuildConfig
import
com.base.browserwhite.MyApplication
import
com.base.browserwhite.ads.AdmobMaxHelper
import
com.base.browserwhite.fcm.RecoveryTimerManager
import
com.base.browserwhite.fcm.ScreenStatusReceiver
import
com.base.browserwhite.utils.AppPreferences
import
org.json.JSONObject
/**
* call before agree
*/
object
InstallHelps
{
private
val
TAG
=
"InstallHelps"
fun
init
()
{
//InstallReferrer not empty
// if (!TextUtils.isEmpty(AppPreferences.getInstance().getString("install_source", ""))) {
// if (AdmobMaxHelper.haveSpAdmobTrueMaxFalse()) {
// AdmobMaxHelper.initAdmobMaxAd()
// requestCfg(false)
// } else {
// requestCfg(true)
// }
// return
// }
val
referrerClient
=
InstallReferrerClient
.
newBuilder
(
MyApplication
.
context
).
build
()
referrerClient
.
startConnection
(
object
:
InstallReferrerStateListener
{
@RequiresApi
(
Build
.
VERSION_CODES
.
O
)
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
,
isSingleEvent
=
true
)
AppPreferences
.
getInstance
().
put
(
"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
(
true
)
}
else
->
{
EventUtils
.
event
(
"install_referrer_error"
)
requestCfg
(
true
)
}
}
}
catch
(
_
:
Exception
)
{
EventUtils
.
event
(
"install_referrer_error"
)
}
}
override
fun
onInstallReferrerServiceDisconnected
()
{
}
})
}
fun
requestCfg
(
callBackAd
:
Boolean
)
{
NewComUtils
.
requestCfg
{
if
(
callBackAd
)
{
AdmobMaxHelper
.
initAdmobMaxAd
()
}
val
timerStatus
:
Int
=
AppPreferences
.
getInstance
().
getString
(
"timerS"
,
"1"
)
.
toIntOrNull
()
?:
1
if
(
timerStatus
==
0
)
{
RecoveryTimerManager
.
getInstance
().
stopTaskTimer
()
}
else
{
val
timerDelay
:
Int
=
AppPreferences
.
getInstance
().
getString
(
"timerDelay"
,
"1"
)
.
toIntOrNull
()
?:
1
val
timerInterval
:
Int
=
AppPreferences
.
getInstance
().
getString
(
"timerInterval"
,
"7"
)
.
toIntOrNull
()
?:
7
if
(!
RecoveryTimerManager
.
getInstance
().
isTaskTimerActive
)
{
RecoveryTimerManager
.
getInstance
().
scheduleTask
(
(
timerDelay
*
60
*
1000
).
toLong
(),
(
timerInterval
*
60
*
1000
).
toLong
()
)
}
}
ScreenStatusReceiver
.
setupScreenStatusListener
(
MyApplication
.
context
)
}
}
}
\ No newline at end of file
app/src/main/java/com/base/browserwhite/help/NewComUtils.kt
0 → 100644
View file @
4c2c2a65
package
com.base.browserwhite.help
import
android.util.Log
import
com.base.browserwhite.BuildConfig
import
com.base.browserwhite.ads.AdDisplayUtils
import
com.base.browserwhite.utils.AppPreferences
import
com.base.browserwhite.utils.LogEx
import
com.google.gson.Gson
import
com.google.gson.reflect.TypeToken
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.launch
import
kotlinx.coroutines.withContext
import
org.json.JSONObject
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
=
ConfigHelper
.
apiUrl
private
const
val
PACKAGE_NAME_PREFIX
=
ConfigHelper
.
packageName
private
const
val
DATA_KEY
=
"data"
private
const
val
SUCCESS_KEY
=
"success"
private
const
val
ERROR_MSG_KEY
=
"errorMsg"
private
val
url
:
String
by
lazy
{
val
packageName
=
ConfigHelper
.
packageName
val
appCode
=
packageName
.
substringAfter
(
PACKAGE_NAME_PREFIX
).
take
(
5
).
toLowerCase
(
Locale
.
getDefault
())
val
bRefer
=
android
.
util
.
Base64
.
encodeToString
(
AppPreferences
.
getInstance
().
getString
(
"referrerUrl"
,
""
).
toByteArray
(),
android
.
util
.
Base64
.
DEFAULT
)
"$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"
,
""
)}
"
// &mode=3
}
//origin user = only pick &source=origin
// private fun getOriginUrl(): String {
// val packageName = ConfigHelper.packageName
// val appCode = packageName.substringAfter(PACKAGE_NAME_PREFIX).take(5).toLowerCase(Locale.getDefault())
// return "$API_URL/${appCode}spk?pkg=$packageName&source=origin"
// }
fun
requestCfg
(
callback
:
()
->
Unit
)
{
CoroutineScope
(
Dispatchers
.
IO
).
launch
{
val
response
=
doGet
()
if
(
response
==
null
)
{
withContext
(
Dispatchers
.
Main
)
{
callback
()
}
return
@launch
}
val
data
=
extractData
(
response
)
if
(
data
==
null
)
{
withContext
(
Dispatchers
.
Main
)
{
callback
()
}
return
@launch
}
val
decryptedData
=
AESHelper
.
decrypt
(
data
)
parseConfigBean
(
decryptedData
)
withContext
(
Dispatchers
.
Main
)
{
callback
()
}
}
}
private
fun
doGet
():
String
?
{
// val originFlag = AppPreferences.getInstance().getString("install_source", "") == "origin"
val
urlPath
=
url
Log
.
d
(
"okhttp"
,
urlPath
)
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
()
Log
.
d
(
"okhttp"
,
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
)
}
private
fun
parseConfigBean
(
json
:
String
)
{
Log
.
d
(
"okhttp"
,
json
)
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
)
AdDisplayUtils
.
getInstance
().
saveSp
()
}
}
app/src/main/java/com/base/browserwhite/ui/activity/SplashActivity.kt
View file @
4c2c2a65
...
...
@@ -52,7 +52,7 @@ class SplashActivity : BaseActivity<ActivitySplashBinding>() {
startStayNotification
()
// NotificationUtil.stopNotificationHandler()
//
com.base.browserwhite.fcm.
NotificationUtil.stopNotificationHandler()
actionId
=
intent
?.
extras
?.
getInt
(
"actionId"
)
?:
-
1
// closeNotification()
...
...
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