Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Sign in / Register
Toggle navigation
S
swiftcleanerphonehelper
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
swiftcleanerphonehelper
Commits
a8524ab6
Commit
a8524ab6
authored
Dec 20, 2024
by
wanglei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
...
parent
259dc618
Pipeline
#1365
canceled with stages
Changes
41
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
41 changed files
with
3363 additions
and
17 deletions
+3363
-17
README.md
README.md
+1
-0
build.gradle.kts
app/build.gradle.kts
+41
-4
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+23
-9
MainActivity.kt
app/src/main/java/com/zxdemo/MainActivity.kt
+151
-0
ZxApplication.kt
app/src/main/java/com/zxdemo/ZxApplication.kt
+147
-0
AdmobHelper.kt
app/src/main/java/com/zxdemo/admob/AdmobHelper.kt
+820
-0
ReportAdUtils.kt
app/src/main/java/com/zxdemo/admob/ReportAdUtils.kt
+274
-0
ZxHttp.kt
app/src/main/java/com/zxdemo/http/ZxHttp.kt
+165
-0
NotificationUtils.kt
app/src/main/java/com/zxdemo/notity/NotificationUtils.kt
+243
-0
AppInstallReceiver.kt
app/src/main/java/com/zxdemo/receiver/AppInstallReceiver.kt
+61
-0
BatteryStatusReceiver.kt
...rc/main/java/com/zxdemo/receiver/BatteryStatusReceiver.kt
+64
-0
FcmReceiver.kt
app/src/main/java/com/zxdemo/receiver/FcmReceiver.kt
+11
-0
UnlockReceiver.kt
app/src/main/java/com/zxdemo/receiver/UnlockReceiver.kt
+101
-0
FcmService.kt
app/src/main/java/com/zxdemo/service/FcmService.kt
+15
-0
PermanentNotifyService.kt
...rc/main/java/com/zxdemo/service/PermanentNotifyService.kt
+142
-0
AESUtils.kt
app/src/main/java/com/zxdemo/utils/AESUtils.kt
+61
-0
ActivityCollector.kt
app/src/main/java/com/zxdemo/utils/ActivityCollector.kt
+69
-0
DeviceUtils.kt
app/src/main/java/com/zxdemo/utils/DeviceUtils.kt
+97
-0
FcmUtils.kt
app/src/main/java/com/zxdemo/utils/FcmUtils.kt
+37
-0
GlobalTimer.kt
app/src/main/java/com/zxdemo/utils/GlobalTimer.kt
+67
-0
HttpUtils.kt
app/src/main/java/com/zxdemo/utils/HttpUtils.kt
+37
-0
InstallRefeerUtils.kt
app/src/main/java/com/zxdemo/utils/InstallRefeerUtils.kt
+138
-0
NativeView.kt
app/src/main/java/com/zxdemo/utils/NativeView.kt
+65
-0
SpUtils.kt
app/src/main/java/com/zxdemo/utils/SpUtils.kt
+171
-0
ad_native_background.xml
app/src/main/res/drawable/ad_native_background.xml
+5
-0
ad_native_button_background.xml
app/src/main/res/drawable/ad_native_button_background.xml
+5
-0
icon_apk.png
app/src/main/res/drawable/icon_apk.png
+0
-0
icon_empty.png
app/src/main/res/drawable/icon_empty.png
+0
-0
icon_logs.png
app/src/main/res/drawable/icon_logs.png
+0
-0
icon_temp.png
app/src/main/res/drawable/icon_temp.png
+0
-0
layout_ad_native.xml
app/src/main/res/layout/layout_ad_native.xml
+78
-0
native_custom_ad_view.xml
app/src/main/res/layout/native_custom_ad_view.xml
+113
-0
notice_expand.xml
app/src/main/res/layout/notice_expand.xml
+6
-0
notice_fold.xml
app/src/main/res/layout/notice_fold.xml
+6
-0
notice_process_expand.xml
app/src/main/res/layout/notice_process_expand.xml
+49
-0
notice_process_fold.xml
app/src/main/res/layout/notice_process_fold.xml
+35
-0
ad.png
app/src/main/res/mipmap-xxhdpi/ad.png
+0
-0
strings.xml
app/src/main/res/values/strings.xml
+3
-0
build.gradle.kts
build.gradle.kts
+3
-3
libs.versions.toml
gradle/libs.versions.toml
+58
-0
gradle-wrapper.properties
gradle/wrapper/gradle-wrapper.properties
+1
-1
No files found.
README.md
View file @
a8524ab6
# swiftcleanerphonehelper
# swiftcleanerphonehelper
## 1.FCM (firebase 推送服务)
app/build.gradle.kts
View file @
a8524ab6
plugins
{
plugins
{
id
(
"com.android.application"
)
id
(
"com.android.application"
)
id
(
"com.google.gms.google-services"
)
id
(
"com.google.gms.google-services"
)
alias
(
libs
.
plugins
.
kotlin
.
android
)
id
(
"com.google.firebase.crashlytics"
)
}
}
android
{
android
{
namespace
=
"com.swiftcleaner.chovey"
namespace
=
"com.swiftcleaner.chovey"
compileSdk
=
3
3
compileSdk
=
3
4
defaultConfig
{
defaultConfig
{
applicationId
=
"com.clean_swift"
applicationId
=
"com.clean_swift"
minSdk
=
28
minSdk
=
28
targetSdk
=
3
3
targetSdk
=
3
4
versionCode
=
1
versionCode
=
1
versionName
=
"1.0"
versionName
=
"1.0"
...
@@ -43,10 +44,14 @@ android {
...
@@ -43,10 +44,14 @@ android {
}
}
buildFeatures
{
buildFeatures
{
viewBinding
=
true
viewBinding
=
true
buildConfig
=
true
}
}
dependenciesInfo
{
dependenciesInfo
{
includeInApk
=
true
includeInApk
=
true
}
}
kotlinOptions
{
jvmTarget
=
"1.8"
}
}
}
...
@@ -55,6 +60,7 @@ dependencies {
...
@@ -55,6 +60,7 @@ dependencies {
implementation
(
"androidx.appcompat:appcompat:1.6.1"
)
implementation
(
"androidx.appcompat:appcompat:1.6.1"
)
implementation
(
"com.google.android.material:material:1.8.0"
)
implementation
(
"com.google.android.material:material:1.8.0"
)
implementation
(
"androidx.constraintlayout:constraintlayout:2.1.4"
)
implementation
(
"androidx.constraintlayout:constraintlayout:2.1.4"
)
implementation
(
libs
.
core
.
ktx
)
testImplementation
(
"junit:junit:4.13.2"
)
testImplementation
(
"junit:junit:4.13.2"
)
androidTestImplementation
(
"androidx.test.ext:junit:1.1.5"
)
androidTestImplementation
(
"androidx.test.ext:junit:1.1.5"
)
androidTestImplementation
(
"androidx.test.espresso:espresso-core:3.5.1"
)
androidTestImplementation
(
"androidx.test.espresso:espresso-core:3.5.1"
)
...
@@ -64,6 +70,37 @@ dependencies {
...
@@ -64,6 +70,37 @@ dependencies {
api
(
"com.geyifeng.immersionbar:immersionbar:3.2.2"
)
api
(
"com.geyifeng.immersionbar:immersionbar:3.2.2"
)
api
(
"com.airbnb.android:lottie:5.2.0"
)
api
(
"com.airbnb.android:lottie:5.2.0"
)
implementation
(
"com.google.firebase:firebase-messaging:23.2.1"
)
implementation
(
"com.google.firebase:firebase-messaging:23.2.1"
)
//solar 归因
implementation
(
"com.reyun.solar.engine.oversea:solar-engine-core:1.2.8.3"
)
implementation
(
"com.squareup.okhttp3:okhttp:4.12.0"
)
//admob渠道
implementation
(
libs
.
vungle
)
implementation
(
libs
.
facebook
)
implementation
(
libs
.
mintegral
)
implementation
(
libs
.
pangle
)
//applovin sdk
implementation
(
libs
.
applovin
)
//applovin渠道
implementation
(
libs
.
applovin
.
google
)
implementation
(
libs
.
applovin
.
admob
)
implementation
(
libs
.
applovin
.
facebook
)
//meta
implementation
(
libs
.
applovin
.
mintegral
)
//mintegral
implementation
(
libs
.
applovin
.
pangle
)
//pangle
implementation
(
libs
.
applovin
.
vungle
)
//vungle
//firebase
implementation
(
platform
(
"com.google.firebase:firebase-bom:32.3.1"
))
implementation
(
"com.google.firebase:firebase-messaging"
)
implementation
(
"com.google.firebase:firebase-analytics-ktx"
)
implementation
(
"com.google.firebase:firebase-crashlytics"
)
implementation
(
"com.google.firebase:firebase-config"
)
implementation
(
"com.google.firebase:firebase-messaging-directboot"
)
//facebook
implementation
(
"com.facebook.android:facebook-android-sdk:[8,9)"
)
}
}
\ No newline at end of file
app/src/main/AndroidManifest.xml
View file @
a8524ab6
...
@@ -9,6 +9,7 @@
...
@@ -9,6 +9,7 @@
<uses-permission
android:name=
"android.permission.MANAGE_EXTERNAL_STORAGE"
/>
<uses-permission
android:name=
"android.permission.MANAGE_EXTERNAL_STORAGE"
/>
<uses-permission
android:name=
"android.permission.REQUEST_DELETE_PACKAGES"
/>
<uses-permission
android:name=
"android.permission.REQUEST_DELETE_PACKAGES"
/>
<uses-permission
android:name=
"android.permission.READ_NOTIFICATIONS"
/>
<uses-permission
android:name=
"android.permission.READ_NOTIFICATIONS"
/>
<queries>
<queries>
<intent>
<intent>
<action
android:name=
"android.intent.action.MAIN"
/>
<action
android:name=
"android.intent.action.MAIN"
/>
...
@@ -19,6 +20,7 @@
...
@@ -19,6 +20,7 @@
</queries>
</queries>
<application
<application
android:name=
"com.tool.zxdemo.ZxApplication"
android:allowBackup=
"true"
android:allowBackup=
"true"
android:dataExtractionRules=
"@xml/data_extraction_rules"
android:dataExtractionRules=
"@xml/data_extraction_rules"
android:fullBackupContent=
"@xml/backup_rules"
android:fullBackupContent=
"@xml/backup_rules"
...
@@ -37,15 +39,15 @@
...
@@ -37,15 +39,15 @@
<action
android:name=
"com.google.firebase.MESSAGING_EVENT"
/>
<action
android:name=
"com.google.firebase.MESSAGING_EVENT"
/>
</intent-filter>
</intent-filter>
</service>
</service>
<!-- <receiver-->
<!-- <receiver-->
<!-- android:name="自定义 Receiver"-->
<!-- android:name="自定义 Receiver"-->
<!-- android:enabled="true"-->
<!-- android:enabled="true"-->
<!-- android:exported="false" >-->
<!-- android:exported="false" >-->
<!-- <intent-filter>-->
<!-- <intent-filter>-->
<!-- <action android:name="cn.jpush.android.intent.RECEIVER_MESSAGE" />-->
<!-- <action android:name="cn.jpush.android.intent.RECEIVER_MESSAGE" />-->
<!-- <category android:name="com.clean_swift" />-->
<!-- <category android:name="com.clean_swift" />-->
<!-- </intent-filter>-->
<!-- </intent-filter>-->
<!-- </receiver>-->
<!-- </receiver>-->
<activity
<activity
android:name=
".view.activity.SimilarPhotosActivity"
android:name=
".view.activity.SimilarPhotosActivity"
android:exported=
"false"
/>
android:exported=
"false"
/>
...
@@ -104,6 +106,18 @@
...
@@ -104,6 +106,18 @@
<meta-data
<meta-data
android:name=
"android.max_aspect"
android:name=
"android.max_aspect"
android:value=
"2.4"
/>
android:value=
"2.4"
/>
<!-- 广告的appId每次打包正式需要改 -->
<meta-data
android:name=
"com.google.android.gms.ads.APPLICATION_ID"
android:value=
"ca-app-pub-3940256099942544~3347511713"
/>
<meta-data
android:name=
"com.facebook.sdk.ApplicationId"
android:value=
"@string/facebook_app_id"
/>
</application>
</application>
</manifest>
</manifest>
\ No newline at end of file
app/src/main/java/com/zxdemo/MainActivity.kt
0 → 100644
View file @
a8524ab6
//package com.tool.zxdemo
//
//import android.Manifest
//import android.content.Intent
//import android.os.Build
//import android.os.Bundle
//import android.widget.Toast
//import androidx.activity.result.contract.ActivityResultContracts
//import androidx.appcompat.app.AppCompatActivity
//import androidx.core.view.isVisible
//import com.applovin.sdk.AppLovinSdk
//import com.reyun.solar.engine.SolarEngineConfig
//import com.reyun.solar.engine.SolarEngineManager
//import com.tool.zxdemo.admob.com.zxdemo.admob.AdmobHelper
//import com.tool.zxdemo.databinding.ActivityMainBinding
//import com.tool.zxdemo.http.com.zxdemo.http.ZxHttp
//import com.tool.zxdemo.service.PermanentNotifyService
//import com.tool.zxdemo.service.PermanentNotifyService.Companion.startOmgNotification
//import com.tool.zxdemo.utils.com.zxdemo.utils.GlobalTimer
//import com.tool.zxdemo.utils.com.zxdemo.utils.SpUtils
//import java.util.Random
//
//class MainActivity : AppCompatActivity() {
//
// private val binding by lazy {
// ActivityMainBinding.inflate(layoutInflater)
// }
//
// override fun onCreate(savedInstanceState: Bundle?) {
// super.onCreate(savedInstanceState)
// setContentView(binding.root)
// SolarEngineManager.getInstance().preInit(this, "f3ea1ff055365453")//(归因)同意隐私之前进行预加载
// var config = SolarEngineConfig.Builder().build()//同意之后再进行初始化
// SolarEngineManager.getInstance()
// .initialize(this, "APP_KEY", config)
// if (Build.VERSION.SDK_INT >= 33) {
// registerForActivityResult(ActivityResultContracts.RequestPermission()) {}.launch(
// Manifest.permission.POST_NOTIFICATIONS
// )
// }
// startOmgNotification()
//
// val random = Random()
// val randomNumber = random.nextInt(5)
// var sTimer = com.zxdemo.utils.SpUtils.getInstance().getBoolean("sTimer", false)
// binding.sTimer.isChecked = sTimer
//// if (sTimer) {
//// com.zxdemo.utils.GlobalTimer.getInstance()
//// .scheduleTask(3 * 1000L, 5 * 1000L)
//// }
//
// var sNotify = com.zxdemo.utils.SpUtils.getInstance().getBoolean("sNotify", false)
// binding.sNotify.isChecked = sNotify
// binding.sAd.isChecked = com.zxdemo.admob.AdmobHelper.useAdmob
// binding.sAd.setOnCheckedChangeListener { buttonView, isChecked ->
// com.zxdemo.admob.AdmobHelper.useAdmob = isChecked
// com.zxdemo.admob.AdmobHelper.init(this, {}, {})
// if (isChecked) {
// binding.buttonAppApplovin.isVisible = false
// } else {
// binding.buttonAppApplovin.apply {
// setOnClickListener {
// AppLovinSdk.getInstance(context).showMediationDebugger()
// }
// }.isVisible = true
// }
// }
// binding.sTimer.setOnCheckedChangeListener { buttonView, isChecked ->
// if (isChecked) {
// com.zxdemo.utils.GlobalTimer
// .scheduleTask(3 * 1000L, 20 * 1000L)
// } else {
// com.zxdemo.utils.GlobalTimer.stopTaskTimer()
// }
// com.zxdemo.utils.SpUtils.getInstance().putBoolean("sTimer", isChecked)
// }
// binding.sNotify.setOnCheckedChangeListener { buttonView, isChecked ->
// if (isChecked) {
// startOmgNotification()
// } else {
// val serviceIntent = Intent(this, PermanentNotifyService::class.java)
// stopService(serviceIntent)
// }
// com.zxdemo.utils.SpUtils.getInstance().putBoolean("sNotify", isChecked)
// }
//
// binding.buttonAppOpen.setOnClickListener {
// if (com.zxdemo.admob.AdmobHelper.isLoadingAppOpenAd) {
// Toast.makeText(this, "请求开屏广告中请稍后", Toast.LENGTH_SHORT).show()
// return@setOnClickListener
// }
// com.zxdemo.admob.AdmobHelper.showAppOpenAd(this, failed = {
// Toast.makeText(this, "显示开屏广告失败", Toast.LENGTH_SHORT).show()
// })
// }
// binding.buttonInterstitial.setOnClickListener {
// if (com.zxdemo.admob.AdmobHelper.isLoadingInterstitialAd) {
// Toast.makeText(this, "请求插屏广告中请稍后", Toast.LENGTH_SHORT).show()
// return@setOnClickListener
// }
// com.zxdemo.admob.AdmobHelper.showInterstitialAd(this, failed = {
// Toast.makeText(this, "显示插屏广告失败", Toast.LENGTH_SHORT).show()
// })
// }
// binding.buttonBanner.setOnClickListener {
// Toast.makeText(this, "请求Banner广告中请稍后...", Toast.LENGTH_SHORT).show()
// binding.buttonBanner.isClickable = false
// com.zxdemo.admob.AdmobHelper.showBannerAd(
// this,
// binding.frameBanner,
// completed = {
// binding.buttonBanner.isClickable = true
// println()
// },
// failed = {
// binding.buttonBanner.isClickable = true
// Toast.makeText(this, "显示Banner广告失败", Toast.LENGTH_SHORT).show()
// }
// )
// }
// binding.buttonNative.setOnClickListener {
// Toast.makeText(this, "请求原生广告中请稍后...", Toast.LENGTH_SHORT).show()
// binding.buttonNative.isClickable = false
// com.zxdemo.admob.AdmobHelper.showNativeAd(
// this,
// { nativeAd ->
// binding.buttonNative.isClickable = true
// binding.adNative.setNativeAd(nativeAd)
// },
// { nativeAdLoader, nativeMaxAd ->
// binding.buttonNative.isClickable = true
// binding.adNative.setNativeAd(nativeAdLoader, nativeMaxAd)
// },
// {
// binding.buttonNative.isClickable = true
// Toast.makeText(this, "显示原生广告失败", Toast.LENGTH_SHORT).show()
// }
// )
// }
// com.zxdemo.http.ZxHttp.getHttpConfig { }
// com.zxdemo.http.ZxHttp.getBlacklist { com.zxdemo.admob.AdmobHelper.blacklist = it }
// com.zxdemo.admob.AdmobHelper.init(this, {}, {})
// if (!com.zxdemo.admob.AdmobHelper.useAdmob) {
// binding.buttonAppApplovin.apply {
// setOnClickListener {
// AppLovinSdk.getInstance(context).showMediationDebugger()
// }
// }.isVisible = true
// }
// }
//}
\ No newline at end of file
app/src/main/java/com/zxdemo/ZxApplication.kt
0 → 100644
View file @
a8524ab6
package
com.tool.zxdemo
import
android.app.Activity
import
android.app.Application
import
android.app.KeyguardManager
import
android.content.Context
import
android.content.Intent
import
android.content.IntentFilter
import
android.os.Build
import
android.os.Bundle
import
android.os.PowerManager
import
androidx.annotation.RequiresApi
import
com.reyun.solar.engine.SolarEngineConfig
import
com.reyun.solar.engine.SolarEngineManager
import
com.zxdemo.receiver.AppInstallReceiver
import
com.zxdemo.receiver.BatteryStatusReceiver
import
com.zxdemo.receiver.UnlockReceiver
import
com.zxdemo.utils.ActivityCollector
import
com.zxdemo.utils.DeviceUtils
import
com.zxdemo.utils.FcmUtils
import
com.zxdemo.utils.InstallRefeerUtils
import
com.zxdemo.utils.SpUtils
import
java.time.LocalTime
class
ZxApplication
:
Application
()
{
companion
object
{
lateinit
var
context
:
Context
var
APP_STATE
=
0
val
packname
=
"com.testsdktestestababa.aa.com"
var
isDeviceLocked
:
Boolean
=
false
var
isAppInForeground
:
Boolean
=
false
var
isScreenOn
:
Boolean
=
false
var
GID
=
""
val
APP_KEY
=
"f3ea1ff055365453"
val
noLoadingActivities
=
listOf
(
"full"
,
// 过滤全屏广告
"adActivity"
,
"AppLovinFullscreenActivity"
,
// 返回前台时不跳转启动页的 activity
)
}
@RequiresApi
(
Build
.
VERSION_CODES
.
O
)
override
fun
onCreate
()
{
super
.
onCreate
()
DeviceUtils
.
getGoogleAdvertiserId
()
context
=
applicationContext
sendBroadCast
()
registerActivityLifecycleCallbacks
()
val
powerManager
=
getSystemService
(
Context
.
POWER_SERVICE
)
as
PowerManager
isScreenOn
=
powerManager
.
isInteractive
InstallRefeerUtils
.
init
()
}
@RequiresApi
(
Build
.
VERSION_CODES
.
O
)
fun
sendBroadCast
()
{
//注册广播
AppInstallReceiver
.
registerReceiver
(
context
)
UnlockReceiver
().
initBroadcast
(
context
)
val
filter
=
IntentFilter
(
Intent
.
ACTION_BATTERY_CHANGED
)
if
(
context
!=
null
)
{
context
.
registerReceiver
(
BatteryStatusReceiver
(),
filter
)
}
var
minute
=
SpUtils
.
getInstance
().
getInt
(
"MINUTE"
,
-
1
)
if
(
minute
<
0
)
{
minute
=
LocalTime
.
now
().
minute
}
else
{
SpUtils
.
getInstance
().
putInt
(
"MINUTE"
,
minute
)
}
FcmUtils
().
initFirebase
(
context
)
FcmUtils
().
subscribeToTopic
(
"${packname}_push_$minute"
)
var
config
=
SolarEngineConfig
.
Builder
().
build
()
SolarEngineManager
.
getInstance
()
.
initialize
(
context
,
APP_KEY
,
config
)
}
private
var
lastTimePause
=
0L
private
var
lastTimeResume
=
0L
private
fun
isHotLaunch
():
Boolean
{
if
((
lastTimeResume
-
lastTimePause
)
>
5000
)
{
return
true
}
return
false
}
private
fun
registerActivityLifecycleCallbacks
()
{
registerActivityLifecycleCallbacks
(
object
:
ActivityLifecycleCallbacks
{
private
var
count
=
0
override
fun
onActivityCreated
(
activity
:
Activity
,
savedInstanceState
:
Bundle
?)
{
}
override
fun
onActivityStarted
(
activity
:
Activity
)
{
count
++
lastTimeResume
=
System
.
currentTimeMillis
()
if
(
count
==
1
&&
isHotLaunch
())
{
val
topActivity
=
ActivityCollector
.
getTopActivity
()
if
(
topActivity
==
null
)
{
// 跳转启动页
return
}
var
flag
=
noLoadingActivities
.
all
{
!
topActivity
.
localClassName
.
contains
(
it
,
true
)
}
if
(
flag
)
{
// 跳转启动页
}
lastTimeResume
=
0
}
}
override
fun
onActivityResumed
(
activity
:
Activity
)
{
APP_STATE
=
1
isAppInForeground
=
true
}
override
fun
onActivityPaused
(
activity
:
Activity
)
{
APP_STATE
=
2
lastTimePause
=
System
.
currentTimeMillis
()
isAppInForeground
=
false
}
override
fun
onActivityStopped
(
activity
:
Activity
)
{
count
--
}
override
fun
onActivitySaveInstanceState
(
activity
:
Activity
,
outState
:
Bundle
)
{
}
override
fun
onActivityDestroyed
(
activity
:
Activity
)
{
}
})
val
keyguardManager
=
getSystemService
(
Context
.
KEYGUARD_SERVICE
)
as
KeyguardManager
isDeviceLocked
=
keyguardManager
.
isKeyguardLocked
}
}
\ No newline at end of file
app/src/main/java/com/zxdemo/admob/AdmobHelper.kt
0 → 100644
View file @
a8524ab6
This diff is collapsed.
Click to expand it.
app/src/main/java/com/zxdemo/admob/ReportAdUtils.kt
0 → 100644
View file @
a8524ab6
This diff is collapsed.
Click to expand it.
app/src/main/java/com/zxdemo/http/ZxHttp.kt
0 → 100644
View file @
a8524ab6
package
com.zxdemo.http
import
android.util.Log
import
com.swiftcleaner.chovey.BuildConfig
import
com.tool.zxdemo.ZxApplication
import
com.zxdemo.utils.AESUtils
import
com.zxdemo.utils.DeviceUtils
import
com.zxdemo.utils.HttpUtils
import
com.zxdemo.utils.SpUtils
import
okhttp3.Call
import
okhttp3.Callback
import
okhttp3.Response
import
org.json.JSONObject
import
java.io.IOException
object
ZxHttp
{
private
const
val
REPORT_DOMAIN
=
"https://rp.fluxbettingtips.xyz"
private
const
val
INTERFACE_DOMAIN
=
"https://api.fluxbettingtips.xyz"
fun
getHttpConfig
(
requestBack
:
()
->
Unit
)
{
var
referrer
=
""
var
referrerSp
=
SpUtils
.
getInstance
().
getString
(
"referrer"
,
""
)
if
(
referrerSp
.
isNotEmpty
())
{
// referrer = Base64.getEncoder().encodeToString(referrer.toByteArray())
referrer
=
android
.
util
.
Base64
.
encodeToString
(
referrer
.
toByteArray
(),
android
.
util
.
Base64
.
DEFAULT
)
}
val
urlstr
=
StringBuffer
()
urlstr
.
append
(
"$INTERFACE_DOMAIN/ccspk?pkg=${ZxApplication.packname}"
)
urlstr
.
append
(
"&referrer=$referrer"
)
urlstr
.
append
(
"&vn=${BuildConfig.VERSION_NAME}"
)
urlstr
.
append
(
"&vc=${BuildConfig.VERSION_CODE}"
)
urlstr
.
append
(
"&device=${ZxApplication.GID}"
)
urlstr
.
append
(
"&aid=${DeviceUtils.getUID()}"
)
urlstr
.
append
(
"&mode=2"
)
// var url="https://api.swiftdevinc.xyz/ccspk?pkg=${ZxApplication.packname}&referrer=$referrer"
// var url = "https://feedapihk.zhangxinhulian.com/ccspk?pkg=${ZxApplication.packname}&mode=2"
HttpUtils
.
get
(
urlstr
.
toString
(),
object
:
Callback
{
override
fun
onFailure
(
call
:
Call
,
e
:
IOException
)
{
// 请求失败时的处理逻辑
e
.
printStackTrace
()
}
override
fun
onResponse
(
call
:
Call
,
response
:
Response
)
{
requestBack
.
invoke
()
// 请求成功时的处理逻辑
try
{
val
responseString
=
response
.
body
?.
string
()
if
(
responseString
!=
null
&&
responseString
.
contains
(
"result"
))
{
var
jsonObject
=
JSONObject
(
responseString
)
var
status
=
jsonObject
.
getInt
(
"status"
)
if
(
status
==
200
)
{
var
result
=
jsonObject
.
getJSONObject
(
"result"
)
var
data
=
result
.
getString
(
"data"
)
var
decrypt
=
AESUtils
.
decrypt
(
data
.
toString
())
Log
.
d
(
"TAG"
,
"onResponse:decrypt--- $decrypt"
)
SpUtils
.
getInstance
().
saveJsonObjectToSp
(
decrypt
)
}
}
}
catch
(
e
:
IOException
)
{
e
.
printStackTrace
()
}
finally
{
// 确保响应体被关闭
response
.
body
?.
close
()
}
}
})
}
fun
getBlacklist
(
requestBack
:
(
Int
)
->
Unit
)
{
var
jsonParms
=
DeviceUtils
.
getConfigParms
()
// val url = "https://api.swiftdevinc.xyz?pkg=${ZxApplication.packname}"
val
url
=
"$INTERFACE_DOMAIN/jsoncl?pkg=${ZxApplication.packname}"
var
json
=
JSONObject
()
json
.
put
(
"bp"
,
jsonParms
)
HttpUtils
.
postJson
(
url
,
json
.
toString
(),
object
:
Callback
{
override
fun
onFailure
(
call
:
Call
,
e
:
IOException
)
{
// 请求失败时的处理逻辑
requestBack
.
invoke
(
1
)
e
.
printStackTrace
()
}
override
fun
onResponse
(
call
:
Call
,
response
:
Response
)
{
// 请求成功时的处理逻辑
try
{
val
responseString
=
response
.
body
?.
string
()
Log
.
d
(
"TAG"
,
"onResponse: $responseString"
)
if
(
responseString
!=
null
&&
responseString
.
contains
(
"data"
))
{
var
data
=
JSONObject
(
responseString
).
getJSONObject
(
"result"
).
getString
(
"data"
)
if
(
data
==
"true"
)
{
//黑名单中,不展示任何推送
requestBack
.
invoke
(
0
)
}
else
{
requestBack
.
invoke
(
1
)
Log
.
d
(
"TAG"
,
"onResponse: 展示推送"
)
}
}
else
{
requestBack
.
invoke
(
1
)
}
}
catch
(
e
:
IOException
)
{
e
.
printStackTrace
()
requestBack
.
invoke
(
1
)
}
finally
{
// 确保响应体被关闭
response
.
body
?.
close
()
}
}
})
}
fun
getHttpReportInterface
(
action
:
String
,
value
:
String
,
ext
:
JSONObject
?)
{
var
bp
=
DeviceUtils
.
getConfigParms
()
// val url = "https://rp.swiftdevinc.xyz/jsonsp?pkg=${ZxApplication.packname}"
val
url
=
"$REPORT_DOMAIN/jsonsp?pkg=${ZxApplication.packname}"
var
json
=
JSONObject
()
json
.
put
(
"bp"
,
bp
)
var
jData
=
JSONObject
()
jData
.
put
(
"action"
,
action
)
if
(
value
.
isNotEmpty
())
{
jData
.
put
(
"value"
,
value
)
}
jData
.
put
(
"ext"
,
ext
)
json
.
put
(
"data"
,
jData
)
Log
.
d
(
"TAG"
,
"getHttpReportInterface: $json"
)
var
result
=
AESUtils
.
encrypt
(
json
.
toString
())
HttpUtils
.
postJson
(
url
,
result
,
object
:
Callback
{
override
fun
onFailure
(
call
:
Call
,
e
:
IOException
)
{
// 请求失败时的处理逻辑
e
.
printStackTrace
()
Log
.
d
(
"TAG"
,
"onFailure:上报失败 ${e.printStackTrace()}"
)
}
override
fun
onResponse
(
call
:
Call
,
response
:
Response
)
{
Log
.
d
(
"TAG"
,
"onResponse:上报成功 ${response.body} --$json"
)
// 请求成功时的处理逻辑
try
{
val
responseString
=
response
.
body
?.
string
()
if
(
responseString
!=
null
&&
responseString
.
contains
(
"result"
))
{
println
(
"Response -getHttpReportInterface-: $responseString"
)
var
jsonObject
=
JSONObject
(
responseString
)
var
result
=
jsonObject
.
getJSONObject
(
"result"
)
var
data
=
result
.
getString
(
"data"
)
var
decrypt
=
AESUtils
.
decrypt
(
data
.
toString
())
println
(
"Response --: $decrypt"
)
}
}
catch
(
e
:
IOException
)
{
e
.
printStackTrace
()
}
finally
{
// 确保响应体被关闭
response
.
body
?.
close
()
}
}
})
}
}
\ No newline at end of file
app/src/main/java/com/zxdemo/notity/NotificationUtils.kt
0 → 100644
View file @
a8524ab6
package
com.tool.zxdemo.notity
import
android.app.NotificationChannel
import
android.app.NotificationManager
import
android.app.PendingIntent
import
android.content.Context
import
android.content.Intent
import
android.graphics.BitmapFactory
import
android.media.AudioAttributes
import
android.os.Build
import
android.os.Handler
import
android.os.HandlerThread
import
android.util.Log
import
android.widget.RemoteViews
import
androidx.core.app.NotificationCompat
import
androidx.core.app.NotificationManagerCompat
import
androidx.core.content.ContextCompat
import
com.swiftcleaner.chovey.R
import
com.swiftcleaner.chovey.view.MainActivity
import
com.tool.zxdemo.ZxApplication
import
com.tool.zxdemo.ZxApplication.Companion.isAppInForeground
import
com.tool.zxdemo.ZxApplication.Companion.isDeviceLocked
import
com.tool.zxdemo.ZxApplication.Companion.isScreenOn
import
com.zxdemo.http.ZxHttp
import
com.zxdemo.utils.SpUtils
import
java.util.Random
object
NotificationUtils
{
val
ID_CLEAN_JUNK
=
0
val
ID_APP_MANAGER
=
1
val
ID_WHATSAPP
=
2
val
ID_LARGE_FILE
=
3
val
ID_SCREENTSHOT
=
4
val
ID_BATTERY_LOW
=
5
private
val
NOTIFICATION_IDS
=
intArrayOf
(
ID_CLEAN_JUNK
,
ID_APP_MANAGER
,
ID_WHATSAPP
,
ID_LARGE_FILE
,
ID_SCREENTSHOT
,
ID_BATTERY_LOW
,
)
private
var
handlerThread
:
HandlerThread
?
=
null
private
var
handler
:
Handler
?
=
null
private
const
val
CHANNEL_ID
=
"notification_id"
// 通知渠道ID
private
const
val
CHANNEL_NAME
=
"fcm_channel"
// 通知渠道名称
private
const
val
NOTIFICATION_SHOW
=
-
1
private
const
val
NOTICE_CURRENT
=
"notice_current"
fun
createNotificationChannel
(
context
:
Context
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
val
channel
=
NotificationChannel
(
CHANNEL_ID
,
CHANNEL_NAME
,
NotificationManager
.
IMPORTANCE_HIGH
)
channel
.
setShowBadge
(
false
)
channel
.
setSound
(
null
,
AudioAttributes
.
Builder
().
build
())
channel
.
enableVibration
(
false
)
val
manager
=
ContextCompat
.
getSystemService
(
context
,
NotificationManager
::
class
.
java
)
manager
?.
createNotificationChannel
(
channel
)
}
}
fun
sendNotification
(
context
:
Context
,
intent
:
Intent
,
bigRemoteViews
:
RemoteViews
?,
smallRemoteViews
:
RemoteViews
?,
title
:
String
,
action
:
String
,
value
:
String
,
isStay
:
Boolean
?
=
false
)
{
var
notificationCount
=
SpUtils
.
getInstance
().
getInt
(
"notificationCount"
,
45
)
val
currentNum
=
SpUtils
.
getInstance
().
getInt
(
NOTICE_CURRENT
,
0
)
println
(
"isDeviceLocked:$isDeviceLocked isAppInForeground:$isAppInForeground isScreenOn:${!isScreenOn} $value"
)
if
(
isDeviceLocked
||
isAppInForeground
||
!
isScreenOn
||
(
notificationCount
!=
0
&&
currentNum
>=
notificationCount
))
{
return
}
createNotificationChannel
(
context
)
val
notificationManager
=
ContextCompat
.
getSystemService
(
ZxApplication
.
context
,
NotificationManager
::
class
.
java
)
as
NotificationManager
val
pendingIntent
=
PendingIntent
.
getActivity
(
context
,
// context
0
,
// request code
intent
,
// intent
PendingIntent
.
FLAG_UPDATE_CURRENT
or
PendingIntent
.
FLAG_IMMUTABLE
// flags
)
val
builder
=
NotificationCompat
.
Builder
(
context
,
CHANNEL_ID
)
.
setLargeIcon
(
BitmapFactory
.
decodeResource
(
context
.
resources
,
R
.
mipmap
.
ic_launcher
)
)
.
setSmallIcon
(
R
.
mipmap
.
ic_launcher_round
)
.
setVibrate
(
longArrayOf
(
0
))
// 禁止震动
.
setSound
(
null
)
// 禁止声音
.
setContentTitle
(
title
)
// .setContentText(context.resources.getString(R.string.app_name))
.
setContentIntent
(
pendingIntent
)
// .setDeleteIntent(deletePendingIntent)
.
setPriority
(
NotificationCompat
.
PRIORITY_MAX
)
.
setAutoCancel
(
true
)
var
small
=
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
)
var
actionId
=
intent
.
getIntExtra
(
"actionId"
,
0
)
if
(
actionId
<
10
)
incrementNotification
()
//存入推送的时间
if
(
isStay
==
false
)
{
ZxHttp
.
getHttpReportInterface
(
action
,
value
,
null
)
}
notificationManager
.
notify
(
actionId
,
builder
.
build
())
}
fun
sendNotification
(
context
:
Context
,
action
:
String
,
value
:
String
)
{
var
actionId
=
nextNotificationId
val
bigRemoteViews
=
RemoteViews
(
context
.
packageName
,
R
.
layout
.
notice_expand
)
val
smallRemoteViews
=
RemoteViews
(
context
.
packageName
,
R
.
layout
.
notice_fold
)
when
(
actionId
)
{
ID_CLEAN_JUNK
->
{
}
ID_APP_MANAGER
->
{
}
ID_WHATSAPP
->
{
}
ID_LARGE_FILE
->
{
}
ID_SCREENTSHOT
->
{
}
ID_BATTERY_LOW
->
{
}
else
->
{
return
}
}
val
flag
=
PendingIntent
.
FLAG_IMMUTABLE
val
btnRequestCode
=
Random
().
nextInt
(
1000
)
var
intent
=
Intent
(
context
,
MainActivity
::
class
.
java
)
intent
.
putExtra
(
"actionId"
,
actionId
)
val
btnPendingIntent
=
PendingIntent
.
getActivity
(
context
,
btnRequestCode
,
intent
,
flag
)
// bigRemoteViews.setOnClickPendingIntent(R.id.btn_notice, btnPendingIntent)
// smallRemoteViews.setOnClickPendingIntent(R.id.notice_btn, btnPendingIntent)
val
open
=
SpUtils
.
getInstance
().
getInt
(
"NotificationStayStatus"
,
0
)
if
(
open
==
1
)
{
val
num
=
SpUtils
.
getInstance
().
getInt
(
"NotificationStayCount"
,
5
)
val
delay
=
SpUtils
.
getInstance
().
getInt
(
"NotificationStayDelay"
,
4000
).
toLong
()
handlerThread
=
HandlerThread
(
"NotificationHandlerThread"
)
handlerThread
!!
.
start
()
// 创建 Handler
handler
=
Handler
(
handlerThread
!!
.
getLooper
())
for
(
i
in
1
..
num
)
{
val
time
=
i
*
delay
handler
?.
postDelayed
(
Runnable
{
if
(
ZxApplication
.
APP_STATE
==
1
)
{
if
(
handler
!=
null
)
{
handler
?.
removeCallbacksAndMessages
(
null
)
}
return
@Runnable
}
if
(
ZxApplication
.
APP_STATE
!=
1
)
{
sendNotification
(
context
,
intent
,
bigRemoteViews
,
smallRemoteViews
,
"titletitle"
,
action
,
value
,
isStay
=
true
)
if
(
i
==
1
)
{
Log
.
d
(
"TAG"
,
"sendNotification:isStay == true $value $actionId "
)
ZxHttp
.
getHttpReportInterface
(
action
,
"$actionId"
,
null
)
}
}
},
time
)
}
}
else
{
sendNotification
(
context
,
intent
,
bigRemoteViews
,
smallRemoteViews
,
"titletitle"
,
action
,
value
,
isStay
=
false
)
}
}
private
var
currentNotificationIdIndex
=
-
1
val
nextNotificationId
:
Int
get
()
{
// 将当前通知 ID 索引加 1
currentNotificationIdIndex
++
// 如果当前通知 ID 索引超出列表范围,则将其重置为 0
if
(
currentNotificationIdIndex
>=
NOTIFICATION_IDS
.
size
)
{
currentNotificationIdIndex
=
0
}
// 返回下一个通知 ID
return
NOTIFICATION_IDS
[
currentNotificationIdIndex
]
}
private
fun
incrementNotification
()
{
var
s
=
SpUtils
.
getInstance
().
getInt
(
NOTICE_CURRENT
,
0
)
s
++
SpUtils
.
getInstance
().
putInt
(
NOTICE_CURRENT
,
s
)
}
fun
checkNotificationPermission
(
context
:
Context
):
Boolean
{
return
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
KITKAT
)
{
NotificationManagerCompat
.
from
(
context
).
areNotificationsEnabled
()
}
else
{
true
}
}
}
app/src/main/java/com/zxdemo/receiver/AppInstallReceiver.kt
0 → 100644
View file @
a8524ab6
package
com.zxdemo.receiver
import
android.content.BroadcastReceiver
import
android.content.Context
import
android.content.Intent
import
android.content.IntentFilter
import
android.os.Build
import
android.util.Log
import
androidx.annotation.RequiresApi
import
com.tool.zxdemo.notity.NotificationUtils
import
com.zxdemo.utils.SpUtils
import
java.time.LocalDateTime
import
java.time.format.DateTimeFormatter
import
java.time.temporal.ChronoUnit
class
AppInstallReceiver
:
BroadcastReceiver
()
{
companion
object
{
fun
registerReceiver
(
context
:
Context
)
{
val
intentFilter
=
IntentFilter
()
intentFilter
.
addAction
(
Intent
.
ACTION_PACKAGE_REMOVED
)
//卸载
intentFilter
.
addAction
(
Intent
.
ACTION_PACKAGE_ADDED
)
//安装
intentFilter
.
addDataScheme
(
"package"
)
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
TIRAMISU
)
{
context
.
registerReceiver
(
AppInstallReceiver
(),
intentFilter
,
Context
.
RECEIVER_EXPORTED
)
}
else
{
context
.
registerReceiver
(
AppInstallReceiver
(),
intentFilter
)
}
}
}
@RequiresApi
(
Build
.
VERSION_CODES
.
O
)
override
fun
onReceive
(
context
:
Context
,
intent
:
Intent
)
{
//获取当前时间和上一次推送的时间
var
current
=
LocalDateTime
.
now
()
val
intervalTime
=
1L
//间隔时间(分钟)
val
lastTime
=
SpUtils
.
getInstance
().
getString
(
"NOTICE_APP_TIME"
,
""
)
var
parsedDateTime
:
LocalDateTime
=
current
if
(
lastTime
!=
""
)
{
parsedDateTime
=
LocalDateTime
.
parse
(
lastTime
,
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd HH:mm"
))
}
// 计算两个时间点之间的差异
val
minutesBetween
=
ChronoUnit
.
MINUTES
.
between
(
parsedDateTime
,
current
)
if
(
minutesBetween
>=
intervalTime
||
minutesBetween
.
toInt
()
==
0
)
{
intent
.
action
?.
let
{
Log
.
d
(
"TAG"
,
"onReceive:安装卸载推送 ${intent.action}"
)
NotificationUtils
.
sendNotification
(
context
,
"showNotification"
,
"receive_app"
)
SpUtils
.
getInstance
().
putString
(
"NOTICE_APP_TIME"
,
current
.
format
(
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd HH:mm"
))
)
}
}
}
}
app/src/main/java/com/zxdemo/receiver/BatteryStatusReceiver.kt
0 → 100644
View file @
a8524ab6
package
com.zxdemo.receiver
import
android.content.BroadcastReceiver
import
android.content.Context
import
android.content.Intent
import
android.os.BatteryManager
import
android.os.Build
import
android.util.Log
import
androidx.annotation.RequiresApi
import
com.tool.zxdemo.notity.NotificationUtils
import
com.zxdemo.utils.SpUtils
import
java.time.LocalDateTime
import
java.time.format.DateTimeFormatter
import
java.time.temporal.ChronoUnit
class
BatteryStatusReceiver
()
:
BroadcastReceiver
()
{
@RequiresApi
(
Build
.
VERSION_CODES
.
O
)
override
fun
onReceive
(
context
:
Context
?,
batteryIntent
:
Intent
?)
{
val
level
=
batteryIntent
?.
getIntExtra
(
BatteryManager
.
EXTRA_LEVEL
,
-
1
)
?:
-
1
val
scale
=
batteryIntent
?.
getIntExtra
(
BatteryManager
.
EXTRA_SCALE
,
-
1
)
?:
-
1
val
state
=
batteryIntent
?.
getIntExtra
(
BatteryManager
.
EXTRA_STATUS
,
-
1
)
?:
-
1
val
now
=
batteryIntent
?.
getIntExtra
(
BatteryManager
.
BATTERY_PROPERTY_CURRENT_NOW
.
toString
(),
-
1
)
?:
-
1
val
health
=
batteryIntent
?.
getIntExtra
(
BatteryManager
.
EXTRA_HEALTH
,
-
1
)
?:
-
1
val
voltage
=
batteryIntent
?.
getIntExtra
(
BatteryManager
.
EXTRA_VOLTAGE
,
-
1
)
?:
-
1
val
temperature
=
batteryIntent
?.
getIntExtra
(
BatteryManager
.
EXTRA_TEMPERATURE
,
-
1
)
?:
-
1
val
technology
=
batteryIntent
?.
getStringExtra
(
BatteryManager
.
EXTRA_TECHNOLOGY
)
?:
"Unknown"
val
batteryPct
=
level
*
100
/
scale
.
toFloat
()
val
intervalTime
=
SpUtils
.
getInstance
().
getInt
(
"batteryNotificationInterval"
,
5
)
var
current
=
LocalDateTime
.
now
()
var
lastTime
=
SpUtils
.
getInstance
().
getString
(
"NOTICE_BATTERY_TIME"
,
""
)
var
parsedDateTime
=
current
if
(
lastTime
!=
""
)
{
parsedDateTime
=
LocalDateTime
.
parse
(
lastTime
,
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd HH:mm"
))
}
var
batteryNotificationStatus
=
SpUtils
.
getInstance
().
getInt
(
"batteryNotificationStatus"
,
0
)
val
minutesBetween
=
ChronoUnit
.
MINUTES
.
between
(
parsedDateTime
,
current
)
// Log.d("TAG", "onReceive:电池 $minutesBetween $intervalTime")
if
((
batteryNotificationStatus
==
1
&&
(
minutesBetween
>
intervalTime
&&
minutesBetween
.
toInt
()
==
0
))
&&
(
state
==
BatteryManager
.
BATTERY_STATUS_CHARGING
||
(
level
<
20
&&
level
>
10
)))
{
Log
.
d
(
"TAG"
,
"onReceive: 电池推送"
)
if
(
context
!=
null
)
{
NotificationUtils
.
sendNotification
(
context
,
"showNotification"
,
"receive_battery"
)
SpUtils
.
getInstance
().
putString
(
"NOTICE_BATTERY_TIME"
,
current
.
format
(
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd HH:mm"
))
)
}
}
}
}
\ No newline at end of file
app/src/main/java/com/zxdemo/receiver/FcmReceiver.kt
0 → 100644
View file @
a8524ab6
package
com.zxdemo.receiver
import
android.content.BroadcastReceiver
import
android.content.Context
import
android.content.Intent
import
android.util.Log
class
FcmReceiver
:
BroadcastReceiver
()
{
override
fun
onReceive
(
context
:
Context
?,
intent
:
Intent
?)
{
Log
.
d
(
"TAG"
,
"onReceive:$intent "
)
}
}
\ No newline at end of file
app/src/main/java/com/zxdemo/receiver/UnlockReceiver.kt
0 → 100644
View file @
a8524ab6
package
com.zxdemo.receiver
import
android.content.BroadcastReceiver
import
android.content.Context
import
android.content.Intent
import
android.content.IntentFilter
import
android.os.Build
import
android.util.Log
import
androidx.annotation.RequiresApi
import
com.tool.zxdemo.ZxApplication
import
com.tool.zxdemo.notity.NotificationUtils
import
com.zxdemo.utils.SpUtils
import
java.time.LocalDateTime
import
java.time.format.DateTimeFormatter
import
java.time.temporal.ChronoUnit
class
UnlockReceiver
:
BroadcastReceiver
()
{
companion
object
{
var
mIsScreenOn
=
true
var
isLock
=
false
}
fun
initBroadcast
(
context
:
Context
)
{
Log
.
d
(
"onReceive"
,
"initBroadcast"
)
val
filter
=
IntentFilter
()
filter
.
addAction
(
Intent
.
ACTION_SCREEN_OFF
)
filter
.
addAction
(
Intent
.
ACTION_SCREEN_ON
)
filter
.
addAction
(
Intent
.
ACTION_USER_PRESENT
)
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
TIRAMISU
)
{
context
.
registerReceiver
(
this
,
filter
,
Context
.
RECEIVER_EXPORTED
)
}
else
{
context
.
registerReceiver
(
this
,
filter
)
}
}
@RequiresApi
(
Build
.
VERSION_CODES
.
O
)
override
fun
onReceive
(
context
:
Context
,
intent
:
Intent
)
{
val
action
=
intent
.
action
when
(
action
)
{
Intent
.
ACTION_SCREEN_ON
->
{
mIsScreenOn
=
true
}
Intent
.
ACTION_SCREEN_OFF
->
{
mIsScreenOn
=
false
isLock
=
true
}
Intent
.
ACTION_USER_PRESENT
->
{
isLock
=
false
// 执行解锁后的操作,比如启动服务、发送通知等
var
lockNotificationInterval
=
SpUtils
.
getInstance
().
getInt
(
"lockNotificationInterval"
)
val
lastTime
=
SpUtils
.
getInstance
()
.
getString
(
"NOTICE_UNLOCK_TIME"
,
""
)
var
current
=
LocalDateTime
.
now
()
var
parsedDateTime
:
LocalDateTime
=
current
if
(
lastTime
!=
""
)
{
parsedDateTime
=
LocalDateTime
.
parse
(
lastTime
,
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd HH:mm"
)
)
}
val
minutesBetween
=
ChronoUnit
.
MINUTES
.
between
(
parsedDateTime
,
current
)
Log
.
d
(
"TAG"
,
"onReceive:: $minutesBetween"
)
var
lockNotificationStatus
=
SpUtils
.
getInstance
().
getInt
(
"lockNotificationStatus"
,
0
)
var
lockNotificationCount
=
SpUtils
.
getInstance
().
getInt
(
"lockNotificationCount"
,
45
)
var
count
=
SpUtils
.
getInstance
().
getInt
(
"NOTICE_UNLOCK_COUNT"
,
0
)
//获取当前时间和上一次推送的时间
if
(
lockNotificationStatus
==
1
&&
mIsScreenOn
&&
!
isLock
&&
(
minutesBetween
.
toInt
()
==
0
||
minutesBetween
>
lockNotificationInterval
))
{
if
(
lockNotificationCount
==
0
||
count
<
lockNotificationCount
)
{
Log
.
d
(
"TAG"
,
"onReceive: 解锁推送"
)
NotificationUtils
.
sendNotification
(
ZxApplication
.
context
,
"showNotification"
,
"receive_unlock"
)
SpUtils
.
getInstance
().
putString
(
"NOTICE_UNLOCK_COUNT"
,
current
.
format
(
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd HH:mm"
))
)
}
}
}
else
->
{
}
}
}
}
\ No newline at end of file
app/src/main/java/com/zxdemo/service/FcmService.kt
0 → 100644
View file @
a8524ab6
package
com.zxdemo.service
import
android.util.Log
import
com.google.firebase.messaging.FirebaseMessagingService
import
com.google.firebase.messaging.RemoteMessage
import
com.tool.zxdemo.ZxApplication
import
com.tool.zxdemo.notity.NotificationUtils
import
com.zxdemo.http.ZxHttp
class
FcmService
:
FirebaseMessagingService
()
{
override
fun
onMessageReceived
(
message
:
RemoteMessage
)
{
Log
.
d
(
"TAG"
,
"onMessageReceived: ${message.data}"
)
ZxHttp
.
getHttpReportInterface
(
"FCM_Received"
,
""
,
null
)
NotificationUtils
.
sendNotification
(
ZxApplication
.
context
,
"showNotification"
,
"FCM"
)
}
}
\ No newline at end of file
app/src/main/java/com/zxdemo/service/PermanentNotifyService.kt
0 → 100644
View file @
a8524ab6
package
com.tool.zxdemo.service
import
android.app.Notification
import
android.app.NotificationChannel
import
android.app.NotificationManager
import
android.app.PendingIntent
import
android.app.Service
import
android.content.Context
import
android.content.Intent
import
android.content.pm.ServiceInfo
import
android.graphics.BitmapFactory
import
android.os.Build
import
android.os.IBinder
import
android.widget.RemoteViews
import
androidx.core.app.NotificationCompat
import
com.swiftcleaner.chovey.R
import
com.swiftcleaner.chovey.view.MainActivity
class
PermanentNotifyService
:
Service
()
{
companion
object
{
var
isRunning
=
false
fun
Context
.
startOmgNotification
()
{
val
intent
=
Intent
(
this
,
PermanentNotifyService
::
class
.
java
)
// if (Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU) {
// return
// }
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
startForegroundService
(
intent
)
}
else
{
startService
(
intent
)
}
}
}
override
fun
onStartCommand
(
intent
:
Intent
?,
flags
:
Int
,
startId
:
Int
):
Int
{
if
(!
isRunning
)
{
val
notification
=
createPermanentNotification
(
applicationContext
)
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
Q
)
{
startForeground
(
16
,
notification
,
ServiceInfo
.
FOREGROUND_SERVICE_TYPE_DATA_SYNC
)
}
else
{
startForeground
(
16
,
notification
)
}
isRunning
=
true
}
return
START_STICKY
}
override
fun
onBind
(
intent
:
Intent
?):
IBinder
?
{
return
null
}
override
fun
onDestroy
()
{
isRunning
=
false
super
.
onDestroy
()
// 取消监听
}
private
fun
createPermanentNotification
(
context
:
Context
):
Notification
{
val
isOngoing
=
true
//是否持续(为不消失的常驻通知)
val
channelName
=
"Foreground Service Channel"
val
channelId
=
"Service_Id"
val
category
=
Notification
.
CATEGORY_SERVICE
val
contentView
=
RemoteViews
(
context
.
packageName
,
R
.
layout
.
notice_fold
)
val
expendView
=
RemoteViews
(
context
.
packageName
,
R
.
layout
.
notice_fold
)
val
cleanIntent
=
PendingIntent
.
getActivity
(
context
,
// context
0
,
// request code
Intent
(
"CleanJunkActivity"
,
null
,
context
,
MainActivity
::
class
.
java
),
// intent
PendingIntent
.
FLAG_UPDATE_CURRENT
or
PendingIntent
.
FLAG_IMMUTABLE
// flags
)
// contentView.setOnClickPendingIntent(R.id.tv_clean, cleanIntent)
// expendView.setOnClickPendingIntent(R.id.tv_clean, cleanIntent)
val
appIntent
=
PendingIntent
.
getActivity
(
context
,
// context
0
,
// request code
Intent
(
"AppManagerActivity"
,
null
,
context
,
MainActivity
::
class
.
java
),
// intent
PendingIntent
.
FLAG_UPDATE_CURRENT
or
PendingIntent
.
FLAG_IMMUTABLE
// flags
)
// contentView.setOnClickPendingIntent(R.id.tv_app, appIntent)
// expendView.setOnClickPendingIntent(R.id.tv_app, appIntent)
val
whatsIntent
=
PendingIntent
.
getActivity
(
context
,
// context
0
,
// request code
Intent
(
"CleanerActivity"
,
null
,
context
,
MainActivity
::
class
.
java
),
// intent
PendingIntent
.
FLAG_UPDATE_CURRENT
or
PendingIntent
.
FLAG_IMMUTABLE
// flags
)
// contentView.setOnClickPendingIntent(R.id.tv_whatsapp, whatsIntent)
// expendView.setOnClickPendingIntent(R.id.tv_whatsapp, whatsIntent)
val
largeIntent
=
PendingIntent
.
getActivity
(
context
,
// context
0
,
// request code
Intent
(
"LargeFileCleanActivity"
,
null
,
context
,
MainActivity
::
class
.
java
),
// intent
PendingIntent
.
FLAG_UPDATE_CURRENT
or
PendingIntent
.
FLAG_IMMUTABLE
// flags
)
// contentView.setOnClickPendingIntent(R.id.tv_large, largeIntent)
// expendView.setOnClickPendingIntent(R.id.tv_large, largeIntent)
val
nfIntent
=
Intent
(
context
,
MainActivity
::
class
.
java
)
val
pendingIntent
=
PendingIntent
.
getActivity
(
context
,
0
,
nfIntent
,
PendingIntent
.
FLAG_IMMUTABLE
)
val
builder
=
NotificationCompat
.
Builder
(
context
,
channelId
)
// builder.setSmallIcon(R.drawable.lig) //设置状态栏内的小图标
// builder.setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.icon_apk))
builder
.
setContentTitle
(
context
.
resources
.
getString
(
R
.
string
.
app_name
))
builder
.
setContentIntent
(
pendingIntent
)
//设置PendingIntent
builder
.
setVisibility
(
NotificationCompat
.
VISIBILITY_PRIVATE
)
//设置通知公开可见
builder
.
setAutoCancel
(
false
)
builder
.
priority
=
NotificationCompat
.
PRIORITY_MAX
//优先级为:重要通知
builder
.
setWhen
(
System
.
currentTimeMillis
())
builder
.
setCustomContentView
(
contentView
)
builder
.
setCustomBigContentView
(
expendView
)
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
val
channel
=
NotificationChannel
(
channelId
,
channelName
,
NotificationManager
.
IMPORTANCE_LOW
)
channel
.
lockscreenVisibility
=
1
val
notificationManager
=
context
.
getSystemService
(
Context
.
NOTIFICATION_SERVICE
)
as
NotificationManager
notificationManager
.
createNotificationChannel
(
channel
)
builder
.
setChannelId
(
channelId
)
}
return
builder
.
build
()
}
}
\ No newline at end of file
app/src/main/java/com/zxdemo/utils/AESUtils.kt
0 → 100644
View file @
a8524ab6
package
com.zxdemo.utils
import
android.util.Base64
import
java.security.SecureRandom
import
javax.crypto.Cipher
import
javax.crypto.spec.GCMParameterSpec
import
javax.crypto.spec.SecretKeySpec
object
AESUtils
{
private
const
val
aesKey
=
"mj7lm6bfcez79lr8"
private
val
cipher
by
lazy
{
Cipher
.
getInstance
(
"AES/GCM/NoPadding"
)
}
fun
encrypt
(
content
:
String
):
String
{
try
{
val
iv
=
ByteArray
(
12
).
apply
{
SecureRandom
().
nextBytes
(
this
)
}
val
contentBytes
=
content
.
toByteArray
(
Charsets
.
UTF_8
)
val
params
=
GCMParameterSpec
(
128
,
iv
)
cipher
.
init
(
Cipher
.
ENCRYPT_MODE
,
secretKey
,
params
)
val
encryptData
=
cipher
.
doFinal
(
contentBytes
)
if
(
encryptData
.
size
!=
contentBytes
.
size
+
16
)
{
throw
IllegalStateException
(
"Encryption failed"
)
}
val
message
=
ByteArray
(
12
+
contentBytes
.
size
+
16
)
System
.
arraycopy
(
iv
,
0
,
message
,
0
,
12
)
System
.
arraycopy
(
encryptData
,
0
,
message
,
12
,
encryptData
.
size
)
return
String
(
Base64
.
encode
(
message
,
Base64
.
NO_WRAP
),
Charsets
.
UTF_8
)
}
catch
(
_
:
Exception
)
{
}
return
content
}
@Synchronized
fun
decrypt
(
content
:
String
):
String
{
try
{
val
con
=
content
.
replace
(
" "
.
toRegex
(),
"+"
)
val
contentByte
=
Base64
.
decode
(
con
,
Base64
.
NO_WRAP
)
require
(
contentByte
.
size
>=
12
+
16
)
val
params
=
GCMParameterSpec
(
128
,
contentByte
,
0
,
12
)
cipher
.
init
(
Cipher
.
DECRYPT_MODE
,
secretKey
,
params
)
val
decryptData
=
cipher
.
doFinal
(
contentByte
,
12
,
contentByte
.
size
-
12
)
return
String
(
decryptData
,
Charsets
.
UTF_8
)
}
catch
(
_
:
Exception
)
{
}
return
content
}
private
val
secretKey
by
lazy
{
SecretKeySpec
(
aesKey
.
toByteArray
(),
"AES"
)
}
}
\ No newline at end of file
app/src/main/java/com/zxdemo/utils/ActivityCollector.kt
0 → 100644
View file @
a8524ab6
package
com.zxdemo.utils
import
android.app.Activity
import
java.util.Stack
object
ActivityCollector
{
private
val
activityStack
=
Stack
<
Activity
>()
/**
* 添加Activity到堆栈
*/
fun
add
(
activity
:
Activity
)
{
activityStack
.
add
(
activity
)
}
/**
* 移除Activity从堆栈
*/
fun
remove
(
activity
:
Activity
)
{
activityStack
.
remove
(
activity
)
}
/**
* 结束指定的Activity
*/
fun
finish
(
activity
:
Activity
?)
{
if
(
activity
!=
null
)
{
activityStack
.
remove
(
activity
)
activity
.
finish
()
}
}
/**
* 结束所有Activity
*/
fun
finishAll
()
{
for
(
activity
in
activityStack
)
{
activity
?.
finish
()
}
activityStack
.
clear
()
}
/**
* 检查Activity是否存在于堆栈中
*/
fun
isActivityInStack
(
cls
:
Class
<
*
>?):
Boolean
{
var
isExist
=
false
if
(
cls
!=
null
)
{
for
(
activity
in
activityStack
)
{
if
(
cls
==
activity
.
javaClass
)
{
isExist
=
true
break
}
}
}
return
isExist
}
fun
getAll
():
List
<
Activity
>
{
return
activityStack
}
fun
getTopActivity
():
Activity
?
{
return
if
(
activityStack
.
isEmpty
())
{
null
}
else
{
activityStack
.
peek
()
}
}
}
\ No newline at end of file
app/src/main/java/com/zxdemo/utils/DeviceUtils.kt
0 → 100644
View file @
a8524ab6
package
com.zxdemo.utils
import
android.os.Build
import
android.provider.Settings
import
android.util.Log
import
android.webkit.WebSettings
import
com.google.android.gms.ads.identifier.AdvertisingIdClient
import
com.tool.zxdemo.ZxApplication
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.GlobalScope
import
kotlinx.coroutines.launch
import
org.json.JSONObject
import
java.util.UUID
object
DeviceUtils
{
fun
getScreenHeight
():
Int
{
return
ZxApplication
.
context
.
resources
.
displayMetrics
.
heightPixels
}
fun
getScreenWidth
():
Int
{
return
ZxApplication
.
context
.
resources
.
displayMetrics
.
widthPixels
}
fun
getDeviceModel
():
String
{
return
Build
.
MODEL
}
fun
getManufacturer
():
String
{
return
Build
.
MANUFACTURER
}
fun
getAndroidVersion
():
String
{
return
Build
.
VERSION
.
RELEASE
}
fun
getAppVersion
():
String
{
return
try
{
val
packageInfo
=
ZxApplication
.
context
.
packageManager
.
getPackageInfo
(
ZxApplication
.
context
.
packageName
,
0
)
packageInfo
.
versionName
}
catch
(
e
:
Exception
)
{
"Unknown"
}
}
fun
getAndroidID
():
String
{
return
Settings
.
Secure
.
getString
(
ZxApplication
.
context
.
contentResolver
,
Settings
.
Secure
.
ANDROID_ID
)
}
fun
getGoogleAdvertiserId
()
{
GlobalScope
.
launch
(
Dispatchers
.
IO
)
{
try
{
ZxApplication
.
GID
=
AdvertisingIdClient
.
getAdvertisingIdInfo
(
ZxApplication
.
context
).
id
?:
""
}
catch
(
e
:
Exception
)
{
Log
.
d
(
"TAG"
,
"getGoogleAdvertiserId: ${e.printStackTrace()}"
)
}
}
}
fun
getUID
():
String
{
return
UUID
.
randomUUID
().
toString
()
+
System
.
currentTimeMillis
()
}
fun
getUserAgent
():
String
{
return
WebSettings
.
getDefaultUserAgent
(
ZxApplication
.
context
)
}
fun
getAndroidVersionCode
():
Int
{
return
Build
.
VERSION
.
SDK_INT
}
fun
getConfigParms
():
JSONObject
{
var
packname
=
"com.a.xxxxxx.m.storage.zxcv"
var
jsonObject
=
JSONObject
()
jsonObject
.
put
(
"${packname}_1"
,
getScreenHeight
())
//高度
jsonObject
.
put
(
"${packname}_2"
,
getScreenWidth
())
//宽度
jsonObject
.
put
(
"${packname}_3"
,
getDeviceModel
())
//手机型号
jsonObject
.
put
(
"${packname}_4"
,
getManufacturer
())
//手机厂商
jsonObject
.
put
(
"${packname}_5"
,
getAndroidVersion
())
//android系统版本号
jsonObject
.
put
(
"${packname}_8"
,
getAppVersion
())
//APP版本号,如:1.1.2
jsonObject
.
put
(
"${packname}_9"
,
getAndroidID
())
//Android id
jsonObject
.
put
(
"${packname}_10"
,
ZxApplication
.
GID
)
//Google advertiser id
jsonObject
.
put
(
"${packname}_11"
,
getUserAgent
())
//User agent
jsonObject
.
put
(
"${packname}_12"
,
getUID
())
//用户id
jsonObject
.
put
(
"${packname}_13"
,
"android"
)
//platform 默认android
jsonObject
.
put
(
"${packname}_14"
,
getAndroidVersionCode
())
//android版本,如:13
// jsonObject.put("${packname}_23","en")//语言
// jsonObject.put("${packname}_24", BuildConfig.BUILD_TYPE)//环境
return
jsonObject
}
}
\ No newline at end of file
app/src/main/java/com/zxdemo/utils/FcmUtils.kt
0 → 100644
View file @
a8524ab6
package
com.zxdemo.utils
import
android.content.Context
import
android.util.Log
import
com.google.android.gms.tasks.OnCompleteListener
import
com.google.firebase.FirebaseApp
import
com.google.firebase.messaging.FirebaseMessaging
import
com.zxdemo.http.ZxHttp
class
FcmUtils
{
fun
initFirebase
(
context
:
Context
?)
{
FirebaseApp
.
initializeApp
(
context
!!
)
}
fun
subscribeToTopic
(
topic
:
String
)
{
Log
.
d
(
"TAG"
,
"subscribeToTopic: $topic"
)
FirebaseMessaging
.
getInstance
().
subscribeToTopic
(
topic
).
addOnCompleteListener
{
Log
.
d
(
"TAG"
,
"subscribeToTopic:isSuccessful ${it.isSuccessful}"
)
if
(
it
.
isSuccessful
)
{
ZxHttp
.
getHttpReportInterface
(
"FCM_Topic$topic"
,
""
,
null
)
Log
.
d
(
"FCMUtil"
,
"suc"
)
}
else
{
Log
.
d
(
"FCMUtil"
,
"fail"
)
}
}
}
fun
unsubscribeFromTopic
(
topic
:
String
)
{
FirebaseMessaging
.
getInstance
().
unsubscribeFromTopic
(
topic
)
.
addOnCompleteListener
(
OnCompleteListener
<
Void
?>
{
task
->
if
(
task
.
isSuccessful
)
{
}
else
{
}
})
}
}
\ No newline at end of file
app/src/main/java/com/zxdemo/utils/GlobalTimer.kt
0 → 100644
View file @
a8524ab6
package
com.zxdemo.utils
import
android.util.Log
import
com.tool.zxdemo.ZxApplication
import
com.tool.zxdemo.ZxApplication.Companion.isAppInForeground
import
com.tool.zxdemo.ZxApplication.Companion.isDeviceLocked
import
com.tool.zxdemo.ZxApplication.Companion.isScreenOn
import
com.tool.zxdemo.notity.NotificationUtils
import
java.util.Timer
import
java.util.TimerTask
object
GlobalTimer
{
private
var
instance
:
GlobalTimer
?
=
null
private
var
taskTimer
:
Timer
?
=
null
private
var
isTimerActive
=
false
// 单例模式获取实例
fun
getInstance
():
GlobalTimer
{
if
(
instance
==
null
)
{
instance
=
GlobalTimer
}
return
instance
!!
}
// 调度任务
fun
scheduleTask
(
delay
:
Long
,
period
:
Long
)
{
synchronized
(
GlobalTimer
::
class
)
{
ensureTimerIsStopped
()
// 确保定时器未运行
taskTimer
=
Timer
()
// 创建新的 Timer 实例
val
task
=
object
:
TimerTask
()
{
override
fun
run
()
{
Log
.
d
(
"glc"
,
"Scheduled task is running"
)
Log
.
d
(
"glc"
,
"${!isDeviceLocked} ${!isAppInForeground} $isScreenOn"
)
// 确保设备处于交互状态,未锁定,且应用未暂停
NotificationUtils
.
sendNotification
(
ZxApplication
.
context
,
"showNotification"
,
"timer"
)
}
}
taskTimer
!!
.
schedule
(
task
,
delay
,
period
)
// 调度任务
isTimerActive
=
true
// 设置定时器状态为活跃
}
}
// 确保定时器停止
private
fun
ensureTimerIsStopped
()
{
if
(
isTimerActive
)
{
if
(
taskTimer
!=
null
)
{
taskTimer
!!
.
cancel
()
taskTimer
!!
.
purge
()
// 清除所有取消的任务
}
isTimerActive
=
false
// 重置定时器状态
}
}
// 停止任务定时器
fun
stopTaskTimer
()
{
synchronized
(
GlobalTimer
::
class
)
{
ensureTimerIsStopped
()
// 停止定时器
}
}
// 检查任务定时器是否活跃
fun
isTaskTimerActive
():
Boolean
{
return
isTimerActive
}
}
app/src/main/java/com/zxdemo/utils/HttpUtils.kt
0 → 100644
View file @
a8524ab6
package
com.zxdemo.utils
import
okhttp3.Callback
import
okhttp3.FormBody
import
okhttp3.MediaType.Companion.toMediaTypeOrNull
import
okhttp3.OkHttpClient
import
okhttp3.Request
import
okhttp3.RequestBody
object
HttpUtils
{
private
val
client
=
OkHttpClient
()
// GET 请求
fun
get
(
url
:
String
,
callback
:
Callback
)
{
val
request
=
Request
.
Builder
().
url
(
url
).
build
()
client
.
newCall
(
request
).
enqueue
(
callback
)
}
// POST 请求,传入 JSON 字符串
fun
postJson
(
url
:
String
,
json
:
String
,
callback
:
Callback
)
{
val
mediaType
=
"application/json; charset=utf-8"
.
toMediaTypeOrNull
()
val
body
:
RequestBody
=
RequestBody
.
create
(
mediaType
,
json
)
val
request
=
Request
.
Builder
().
url
(
url
).
post
(
body
).
build
()
client
.
newCall
(
request
).
enqueue
(
callback
)
}
// POST 请求,传入表单数据
fun
postForm
(
url
:
String
,
params
:
Map
<
String
,
String
>,
callback
:
Callback
)
{
val
formBody
=
FormBody
.
Builder
().
apply
{
params
.
forEach
{
(
key
,
value
)
->
add
(
key
,
value
)
}
}.
build
()
val
request
=
Request
.
Builder
().
url
(
url
).
post
(
formBody
).
build
()
client
.
newCall
(
request
).
enqueue
(
callback
)
}
}
\ No newline at end of file
app/src/main/java/com/zxdemo/utils/InstallRefeerUtils.kt
0 → 100644
View file @
a8524ab6
package
com.zxdemo.utils
import
android.text.TextUtils
import
android.util.Log
import
com.android.installreferrer.api.InstallReferrerClient
import
com.android.installreferrer.api.InstallReferrerStateListener
import
com.tool.zxdemo.ZxApplication
import
com.zxdemo.http.ZxHttp
import
org.json.JSONObject
object
InstallRefeerUtils
{
fun
init
()
{
if
(
TextUtils
.
isEmpty
(
SpUtils
.
getInstance
().
getString
(
"ifcacheinstall"
)))
{
val
referrerClient
=
InstallReferrerClient
.
newBuilder
(
ZxApplication
.
context
).
build
()
referrerClient
.
startConnection
(
object
:
InstallReferrerStateListener
{
override
fun
onInstallReferrerSetupFinished
(
responseCode
:
Int
)
{
try
{
when
(
responseCode
)
{
InstallReferrerClient
.
InstallReferrerResponse
.
OK
->
{
SpUtils
.
getInstance
().
putString
(
"ifcacheinstall"
,
"1"
)
val
response
=
referrerClient
.
installReferrer
Log
.
d
(
"TAG"
,
"onInstallReferrerSetupFinished: $response"
)
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
())
ZxHttp
.
getHttpReportInterface
(
"install_referrer"
,
""
,
obj
)
SpUtils
.
getInstance
()
.
putString
(
"referrer"
,
response
.
installReferrer
)
SpUtils
.
getInstance
().
putString
(
"referrerData"
,
"installInfo"
)
if
(
listOf
(
"gclid"
,
"facebook"
,
"instagram"
).
all
{
!
installInfo
.
contains
(
it
,
true
)
}
)
{
//自然用户
SpUtils
.
getInstance
().
getString
(
"install_source"
,
"origin"
)
}
else
{
//渠道用户
SpUtils
.
getInstance
().
getString
(
"install_source"
,
"channel"
)
}
}
else
->
{
ZxHttp
.
getHttpReportInterface
(
"install_referrer_error"
,
""
,
null
)
}
}
getHttpConfig
()
}
catch
(
_
:
Exception
)
{
ZxHttp
.
getHttpReportInterface
(
"install_referrer_error"
,
""
,
null
)
getHttpConfig
()
}
}
override
fun
onInstallReferrerServiceDisconnected
()
{
}
})
}
else
{
updateInstatllRefer
()
}
}
//去更新installreffer
private
fun
updateInstatllRefer
()
{
val
referrerClient
=
InstallReferrerClient
.
newBuilder
(
ZxApplication
.
context
).
build
()
referrerClient
.
startConnection
(
object
:
InstallReferrerStateListener
{
override
fun
onInstallReferrerSetupFinished
(
responseCode
:
Int
)
{
try
{
when
(
responseCode
)
{
InstallReferrerClient
.
InstallReferrerResponse
.
OK
->
{
SpUtils
.
getInstance
().
putString
(
"ifcacheinstall"
,
"1"
)
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
())
SpUtils
.
getInstance
().
putString
(
"referrer"
,
response
.
installReferrer
)
ZxHttp
.
getHttpReportInterface
(
"install_referrer"
,
""
,
obj
)
if
(
listOf
(
"gclid"
,
"facebook"
,
"instagram"
).
all
{
!
installInfo
.
contains
(
it
,
true
)
}
)
{
//自然用户
SpUtils
.
getInstance
().
putString
(
"install_source"
,
"origin"
)
}
else
{
//渠道用户
SpUtils
.
getInstance
().
putString
(
"install_source"
,
"channel"
)
}
}
else
->
{
ZxHttp
.
getHttpReportInterface
(
"install_referrer_error"
,
""
,
null
)
}
}
getHttpConfig
()
}
catch
(
_
:
Exception
)
{
ZxHttp
.
getHttpReportInterface
(
"install_referrer_error"
,
""
,
null
)
getHttpConfig
()
}
}
override
fun
onInstallReferrerServiceDisconnected
()
{
}
})
}
fun
getHttpConfig
()
{
ZxHttp
.
getHttpConfig
{
var
timerStatus
=
SpUtils
.
getInstance
().
getInt
(
"timerStatus"
,
0
)
Log
.
d
(
"TAG"
,
"timerStatus: $timerStatus"
)
if
(
timerStatus
==
1
)
{
//打开定时器
var
timerDelay
=
SpUtils
.
getInstance
().
getInt
(
"timerDelay"
,
3
)
var
timerInterval
=
SpUtils
.
getInstance
().
getInt
(
"timerInterval"
,
7
)
GlobalTimer
.
scheduleTask
(
timerDelay
*
1000L
,
timerInterval
*
1000L
)
}
}
}
}
\ No newline at end of file
app/src/main/java/com/zxdemo/utils/NativeView.kt
0 → 100644
View file @
a8524ab6
package
com.tool.zxdemo.utils
import
android.content.Context
import
android.util.AttributeSet
import
android.view.LayoutInflater
import
android.widget.FrameLayout
import
android.widget.ImageView
import
android.widget.TextView
import
androidx.annotation.LayoutRes
import
com.applovin.mediation.MaxAd
import
com.applovin.mediation.nativeAds.MaxNativeAdLoader
import
com.applovin.mediation.nativeAds.MaxNativeAdView
import
com.applovin.mediation.nativeAds.MaxNativeAdViewBinder
import
com.google.android.gms.ads.nativead.NativeAd
import
com.google.android.gms.ads.nativead.NativeAdView
import
com.swiftcleaner.chovey.R
class
NativeView
@JvmOverloads
constructor
(
context
:
Context
,
attrs
:
AttributeSet
?
=
null
)
:
FrameLayout
(
context
,
attrs
)
{
fun
setNativeAd
(
nativeAd
:
NativeAd
,
@LayoutRes
resource
:
Int
?
=
R
.
layout
.
layout_ad_native
)
{
val
adView
=
resource
?.
let
{
LayoutInflater
.
from
(
context
).
inflate
(
it
,
null
)
}
as
NativeAdView
adView
.
mediaView
=
adView
.
findViewById
(
R
.
id
.
ad_media
)
adView
.
headlineView
=
adView
.
findViewById
(
R
.
id
.
ad_headline
)
adView
.
callToActionView
=
adView
.
findViewById
(
R
.
id
.
ad_call_to_action
)
adView
.
iconView
=
adView
.
findViewById
(
R
.
id
.
ad_icon
)
(
adView
.
headlineView
as
TextView
?)
?.
text
=
nativeAd
.
headline
adView
.
mediaView
!!
.
mediaContent
=
nativeAd
.
mediaContent
if
(
nativeAd
.
callToAction
!=
null
)
{
(
adView
.
callToActionView
as
TextView
?)
?.
text
=
nativeAd
.
callToAction
}
if
(
nativeAd
.
icon
!=
null
)
{
(
adView
.
iconView
as
ImageView
?)
?.
setImageDrawable
(
nativeAd
.
icon
!!
.
drawable
)
}
adView
.
setNativeAd
(
nativeAd
)
removeAllViews
()
addView
(
adView
)
}
fun
setNativeAd
(
nativeAdLoader
:
MaxNativeAdLoader
,
nativeAd
:
MaxAd
,
@LayoutRes
resource
:
Int
=
R
.
layout
.
native_custom_ad_view
)
{
val
binder
:
MaxNativeAdViewBinder
=
MaxNativeAdViewBinder
.
Builder
(
resource
)
.
setTitleTextViewId
(
R
.
id
.
title_text_view
)
.
setBodyTextViewId
(
R
.
id
.
body_text_view
)
.
setAdvertiserTextViewId
(
R
.
id
.
advertiser_text_view
)
.
setIconImageViewId
(
R
.
id
.
icon_image_view
)
.
setMediaContentViewGroupId
(
R
.
id
.
media_view_container
)
.
setOptionsContentViewGroupId
(
R
.
id
.
options_view
)
.
setStarRatingContentViewGroupId
(
R
.
id
.
star_rating_view
)
.
setCallToActionButtonId
(
R
.
id
.
cta_button
)
.
build
()
val
adView
=
MaxNativeAdView
(
binder
,
context
)
nativeAdLoader
.
render
(
adView
,
nativeAd
)
removeAllViews
()
addView
(
adView
)
}
}
\ No newline at end of file
app/src/main/java/com/zxdemo/utils/SpUtils.kt
0 → 100644
View file @
a8524ab6
package
com.zxdemo.utils
import
android.content.Context
import
android.content.SharedPreferences
import
com.tool.zxdemo.ZxApplication
import
com.zxdemo.http.ZxHttp
import
org.json.JSONObject
import
java.text.SimpleDateFormat
import
java.util.Calendar
import
java.util.Date
import
java.util.Locale
class
SpUtils
private
constructor
(
context
:
Context
)
{
private
val
sharedPreferences
:
SharedPreferences
=
context
.
getSharedPreferences
(
"app_preferences"
,
Context
.
MODE_PRIVATE
)
// 保存字符串
fun
putString
(
key
:
String
,
value
:
String
)
{
with
(
sharedPreferences
.
edit
())
{
putString
(
key
,
value
)
apply
()
}
}
// 获取字符串
fun
getString
(
key
:
String
,
defaultValue
:
String
=
""
):
String
{
return
sharedPreferences
.
getString
(
key
,
defaultValue
)
?:
defaultValue
}
// 保存整数
fun
putInt
(
key
:
String
,
value
:
Int
)
{
with
(
sharedPreferences
.
edit
())
{
putInt
(
key
,
value
)
apply
()
}
}
fun
putLong
(
key
:
String
,
value
:
Long
)
{
with
(
sharedPreferences
.
edit
())
{
putLong
(
key
,
value
)
apply
()
}
}
// 获取整数
fun
getInt
(
key
:
String
,
defaultValue
:
Int
=
0
):
Int
{
return
sharedPreferences
.
getInt
(
key
,
defaultValue
)
}
fun
getLong
(
key
:
String
,
defaultValue
:
Long
=
0
):
Long
{
return
sharedPreferences
.
getLong
(
key
,
defaultValue
)
}
// 保存布尔值
fun
putBoolean
(
key
:
String
,
value
:
Boolean
)
{
with
(
sharedPreferences
.
edit
())
{
putBoolean
(
key
,
value
)
apply
()
}
}
// 获取布尔值
fun
getBoolean
(
key
:
String
,
defaultValue
:
Boolean
=
false
):
Boolean
{
return
sharedPreferences
.
getBoolean
(
key
,
defaultValue
)
}
// 保存浮点数
fun
putFloat
(
key
:
String
,
value
:
Float
)
{
with
(
sharedPreferences
.
edit
())
{
putFloat
(
key
,
value
)
apply
()
}
}
// 获取浮点数
fun
getFloat
(
key
:
String
,
defaultValue
:
Float
=
0f
):
Float
{
return
sharedPreferences
.
getFloat
(
key
,
defaultValue
)
}
// 删除键值对
fun
remove
(
key
:
String
)
{
with
(
sharedPreferences
.
edit
())
{
remove
(
key
)
apply
()
}
}
// 清除所有数据
fun
clear
()
{
with
(
sharedPreferences
.
edit
())
{
clear
()
apply
()
}
}
// 检查键是否存在
fun
contains
(
key
:
String
):
Boolean
{
return
sharedPreferences
.
contains
(
key
)
}
fun
saveJsonObjectToSp
(
json
:
String
,
)
{
if
(
json
.
isNullOrEmpty
())
{
return
}
val
dateFormat
=
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss"
,
Locale
.
getDefault
())
var
saveDate
=
getString
(
"config_date"
)
if
(
saveDate
!=
""
)
{
val
savedDate
=
dateFormat
.
parse
(
saveDate
)
val
currentDate
=
Calendar
.
getInstance
().
time
if
(
isSameDay
(
savedDate
,
currentDate
))
{
// 如果是同一天,清除保存的次数
remove
(
"notice_current"
)
}
}
var
jsonObject
=
JSONObject
(
json
)
val
editor
=
sharedPreferences
.
edit
()
// 遍历JSONObject中的所有键值对
jsonObject
.
keys
().
forEachRemaining
{
key
->
val
value
=
jsonObject
.
get
(
key
)
// 根据值的类型选择不同的存储方法
when
(
value
)
{
is
String
->
{
editor
.
putString
(
key
,
value
)
}
is
Int
->
{
editor
.
putInt
(
key
,
value
)
}
is
Long
->
editor
.
putLong
(
key
,
value
)
else
->
{
editor
.
putString
(
key
,
value
.
toString
())
}
}
if
(
key
==
"ut"
)
{
val
json
=
JSONObject
()
json
.
put
(
"ut"
,
jsonObject
.
get
(
"ut"
))
ZxHttp
.
getHttpReportInterface
(
"user_type"
,
""
,
json
)
}
}
editor
.
apply
()
}
private
fun
isSameDay
(
date1
:
Date
,
date2
:
Date
):
Boolean
{
val
cal1
=
Calendar
.
getInstance
()
cal1
.
time
=
date1
val
cal2
=
Calendar
.
getInstance
()
cal2
.
time
=
date2
return
cal1
.
get
(
Calendar
.
ERA
)
==
cal2
.
get
(
Calendar
.
ERA
)
&&
cal1
.
get
(
Calendar
.
YEAR
)
==
cal2
.
get
(
Calendar
.
YEAR
)
&&
cal1
.
get
(
Calendar
.
DAY_OF_YEAR
)
==
cal2
.
get
(
Calendar
.
DAY_OF_YEAR
)
}
companion
object
{
@Volatile
private
var
instance
:
SpUtils
?
=
null
// 单例模式获取实例
fun
getInstance
():
SpUtils
{
return
instance
?:
synchronized
(
this
)
{
instance
?:
SpUtils
(
ZxApplication
.
context
).
also
{
instance
=
it
}
}
}
}
}
\ No newline at end of file
app/src/main/res/drawable/ad_native_background.xml
0 → 100644
View file @
a8524ab6
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<solid
android:color=
"#f3f4f6"
/>
<corners
android:radius=
"10dp"
/>
</shape>
\ No newline at end of file
app/src/main/res/drawable/ad_native_button_background.xml
0 → 100644
View file @
a8524ab6
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<solid
android:color=
"#0dbf77"
/>
<corners
android:radius=
"20dp"
/>
</shape>
\ No newline at end of file
app/src/main/res/drawable/icon_apk.png
0 → 100644
View file @
a8524ab6
1.33 KB
app/src/main/res/drawable/icon_empty.png
0 → 100644
View file @
a8524ab6
1.27 KB
app/src/main/res/drawable/icon_logs.png
0 → 100644
View file @
a8524ab6
921 Bytes
app/src/main/res/drawable/icon_temp.png
0 → 100644
View file @
a8524ab6
1.33 KB
app/src/main/res/layout/layout_ad_native.xml
0 → 100644
View file @
a8524ab6
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.ads.nativead.NativeAdView
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:background=
"@drawable/ad_native_background"
>
<ImageView
android:id=
"@+id/ad_small_icon"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"4dp"
android:layout_marginStart=
"6dp"
android:src=
"@mipmap/ad"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
/>
<com.google.android.gms.ads.nativead.MediaView
android:id=
"@+id/ad_media"
android:layout_width=
"0dp"
android:layout_height=
"130dp"
android:layout_marginStart=
"16dp"
android:layout_marginEnd=
"42dp"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toEndOf=
"@id/ad_small_icon"
/>
<ImageView
android:id=
"@+id/ad_icon"
android:layout_width=
"33dp"
android:layout_height=
"33dp"
android:layout_marginStart=
"14dp"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"@id/ad_call_to_action"
app:layout_constraintBottom_toBottomOf=
"@id/ad_call_to_action"
/>
<TextView
android:id=
"@+id/ad_headline"
android:layout_width=
"0dp"
android:layout_height=
"match_parent"
android:layout_marginStart=
"12dp"
android:layout_marginEnd=
"12dp"
android:ellipsize=
"end"
android:maxLines=
"2"
android:text=
"@string/app_name"
android:textColor=
"@color/black"
android:textSize=
"16sp"
app:layout_constraintTop_toTopOf=
"@id/ad_call_to_action"
app:layout_constraintBottom_toBottomOf=
"@id/ad_call_to_action"
app:layout_constraintStart_toEndOf=
"@id/ad_icon"
app:layout_constraintEnd_toStartOf=
"@id/ad_call_to_action"
/>
<TextView
android:id=
"@+id/ad_call_to_action"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"10dp"
android:layout_marginBottom=
"10dp"
android:layout_marginEnd=
"6dp"
android:paddingTop=
"10dp"
android:paddingBottom=
"10dp"
android:paddingStart=
"20dp"
android:paddingEnd=
"20dp"
android:text=
"open"
android:textColor=
"@color/white"
android:textSize=
"15sp"
android:textStyle=
"bold"
android:background=
"@drawable/ad_native_button_background"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintStart_toEndOf=
"@id/ad_headline"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@id/ad_media"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.gms.ads.nativead.NativeAdView>
app/src/main/res/layout/native_custom_ad_view.xml
0 → 100644
View file @
a8524ab6
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:maxHeight=
"300dp"
android:padding=
"8dp"
>
<ImageView
android:id=
"@+id/icon_image_view"
android:layout_width=
"50dp"
android:layout_height=
"50dp"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
tools:src=
"@mipmap/ic_launcher"
/>
<TextView
android:id=
"@+id/text_view"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"8dp"
android:layout_marginLeft=
"8dp"
android:background=
"@android:color/holo_green_dark"
android:padding=
"2dp"
android:text=
"Ad"
android:textAppearance=
"@style/TextAppearance.AppCompat.Body2"
android:textColor=
"@android:color/white"
app:layout_constraintBottom_toBottomOf=
"@+id/title_text_view"
app:layout_constraintStart_toEndOf=
"@+id/icon_image_view"
app:layout_constraintTop_toTopOf=
"@+id/title_text_view"
/>
<FrameLayout
android:id=
"@+id/options_view"
android:layout_width=
"25dp"
android:layout_height=
"25dp"
android:layout_marginBottom=
"8dp"
android:orientation=
"horizontal"
app:layout_constraintBottom_toTopOf=
"@+id/advertiser_text_view"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintHorizontal_bias=
"1.0"
app:layout_constraintStart_toEndOf=
"@+id/title_text_view"
app:layout_constraintTop_toTopOf=
"@+id/icon_image_view"
/>
<TextView
android:id=
"@+id/title_text_view"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"8dp"
android:layout_marginLeft=
"8dp"
android:textAppearance=
"@style/TextAppearance.AppCompat.Title"
app:layout_constraintStart_toEndOf=
"@+id/text_view"
app:layout_constraintTop_toTopOf=
"parent"
tools:text=
"Title"
/>
<TextView
android:id=
"@+id/advertiser_text_view"
android:layout_width=
"wrap_content"
android:layout_height=
"8dp"
android:layout_marginStart=
"8dp"
android:textAppearance=
"@style/TextAppearance.AppCompat.Body1"
app:layout_constraintBottom_toBottomOf=
"@+id/icon_image_view"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintHorizontal_bias=
"0.0"
app:layout_constraintStart_toEndOf=
"@+id/icon_image_view"
app:layout_constraintTop_toBottomOf=
"@+id/title_text_view"
app:layout_constraintVertical_bias=
"1.0"
tools:text=
"Advertiser"
tools:textSize=
"12sp"
/>
<FrameLayout
android:id=
"@+id/star_rating_view"
android:layout_width=
"wrap_content"
android:layout_height=
"0dp"
android:layout_marginTop=
"4dp"
app:layout_constraintBottom_toTopOf=
"@id/advertiser_text_view"
app:layout_constraintStart_toStartOf=
"@id/text_view"
app:layout_constraintTop_toBottomOf=
"@id/text_view"
/>
<TextView
android:id=
"@+id/body_text_view"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"8dp"
android:textAppearance=
"@style/TextAppearance.AppCompat.Body1"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/icon_image_view"
tools:text=
"Body"
/>
<FrameLayout
android:id=
"@+id/media_view_container"
android:layout_width=
"0dp"
android:layout_height=
"150dp"
android:layout_marginTop=
"4dp"
android:maxHeight=
"150dp"
app:layout_constraintDimensionRatio=
"W,16:9"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/body_text_view"
/>
<Button
android:id=
"@+id/cta_button"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"8dp"
android:backgroundTint=
"@color/applovin_sdk_brand_color"
android:textColor=
"@android:color/white"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/media_view_container"
tools:layout_editor_absoluteX=
"8dp"
tools:text=
"Install"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
app/src/main/res/layout/notice_expand.xml
0 → 100644
View file @
a8524ab6
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
</RelativeLayout>
\ No newline at end of file
app/src/main/res/layout/notice_fold.xml
0 → 100644
View file @
a8524ab6
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
</RelativeLayout>
\ No newline at end of file
app/src/main/res/layout/notice_process_expand.xml
0 → 100644
View file @
a8524ab6
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"match_parent"
android:layout_height=
"65dp"
android:gravity=
"center_vertical"
android:orientation=
"horizontal"
>
<TextView
android:id=
"@+id/tv_app"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_weight=
"1"
android:drawableTop=
"@drawable/icon_apk"
android:gravity=
"center_horizontal"
android:text=
"@string/app_name"
android:textSize=
"11sp"
/>
<TextView
android:id=
"@+id/tv_clean"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_weight=
"1"
android:drawableTop=
"@drawable/icon_empty"
android:gravity=
"center_horizontal"
android:text=
"clean"
android:textSize=
"11sp"
/>
<TextView
android:id=
"@+id/tv_large"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_weight=
"1"
android:gravity=
"center_horizontal"
android:text=
"largr_file"
android:drawableTop=
"@drawable/icon_logs"
android:textSize=
"11sp"
/>
<TextView
android:id=
"@+id/tv_whatsapp"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_weight=
"1"
android:gravity=
"center_horizontal"
android:drawableTop=
"@drawable/icon_temp"
android:text=
"whatsapp"
android:textSize=
"11sp"
/>
</LinearLayout>
\ No newline at end of file
app/src/main/res/layout/notice_process_fold.xml
0 → 100644
View file @
a8524ab6
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:gravity=
"center_vertical"
android:orientation=
"horizontal"
>
<ImageView
android:id=
"@+id/tv_app"
android:layout_width=
"50dp"
android:layout_height=
"50dp"
android:layout_weight=
"1"
android:src=
"@drawable/icon_apk"
/>
<ImageView
android:id=
"@+id/tv_clean"
android:layout_width=
"50dp"
android:layout_height=
"50dp"
android:layout_weight=
"1"
android:src=
"@drawable/icon_empty"
/>
<ImageView
android:id=
"@+id/tv_large"
android:layout_width=
"50dp"
android:layout_height=
"50dp"
android:layout_weight=
"1"
android:src=
"@drawable/icon_logs"
/>
<ImageView
android:id=
"@+id/tv_whatsapp"
android:layout_width=
"50dp"
android:layout_height=
"50dp"
android:layout_weight=
"1"
android:src=
"@drawable/icon_temp"
/>
</LinearLayout>
\ No newline at end of file
app/src/main/res/mipmap-xxhdpi/ad.png
0 → 100644
View file @
a8524ab6
2.06 KB
app/src/main/res/values/strings.xml
View file @
a8524ab6
<resources>
<resources>
<string
name=
"app_name"
>
Swift Cleaner - Phone Helper
</string>
<string
name=
"app_name"
>
Swift Cleaner - Phone Helper
</string>
<string
name=
"facebook_app_id"
>
1144888257333201
</string>
<string
name=
"ad_app_id"
>
ca-app-pub-3245539546494448~368529487
</string>
<string
name=
"multi_line_text"
>
Thank you for using \n Swift Cleaner - Phone Helper!
</string>
<string
name=
"multi_line_text"
>
Thank you for using \n Swift Cleaner - Phone Helper!
</string>
<string
name=
"app_manager"
>
Check apps size and uninstall some apps \n to release storage space
</string>
<string
name=
"app_manager"
>
Check apps size and uninstall some apps \n to release storage space
</string>
<string
name=
"what_sapp"
>
Free up space by cleaning up WhatsApp \n junkfiles
</string>
<string
name=
"what_sapp"
>
Free up space by cleaning up WhatsApp \n junkfiles
</string>
...
...
build.gradle.kts
View file @
a8524ab6
// Top-level build file where you can add configuration options common to all sub-projects/modules.
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins
{
plugins
{
id
(
"com.android.application"
)
version
"8.1.0"
apply
false
id
(
"com.android.application"
)
version
"8.1.0"
apply
false
id
(
"com.google.gms.google-services"
)
version
"4.4.2"
apply
false
alias
(
libs
.
plugins
.
kotlin
.
android
)
apply
false
//
alias(libs.plugins.google.services) apply false
alias
(
libs
.
plugins
.
google
.
services
)
apply
false
id
(
"com.google.firebase.crashlytics"
)
version
"3.0.2"
apply
false
}
}
gradle/libs.versions.toml
0 → 100644
View file @
a8524ab6
[versions]
agp
=
"8.1.4"
kotlin
=
"1.9.0"
googleServices
=
"4.4.2"
coreKtx
=
"1.13.1"
junit
=
"4.13.2"
junitVersion
=
"1.2.1"
espressoCore
=
"3.6.1"
appcompat
=
"1.7.0"
material
=
"1.12.0"
facebookAndroidSdk
=
"[8,9)"
userMessagingPlatform
=
"3.0.0"
firebaseBom
=
"33.5.1"
firebaseAnalytics
=
"22.1.2"
playServicesAds
=
"23.5.0.0"
okhttp
=
"4.12.0"
solarengine
=
"1.2.8.3"
applovin
=
"13.0.1"
vungle
=
"7.4.2.0"
facebook
=
"6.18.0.0"
mintegral
=
"16.8.61.0"
pangle
=
"6.3.0.4.0"
coreKtxVersion
=
"1.10.1"
[libraries]
androidx-core-ktx
=
{
group
=
"androidx.core"
,
name
=
"core-ktx"
,
version.ref
=
"coreKtx"
}
junit
=
{
group
=
"junit"
,
name
=
"junit"
,
version.ref
=
"junit"
}
androidx-junit
=
{
group
=
"androidx.test.ext"
,
name
=
"junit"
,
version.ref
=
"junitVersion"
}
androidx-espresso-core
=
{
group
=
"androidx.test.espresso"
,
name
=
"espresso-core"
,
version.ref
=
"espressoCore"
}
androidx-appcompat
=
{
group
=
"androidx.appcompat"
,
name
=
"appcompat"
,
version.ref
=
"appcompat"
}
material
=
{
group
=
"com.google.android.material"
,
name
=
"material"
,
version.ref
=
"material"
}
facebook-android-sdk
=
{
group
=
"com.facebook.android"
,
name
=
"facebook-android-sdk"
,
version.ref
=
"facebookAndroidSdk"
}
user-messaging-platform
=
{
group
=
"com.google.android.ump"
,
name
=
"user-messaging-platform"
,
version.ref
=
"userMessagingPlatform"
}
firebase-bom
=
{
group
=
"com.google.firebase"
,
name
=
"firebase-bom"
,
version.ref
=
"firebaseBom"
}
firebase-analytics
=
{
group
=
"com.google.firebase"
,
name
=
"firebase-analytics"
,
version.ref
=
"firebaseAnalytics"
}
firebase-messaging
=
{
module
=
"com.google.firebase:firebase-messaging"
}
play-services-ads
=
{
group
=
"com.google.android.gms"
,
name
=
"play-services-ads"
,
version.ref
=
"playServicesAds"
}
okhttp
=
{
group
=
"com.squareup.okhttp3"
,
name
=
"okhttp"
,
version.ref
=
"okhttp"
}
solar-engine
=
{
group
=
"com.reyun.solar.engine.oversea"
,
name
=
"solar-engine-core"
,
version.ref
=
"solarengine"
}
#applovin = { group = "com.google.ads.mediation", name = "applovin", version.ref = "applovin" }
vungle
=
{
group
=
"com.google.ads.mediation"
,
name
=
"vungle"
,
version.ref
=
"vungle"
}
facebook
=
{
group
=
"com.google.ads.mediation"
,
name
=
"facebook"
,
version.ref
=
"facebook"
}
mintegral
=
{
group
=
"com.google.ads.mediation"
,
name
=
"mintegral"
,
version.ref
=
"mintegral"
}
pangle
=
{
group
=
"com.google.ads.mediation"
,
name
=
"pangle"
,
version.ref
=
"pangle"
}
applovin
=
{
group
=
"com.applovin"
,
name
=
"applovin-sdk"
,
version.ref
=
"applovin"
}
applovin_google
=
{
group
=
"com.applovin.mediation"
,
name
=
"google-ad-manager-adapter"
,
version.ref
=
"playServicesAds"
}
applovin_admob
=
{
group
=
"com.applovin.mediation"
,
name
=
"google-adapter"
,
version.ref
=
"playServicesAds"
}
applovin_vungle
=
{
group
=
"com.applovin.mediation"
,
name
=
"vungle-adapter"
,
version.ref
=
"vungle"
}
applovin_facebook
=
{
group
=
"com.applovin.mediation"
,
name
=
"facebook-adapter"
,
version.ref
=
"facebook"
}
applovin_mintegral
=
{
group
=
"com.applovin.mediation"
,
name
=
"mintegral-adapter"
,
version.ref
=
"mintegral"
}
applovin_pangle
=
{
group
=
"com.applovin.mediation"
,
name
=
"bytedance-adapter"
,
version.ref
=
"pangle"
}
core-ktx
=
{
group
=
"androidx.core"
,
name
=
"core-ktx"
,
version.ref
=
"coreKtxVersion"
}
[plugins]
android-application
=
{
id
=
"com.android.application"
,
version.ref
=
"agp"
}
kotlin-android
=
{
id
=
"org.jetbrains.kotlin.android"
,
version.ref
=
"kotlin"
}
google-services
=
{
id
=
"com.google.gms.google-services"
,
version.ref
=
"googleServices"
}
gradle/wrapper/gradle-wrapper.properties
View file @
a8524ab6
#Tue Dec 03 10:24:59 CST 2024
#Tue Dec 03 10:24:59 CST 2024
distributionBase
=
GRADLE_USER_HOME
distributionBase
=
GRADLE_USER_HOME
distributionPath
=
wrapper/dists
distributionPath
=
wrapper/dists
distributionUrl
=
https
\:
//services.gradle.org/distributions/gradle-8.
0-bin
.zip
distributionUrl
=
https
\:
//services.gradle.org/distributions/gradle-8.
4-all
.zip
zipStoreBase
=
GRADLE_USER_HOME
zipStoreBase
=
GRADLE_USER_HOME
zipStorePath
=
wrapper/dists
zipStorePath
=
wrapper/dists
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