Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Sign in / Register
Toggle navigation
F
FileManager
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
yanglin
FileManager
Commits
e8f694cc
Commit
e8f694cc
authored
Apr 18, 2024
by
许译文
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add ad,notification
parent
fa4e93cf
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
34 changed files
with
2100 additions
and
57 deletions
+2100
-57
misc.xml
.idea/misc.xml
+1
-2
gradle.xml
MyDemo3/.idea/gradle.xml
+3
-1
build.gradle
MyDemo3/app/build.gradle
+7
-3
MyApplication.kt
...p/src/main/java/com/xm/test/myfilemaster/MyApplication.kt
+37
-44
NetCommon.kt
...3/app/src/main/java/com/xm/test/myfilemaster/NetCommon.kt
+92
-0
FileManagerActivity.kt
.../com/xm/test/myfilemaster/activity/FileManagerActivity.kt
+1
-0
AESHelper.kt
...pp/src/main/java/com/xm/test/myfilemaster/ad/AESHelper.kt
+59
-0
AdUtils.kt
.../app/src/main/java/com/xm/test/myfilemaster/ad/AdUtils.kt
+53
-0
ComUtils.kt
...app/src/main/java/com/xm/test/myfilemaster/ad/ComUtils.kt
+212
-0
ConfigHelper.kt
...src/main/java/com/xm/test/myfilemaster/ad/ConfigHelper.kt
+26
-0
ConfigInfo.kt
...p/src/main/java/com/xm/test/myfilemaster/ad/ConfigInfo.kt
+14
-0
DataStoreEx.kt
.../src/main/java/com/xm/test/myfilemaster/ad/DataStoreEx.kt
+74
-0
EventHelper.kt
.../src/main/java/com/xm/test/myfilemaster/ad/EventHelper.kt
+111
-0
GravitySensorManager.kt
.../java/com/xm/test/myfilemaster/ad/GravitySensorManager.kt
+104
-0
KokoReportHelper.kt
...main/java/com/xm/test/myfilemaster/ad/KokoReportHelper.kt
+213
-0
MaxAdUtils.kt
...p/src/main/java/com/xm/test/myfilemaster/ad/MaxAdUtils.kt
+460
-0
MyReportViewLisenter.kt
.../java/com/xm/test/myfilemaster/ad/MyReportViewLisenter.kt
+19
-0
PushManager.kt
.../src/main/java/com/xm/test/myfilemaster/ad/PushManager.kt
+69
-0
UserChancelEx.kt
...rc/main/java/com/xm/test/myfilemaster/ad/UserChancelEx.kt
+46
-0
AdUnitCfg.kt
...c/main/java/com/xm/test/myfilemaster/ad/bean/AdUnitCfg.kt
+14
-0
AdsCfg.kt
.../src/main/java/com/xm/test/myfilemaster/ad/bean/AdsCfg.kt
+28
-0
ConfigureData.kt
...in/java/com/xm/test/myfilemaster/ad/bean/ConfigureData.kt
+13
-0
GlobalConfig.kt
...ain/java/com/xm/test/myfilemaster/ad/bean/GlobalConfig.kt
+15
-0
PushCfg.kt
...src/main/java/com/xm/test/myfilemaster/ad/bean/PushCfg.kt
+42
-0
PushManagement.kt
...n/java/com/xm/test/myfilemaster/ad/bean/PushManagement.kt
+16
-0
ZxhyConfigure.kt
...in/java/com/xm/test/myfilemaster/ad/bean/ZxhyConfigure.kt
+7
-0
BaseActivity.kt
...c/main/java/com/xm/test/myfilemaster/base/BaseActivity.kt
+22
-2
ActionBroadcast.kt
.../com/xm/test/myfilemaster/notification/ActionBroadcast.kt
+126
-0
NotificationEx.kt
...a/com/xm/test/myfilemaster/notification/NotificationEx.kt
+19
-0
NotificationHelper.kt
...m/xm/test/myfilemaster/notification/NotificationHelper.kt
+191
-0
PermissionUtil.kt
...main/java/com/xm/test/myfilemaster/util/PermissionUtil.kt
+2
-1
result_layout.xml
MyDemo3/app/src/main/res/layout/result_layout.xml
+1
-1
libs.versions.toml
MyDemo3/gradle/libs.versions.toml
+2
-1
gradle-wrapper.properties
MyDemo3/gradle/wrapper/gradle-wrapper.properties
+1
-2
No files found.
.idea/misc.xml
View file @
e8f694cc
<?xml version="1.0" encoding="UTF-8"?>
<project
version=
"4"
>
<component
name=
"ProjectRootManager"
>
<component
name=
"ProjectRootManager"
version=
"2"
languageLevel=
"JDK_19"
project-jdk-name=
"Android API 33, extension level 3 Platform"
project-jdk-type=
"Android SDK"
>
<output
url=
"file://$PROJECT_DIR$/out"
/>
</component>
</project>
\ No newline at end of file
MyDemo3/.idea/gradle.xml
View file @
e8f694cc
...
...
@@ -4,8 +4,10 @@
<component
name=
"GradleSettings"
>
<option
name=
"linkedExternalProjectsSettings"
>
<GradleProjectSettings>
<option
name=
"testRunner"
value=
"GRADLE"
/>
<option
name=
"distributionType"
value=
"DEFAULT_WRAPPED"
/>
<option
name=
"externalProjectPath"
value=
"$PROJECT_DIR$"
/>
<option
name=
"gradleJvm"
value=
"
#GRADLE_LOCAL_JAVA_HOME
"
/>
<option
name=
"gradleJvm"
value=
"
jbr-17
"
/>
<option
name=
"modules"
>
<set>
<option
value=
"$PROJECT_DIR$"
/>
...
...
MyDemo3/app/build.gradle
View file @
e8f694cc
...
...
@@ -64,6 +64,7 @@ dependencies {
implementation
libs
.
androidx
.
lifecycle
.
livedata
.
ktx
implementation
libs
.
androidx
.
lifecycle
.
viewmodel
.
ktx
implementation
libs
.
androidx
.
fragment
.
ktx
implementation
libs
.
installreferrer
testImplementation
libs
.
junit
androidTestImplementation
libs
.
androidx
.
junit
androidTestImplementation
libs
.
androidx
.
espresso
.
core
...
...
@@ -88,15 +89,18 @@ dependencies {
implementation
'com.google.android.ump:user-messaging-platform:2.1.0'
implementation
"androidx.lifecycle:lifecycle-process:2.
2.0
"
implementation
"androidx.lifecycle:lifecycle-process:2.
6.2
"
implementation
'com.google.code.gson:gson:2.
8.8
'
implementation
'com.google.code.gson:gson:2.
10.1
'
implementation
'com.squareup.okhttp3:okhttp:3.10.0'
implementation
'com.squareup.okhttp3:okhttp:4.10.0'
implementation
(
"com.squareup.okhttp3:logging-interceptor:4.10.0"
)
// compile(name:'trustlook_cleanjunk_sdk_release_3.0.4.20240322',ext:'aar')
implementation
files
(
'libs/trustlook_cleanjunk_sdk_release_3.0.4.20240322.aar'
)
implementation
files
(
'libs/cloudscan_sdk_5.0.5.20240306.aar'
)
implementation
(
"com.github.bumptech.glide:glide:4.15.1"
)
implementation
(
"com.blankj:utilcodex:1.31.1"
)
implementation
(
"androidx.datastore:datastore-preferences:1.0.0"
)
}
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/MyApplication.kt
View file @
e8f694cc
package
com.xm.test.myfilemaster
import
android.annotation.SuppressLint
import
android.app.Application
import
android.content.Context
import
android.content.Intent
import
android.content.IntentFilter
import
android.content.SharedPreferences
import
android.util.Log
import
androidx.lifecycle.Lifecycle
...
...
@@ -12,26 +15,35 @@ import com.applovin.mediation.MaxAd
import
com.applovin.mediation.MaxAdListener
import
com.applovin.mediation.MaxError
import
com.applovin.mediation.ads.MaxAppOpenAd
import
com.applovin.sdk.AppLovinMediationProvider
import
com.applovin.sdk.AppLovinSdk
import
com.cloud.cleanjunksdk.task.CheckSdkCallback
import
com.cloud.cleanjunksdk.task.Clean
import
com.cloud.cleanjunksdk.task.CleanSDK
import
com.cloud.cleanjunksdk.tools.Region
import
com.trustlook.sdk.cloudscan.CloudScanClient
import
com.xm.test.myfilemaster.ad.GravitySensorManager
import
com.xm.test.myfilemaster.notification.ActionBroadcast
import
com.xm.test.myfilemaster.util.UrlManager
class
MyApplication
:
Application
()
{
private
lateinit
var
appOpenManager
:
ExampleAppOpenManager
private
lateinit
var
gravitySensorManager
:
GravitySensorManager
companion
object
{
var
mCleanSdk
:
Clean
?
=
null
@SuppressLint
(
"StaticFieldLeak"
)
var
mCloudScan
:
CloudScanClient
?
=
null
var
mSp
:
SharedPreferences
?
=
null
@SuppressLint
(
"StaticFieldLeak"
)
@JvmStatic
lateinit
var
fContext
:
Context
}
override
fun
onCreate
()
{
super
.
onCreate
()
fContext
=
this
// AppLovinSdk.getInstance( this ).initializeSdk({ configuration: AppLovinSdkConfiguration ->
// {
// appOpenManager = ExampleAppOpenManager(applicationContext)
...
...
@@ -55,50 +67,31 @@ class MyApplication : Application() {
.
setSocketTimeout
(
30000
)
.
build
()
AppLovinSdk
.
getInstance
(
this
).
initializeSdk
{
appOpenManager
=
ExampleAppOpenManager
(
applicationContext
)
}
}
class
ExampleAppOpenManager
(
applicationContext
:
Context
?)
:
LifecycleObserver
,
MaxAdListener
{
private
lateinit
var
appOpenAd
:
MaxAppOpenAd
private
lateinit
var
context
:
Context
init
{
ProcessLifecycleOwner
.
get
().
lifecycle
.
addObserver
(
this
)
context
=
applicationContext
!!
appOpenAd
=
MaxAppOpenAd
(
UrlManager
.
AD_UNIT_ID
,
applicationContext
)
appOpenAd
.
setListener
(
this
)
appOpenAd
.
loadAd
()
}
private
fun
showAdIfReady
()
{
if
(
appOpenAd
==
null
||
!
AppLovinSdk
.
getInstance
(
context
).
isInitialized
)
return
if
(
appOpenAd
.
isReady
)
{
appOpenAd
.
showAd
(
UrlManager
.
TEST_PLACEMENT_HERE
)
}
else
{
appOpenAd
.
loadAd
()
}
}
@OnLifecycleEvent
(
Lifecycle
.
Event
.
ON_START
)
fun
onStart
()
{
showAdIfReady
()
}
override
fun
onAdLoaded
(
ad
:
MaxAd
)
{}
override
fun
onAdLoadFailed
(
adUnitId
:
String
,
error
:
MaxError
)
{}
override
fun
onAdDisplayed
(
ad
:
MaxAd
)
{}
override
fun
onAdClicked
(
ad
:
MaxAd
)
{}
override
fun
onAdHidden
(
ad
:
MaxAd
)
{
appOpenAd
.
loadAd
()
}
AppLovinSdk
.
getInstance
(
this
).
mediationProvider
=
AppLovinMediationProvider
.
MAX
initBroadcast
()
}
override
fun
onAdDisplayFailed
(
ad
:
MaxAd
,
error
:
MaxError
)
{
appOpenAd
.
loadAd
()
}
private
fun
initBroadcast
(){
gravitySensorManager
=
GravitySensorManager
(
this
)
gravitySensorManager
.
registerListener
()
val
filter
=
IntentFilter
()
filter
.
addAction
(
Intent
.
ACTION_SCREEN_OFF
)
filter
.
addAction
(
Intent
.
ACTION_SCREEN_ON
)
filter
.
addAction
(
Intent
.
ACTION_PACKAGE_ADDED
)
filter
.
addAction
(
Intent
.
ACTION_PACKAGE_REMOVED
)
filter
.
addAction
(
Intent
.
ACTION_USER_PRESENT
)
filter
.
addAction
(
Intent
.
ACTION_POWER_CONNECTED
)
filter
.
addAction
(
Intent
.
ACTION_POWER_DISCONNECTED
)
filter
.
addAction
(
Intent
.
ACTION_BATTERY_CHANGED
)
filter
.
addAction
(
Intent
.
ACTION_MEDIA_MOUNTED
)
filter
.
addAction
(
Intent
.
ACTION_MEDIA_REMOVED
)
filter
.
addAction
(
Intent
.
ACTION_MEDIA_UNMOUNTED
)
filter
.
addAction
(
Intent
.
ACTION_MEDIA_BAD_REMOVAL
)
filter
.
addAction
(
Intent
.
ACTION_DEVICE_STORAGE_LOW
)
filter
.
addAction
(
Intent
.
ACTION_DEVICE_STORAGE_OK
)
filter
.
addDataScheme
(
"package"
)
registerReceiver
(
ActionBroadcast
(),
filter
)
}
}
\ No newline at end of file
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/NetCommon.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster
import
android.os.Build
import
android.util.Log
import
com.blankj.utilcode.util.AppUtils
import
com.blankj.utilcode.util.DeviceUtils
import
com.blankj.utilcode.util.NetworkUtils
import
com.blankj.utilcode.util.ScreenUtils
import
com.xm.test.myfilemaster.ad.AESHelper
import
com.xm.test.myfilemaster.ad.ConfigHelper
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.delay
import
kotlinx.coroutines.launch
import
okhttp3.Call
import
okhttp3.Callback
import
okhttp3.MediaType.Companion.toMediaTypeOrNull
import
okhttp3.OkHttpClient
import
okhttp3.Request
import
okhttp3.RequestBody.Companion.toRequestBody
import
okhttp3.Response
import
org.json.JSONObject
import
java.io.IOException
fun
netSendEvent
(
key
:
String
,
value
:
String
?
=
null
,
ext
:
JSONObject
?
=
null
)
{
val
pkg
=
ConfigHelper
.
packageName
val
d1
=
JSONObject
()
.
put
(
"action"
,
key
)
.
put
(
"value"
,
value
)
.
put
(
"ext"
,
ext
)
val
d2
=
JSONObject
()
.
put
(
"${pkg}_1"
,
"${ScreenUtils.getScreenHeight()}"
)
.
put
(
"${pkg}_2"
,
"${ScreenUtils.getScreenWidth()}"
)
.
put
(
"${pkg}_3"
,
DeviceUtils
.
getModel
())
.
put
(
"${pkg}_4"
,
Build
.
MANUFACTURER
)
.
put
(
"${pkg}_5"
,
Build
.
VERSION
.
SDK_INT
)
.
put
(
"${pkg}_6"
,
"${NetworkUtils.getNetworkType()}"
)
.
put
(
"${pkg}_8"
,
AppUtils
.
getAppVersionName
())
.
put
(
"${pkg}_9"
,
DeviceUtils
.
getAndroidID
())
.
put
(
"${pkg}_10"
,
ConfigHelper
.
gid
)
.
put
(
"${pkg}_11"
,
System
.
getProperty
(
"http.agent"
))
.
put
(
"${pkg}_13"
,
"android"
)
.
put
(
"${pkg}_14"
,
"${AppUtils.getAppVersionCode()}"
)
.
put
(
"${pkg}_15"
,
"google"
)
// .put("${pkg}_24",BuildConfig.BUILD_TYPE)
val
data
=
JSONObject
()
.
put
(
"data"
,
d1
)
.
put
(
"bp"
,
d2
)
.
toString
()
val
body
=
AESHelper
.
encrypt
(
data
).
toRequestBody
(
"application/json;charset=utf-8"
.
toMediaTypeOrNull
())
val
client
=
OkHttpClient
.
Builder
().
apply
{
// if (BuildConfig.DEBUG) {
// addInterceptor(HttpLoggingInterceptor().apply {
// level = HttpLoggingInterceptor.Level.BODY
// })
// }
}.
build
()
val
request
=
Request
.
Builder
()
.
url
(
eventUrl
)
.
post
(
body
)
.
build
()
CoroutineScope
(
Dispatchers
.
IO
).
launch
{
delay
(
1000
)
client
.
newCall
(
request
=
request
).
enqueue
(
object
:
Callback
{
override
fun
onFailure
(
call
:
Call
,
e
:
IOException
)
{
Log
.
d
(
"glc"
,
"onFailure:${e.message}"
)
}
override
fun
onResponse
(
call
:
Call
,
response
:
Response
)
{
Log
.
d
(
"glc"
,
"net success"
)
}
})
}
}
val
eventUrl
by
lazy
{
val
pkg
=
ConfigHelper
.
packageName
val
url
=
StringBuilder
(
"${ConfigHelper.eventUrl}/${pkg.filter { it.isLowerCase() }.substring(4, 9)}sp"
)
url
.
append
(
"?pkg=$pkg"
)
url
.
toString
()
}
\ No newline at end of file
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/activity/FileManagerActivity.kt
View file @
e8f694cc
...
...
@@ -63,6 +63,7 @@ class FileManagerActivity : BaseActivity() {
mFileBeanList
.
addAll
(
FileUtil
.
getFileType
(
FileUtil
.
WORD_MIME_TYPE
,
this
))
mFileBeanList
.
addAll
(
FileUtil
.
getFileType
(
FileUtil
.
EXCEL_MIME_TYPE
,
this
))
mFileBeanList
.
addAll
(
FileUtil
.
getFileType
(
FileUtil
.
PPT_MIME_TYPE
,
this
))
mFileBeanList
.
addAll
(
FileUtil
.
getFileType
(
FileUtil
.
PDF_MIME_TYPE
,
this
))
}
else
{
mFileBeanList
=
when
(
mFileType
)
{
"apk"
->
{
...
...
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/ad/AESHelper.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.ad
import
android.util.Base64
import
java.security.SecureRandom
import
javax.crypto.Cipher
import
javax.crypto.spec.GCMParameterSpec
import
javax.crypto.spec.SecretKeySpec
object
AESHelper
{
private
const
val
aesKey
=
"ccc7okanmfth88nb"
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
)
assert
(
encryptData
.
size
==
contentBytes
.
size
+
16
)
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
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/ad/AdUtils.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.ad
import
android.text.TextUtils
import
com.xm.test.myfilemaster.MyApplicaiton
object
AdUtils
{
fun
isShowAd
(
slot
:
String
):
Boolean
{
val
adEntity
=
ComUtils
.
getAdPositionData
(
slot
)
if
(!
PushManager
.
newUserPush
(
adEntity
.
new_user_avoid_time
))
{
return
false
}
if
(!
UserChancelEx
.
getUserChancelSwitch
(
adEntity
.
is_show
))
{
return
false
}
if
(
TextUtils
.
equals
(
adEntity
.
type
,
"interstitial"
))
{
val
isOrganic
=
UserChancelEx
.
isOrganicUser
()
if
(
isOrganic
)
{
if
(!
canNextTime
(
"interstitial"
,
ComUtils
.
getComConfig
().
nature_insert_interval
))
{
return
false
}
}
else
{
if
(!
canNextTime
(
"interstitial"
,
ComUtils
.
getComConfig
().
buy_insert_interval
))
{
return
false
}
}
}
if
(!
canNextTime
(
slot
,
adEntity
.
show_interval
))
{
return
false
}
val
adNum
=
MyApplicaiton
.
fContext
.
queryDataStoreBlock
(
getIntString
(
slot
+
"_ad_show_num"
)
,
0
)
if
(
adNum
>=
adEntity
.
show_limit
)
{
return
false
}
return
true
}
/**
* 间隔
* @param interval 单位分钟
*/
private
fun
canNextTime
(
key
:
String
,
interval
:
Int
):
Boolean
{
val
lastPushTime
=
MyApplicaiton
.
fContext
.
queryDataStoreBlock
(
getLongKey
(
key
),
0
)
return
(
System
.
currentTimeMillis
()
-
lastPushTime
)
/
1000
>
interval
}
}
\ No newline at end of file
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/ad/ComUtils.kt
0 → 100644
View file @
e8f694cc
This diff is collapsed.
Click to expand it.
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/ad/ConfigHelper.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.ad
object
ConfigHelper
{
var
gid
=
""
// 以上默认即可,以下需要手动配置
// 域名
const
val
eventUrl
=
"https://rp.expert3326.xyz"
const
val
apiUrl
=
"https://api.expert3326.xyz"
// 正式包名
const
val
packageName
=
"com.xm.test.myfilemaster"
// // 继承自 BaseSplashActivity 的类
// val splashActivity = SplashActivity::class.java
//
// val noLoadingActivities = listOf(
// "full", // 过滤全屏广告
// "adActivity",
// splashActivity.simpleName
// // 返回前台时不跳转启动页的 activity
// )
}
\ No newline at end of file
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/ad/ConfigInfo.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.ad
fun
loadSatisfyLimit
():
Boolean
{
return
true
}
fun
showSatisfyLimit
():
Boolean
{
return
true
}
fun
recordShowCount
(){
}
\ No newline at end of file
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/ad/DataStoreEx.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.ad
import
android.content.Context
import
androidx.datastore.core.DataStore
import
androidx.datastore.preferences.core.Preferences
import
androidx.datastore.preferences.core.edit
import
androidx.datastore.preferences.core.intPreferencesKey
import
androidx.datastore.preferences.core.longPreferencesKey
import
androidx.datastore.preferences.core.stringPreferencesKey
import
androidx.datastore.preferences.preferencesDataStore
import
kotlinx.coroutines.flow.first
import
kotlinx.coroutines.flow.map
import
kotlinx.coroutines.runBlocking
val
Context
.
dataStore
:
DataStore
<
Preferences
>
by
preferencesDataStore
(
name
=
"settings"
)
val
INSTALL_INFO
=
stringPreferencesKey
(
"install_info_source"
)
//第一次启动时间
val
FIRST_LAUNCH_TIME_KEY
=
longPreferencesKey
(
"install_info"
)
//上次与推送通知时间
val
ALL_LAST_PUSH_TIME
=
longPreferencesKey
(
"all_last_push_time"
)
fun
getStringKey
(
string
:
String
):
Preferences
.
Key
<
String
>
{
return
stringPreferencesKey
(
string
)
}
fun
getLongKey
(
string
:
String
):
Preferences
.
Key
<
Long
>
{
return
longPreferencesKey
(
string
)
}
fun
createByActionId
(
actionId
:
Int
):
Preferences
.
Key
<
Long
>
{
return
longPreferencesKey
(
"actionId_$actionId"
)
}
fun
getLongString
(
string
:
String
):
Preferences
.
Key
<
Long
>
{
return
longPreferencesKey
(
string
)
}
fun
getIntString
(
string
:
String
):
Preferences
.
Key
<
Int
>
{
return
intPreferencesKey
(
string
)
}
suspend
fun
<
T
>
Context
.
saveDataStore
(
key
:
Preferences
.
Key
<
T
>,
any
:
T
)
{
dataStore
.
edit
{
it
[
key
]
=
any
}
}
fun
<
T
>
Context
.
saveDataStoreBlock
(
key
:
Preferences
.
Key
<
T
>,
any
:
T
)
{
runBlocking
{
dataStore
.
edit
{
it
[
key
]
=
any
}
}
}
suspend
fun
<
T
>
Context
.
queryDataStore
(
key
:
Preferences
.
Key
<
T
>,
action
:
suspend
(
any
:
T
?)
->
Unit
)
{
val
flow
=
dataStore
.
data
.
map
{
it
[
key
]
}
action
.
invoke
(
flow
.
first
())
}
/**
* 同步方式查询
*/
fun
<
T
>
Context
.
queryDataStoreBlock
(
key
:
Preferences
.
Key
<
T
>,
defValue
:
T
):
T
{
var
value
=
defValue
runBlocking
{
val
flow
=
dataStore
.
data
.
map
{
preferences
->
preferences
[
key
]
?:
defValue
}
value
=
flow
.
first
()
}
return
value
}
\ No newline at end of file
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/ad/EventHelper.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.ad
import
android.os.Build
import
android.util.Log
import
com.blankj.utilcode.util.AppUtils
import
com.blankj.utilcode.util.DeviceUtils
import
com.blankj.utilcode.util.NetworkUtils
import
com.blankj.utilcode.util.SPUtils
import
com.blankj.utilcode.util.ScreenUtils
import
com.xm.test.myfilemaster.MyApplication
import
com.xm.test.myfilemaster.ad.KokoReportHelper.isCharging
import
com.xm.test.myfilemaster.BuildConfig
import
okhttp3.Call
import
okhttp3.Callback
import
okhttp3.MediaType.Companion.toMediaTypeOrNull
import
okhttp3.OkHttpClient
import
okhttp3.Request
import
okhttp3.RequestBody.Companion.toRequestBody
import
okhttp3.Response
import
okhttp3.logging.HttpLoggingInterceptor
import
org.json.JSONObject
import
java.io.IOException
object
EventHelper
{
private
val
url
by
lazy
{
val
pkg
=
ConfigHelper
.
packageName
val
url
=
StringBuilder
(
"${ConfigHelper.eventUrl}/${pkg.filter { it.isLowerCase() }.substring(4, 9)}sp"
)
url
.
append
(
"?pkg=$pkg"
)
url
.
toString
()
}
fun
event
(
key
:
String
,
value
:
String
?
=
null
,
ext
:
JSONObject
?
=
null
,
isSingleEvent
:
Boolean
=
false
)
{
if
(
isSingleEvent
)
{
val
stringSet
=
SPUtils
.
getInstance
().
getStringSet
(
"singleEvent"
)
if
(
stringSet
.
contains
(
key
))
{
return
}
}
val
pkg
=
ConfigHelper
.
packageName
val
d1
=
JSONObject
()
.
put
(
"action"
,
key
)
.
put
(
"value"
,
value
)
.
put
(
"ext"
,
ext
)
val
d2
=
JSONObject
()
.
put
(
"${pkg}_1"
,
"${ScreenUtils.getScreenHeight()}"
)
.
put
(
"${pkg}_2"
,
"${ScreenUtils.getScreenWidth()}"
)
.
put
(
"${pkg}_3"
,
DeviceUtils
.
getModel
())
.
put
(
"${pkg}_4"
,
Build
.
MANUFACTURER
)
.
put
(
"${pkg}_5"
,
Build
.
VERSION
.
SDK_INT
)
.
put
(
"${pkg}_6"
,
"${NetworkUtils.getNetworkType()}"
)
.
put
(
"${pkg}_8"
,
AppUtils
.
getAppVersionName
())
.
put
(
"${pkg}_9"
,
DeviceUtils
.
getAndroidID
())
.
put
(
"${pkg}_10"
,
ConfigHelper
.
gid
)
.
put
(
"${pkg}_11"
,
System
.
getProperty
(
"http.agent"
))
.
put
(
"${pkg}_13"
,
"android"
)
.
put
(
"${pkg}_14"
,
"${AppUtils.getAppVersionCode()}"
)
.
put
(
"${pkg}_15"
,
"google"
)
.
put
(
"${pkg}_24"
,
BuildConfig
.
BUILD_TYPE
)
// .put("${pkg}_25", PhoneTools.isRoot())
.
put
(
"${pkg}_25"
,
KokoReportHelper
.
isShellRooted
())
// .put("${pkg}_26", PhoneTools.isHooked())
.
put
(
"${pkg}_26"
,
KokoReportHelper
.
isHooked
())
// .put("${pkg}_27", PhoneTools.isEmulator())
.
put
(
"${pkg}_27"
,
KokoReportHelper
.
isVirtualMachine
())
// .put("${pkg}_29", PhoneTools.checkWifiProxy())
.
put
(
"${pkg}_29"
,
KokoReportHelper
.
isWifiProxy
(
MyApplication
.
fContext
))
// .put("${pkg}_30", PhoneTools.hasVPN())
.
put
(
"${pkg}_30"
,
KokoReportHelper
.
isVpnConnected
(
MyApplication
.
fContext
))
// .put("${pkg}_31", if(DeviceUtils.isDevelopmentSettingsEnabled()){1} else 0)
.
put
(
"${pkg}_31"
,
if
(
KokoReportHelper
.
isEnableDeveloperDebug
(
MyApplication
.
fContext
))
1
else
0
)
// .put("${pkg}_32", PhoneTools.isBatteryCharg())
.
put
(
"${pkg}_32"
,
isCharging
(
MyApplication
.
fContext
))
// .put("${pkg}_33", ConfigHelper.sensorParm)
.
put
(
"${pkg}_33"
,
GravitySensorManager
.
sensorParm
)
val
data
=
JSONObject
()
.
put
(
"data"
,
d1
)
.
put
(
"bp"
,
d2
)
.
toString
()
val
body
=
AESHelper
.
encrypt
(
data
).
toRequestBody
(
"application/json;charset=utf-8"
.
toMediaTypeOrNull
())
val
client
=
OkHttpClient
.
Builder
().
apply
{
if
(
BuildConfig
.
DEBUG
)
{
addInterceptor
(
HttpLoggingInterceptor
().
apply
{
level
=
HttpLoggingInterceptor
.
Level
.
BODY
})
}
}.
build
()
val
request
=
Request
.
Builder
()
.
url
(
url
)
.
post
(
body
)
.
build
()
client
.
newCall
(
request
).
enqueue
(
object
:
Callback
{
override
fun
onFailure
(
call
:
Call
,
e
:
IOException
)
{
}
override
fun
onResponse
(
call
:
Call
,
response
:
Response
)
{
Log
.
d
(
"TAG"
,
"event: $key"
)
if
(
isSingleEvent
)
{
val
stringSet
=
SPUtils
.
getInstance
().
getStringSet
(
"singleEvent"
,
mutableSetOf
())
stringSet
.
add
(
key
)
SPUtils
.
getInstance
().
put
(
"singleEvent"
,
stringSet
)
}
}
})
}
}
\ No newline at end of file
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/ad/GravitySensorManager.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.ad
import
android.content.Context
import
android.hardware.Sensor
import
android.hardware.SensorEvent
import
android.hardware.SensorEventListener
import
android.hardware.SensorManager
import
android.util.Log
import
java.util.Timer
import
java.util.TimerTask
import
java.util.concurrent.atomic.AtomicBoolean
import
kotlin.math.sqrt
import
kotlin.time.Duration.Companion.seconds
import
kotlin.time.DurationUnit
/**
* 重量传感器
*/
class
GravitySensorManager
(
val
context
:
Context
)
{
private
var
sensorManager
:
SensorManager
=
context
.
getSystemService
(
Context
.
SENSOR_SERVICE
)
as
SensorManager
private
var
mySensorEventListener
:
MySensorEventListener
?
=
null
private
var
xWave
=
0f
private
var
yWave
=
0f
private
var
zWave
=
0f
private
val
initValue
=
AtomicBoolean
(
false
)
companion
object
{
private
var
x
:
Float
=
0f
private
var
y
:
Float
=
0f
private
var
z
:
Float
=
0f
var
sensorParm
:
String
=
"$x:$y:$z"
}
init
{
val
time
=
Timer
()
val
timerTask
=
object
:
TimerTask
()
{
override
fun
run
()
{
}
}
time
.
schedule
(
timerTask
,
5
.
seconds
.
toLong
(
DurationUnit
.
MILLISECONDS
),
20
.
seconds
.
toLong
(
DurationUnit
.
MILLISECONDS
))
}
inner
class
MySensorEventListener
:
SensorEventListener
{
/**
* 传感器实时测量出来的变化值
*/
override
fun
onSensorChanged
(
event
:
SensorEvent
)
{
if
(
event
.
sensor
.
type
==
Sensor
.
TYPE_ACCELEROMETER
)
{
// if (!initValue.get()) {
// x = event.values[SensorManager.DATA_X]
// y = event.values[SensorManager.DATA_Y]
// z = event.values[SensorManager.DATA_Z]
// initValue.set(true)
// } else {
//
// val changeX = x - event.values[SensorManager.DATA_X]
// val changeY = y - event.values[SensorManager.DATA_Y]
// val changeZ = z - event.values[SensorManager.DATA_Z]
//
// xWave = changeX.coerceAtLeast(xWave)
// yWave = changeY.coerceAtLeast(yWave)
// zWave = changeZ.coerceAtLeast(zWave)
//
// }
x
=
event
.
values
[
SensorManager
.
DATA_X
]
y
=
event
.
values
[
SensorManager
.
DATA_Y
]
z
=
event
.
values
[
SensorManager
.
DATA_Z
]
// Log.e("GravitySensorManager", "$x:$y:$z")
}
}
override
fun
onAccuracyChanged
(
sensor
:
Sensor
?,
accuracy
:
Int
)
{
}
}
/**
* onResume() 注册
*/
fun
registerListener
()
{
if
(
mySensorEventListener
==
null
)
{
mySensorEventListener
=
MySensorEventListener
()
}
val
sensorAccelerometer
=
sensorManager
.
getDefaultSensor
(
Sensor
.
TYPE_ACCELEROMETER
)
sensorManager
.
registerListener
(
mySensorEventListener
,
sensorAccelerometer
,
SensorManager
.
SENSOR_DELAY_UI
)
}
/**
* onPause()注销
*/
fun
unregisterListener
()
{
sensorManager
.
unregisterListener
(
mySensorEventListener
)
}
}
\ No newline at end of file
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/ad/KokoReportHelper.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.ad
import
android.annotation.SuppressLint
import
android.content.Context
import
android.content.Intent
import
android.content.IntentFilter
import
android.content.pm.PackageManager
import
android.hardware.Sensor
import
android.hardware.SensorManager
import
android.net.ConnectivityManager
import
android.net.Proxy
import
android.os.BatteryManager
import
android.os.Build
import
android.telephony.TelephonyManager
import
android.text.TextUtils
import
java.io.DataOutputStream
import
java.io.File
import
java.lang.reflect.Method
object
KokoReportHelper
{
//https://blog.51cto.com/u_16213304/7913939
//是否root
/**
* 通过Path判断是否root
*/
fun
isPathRooted
():
Boolean
{
val
paths
=
arrayOf
(
"/system/bin/"
,
"/system/xbin/"
,
"/su/bin/"
,
"/sbin/"
,
"/su/"
)
for
(
path
in
paths
)
{
if
(
File
(
path
+
"su"
).
exists
())
{
return
true
}
}
return
false
}
/**
* 通过执行shell命令来判断设备是否已经root
*/
fun
isShellRooted
():
Boolean
{
try
{
val
process
=
Runtime
.
getRuntime
().
exec
(
"su"
)
val
os
=
DataOutputStream
(
process
.
outputStream
)
os
.
writeBytes
(
"echo root\n"
)
os
.
writeBytes
(
"exit\n"
)
os
.
flush
()
process
.
waitFor
()
if
(
process
.
exitValue
()
==
0
)
{
return
true
}
}
catch
(
e
:
Exception
)
{
// e.printStackTrace()
}
return
false
}
/**
* 是否是虚拟机
* https://blog.51cto.com/u_16175492/7712954
* 检查当前设备的信息,包括设备型号、产品名称、品牌、硬件等
*/
fun
isVirtualMachine
():
Boolean
{
val
manufacturer
=
Build
.
MANUFACTURER
val
model
=
Build
.
MODEL
val
product
=
Build
.
PRODUCT
return
if
(
manufacturer
.
contains
(
"Genymotion"
)
||
model
.
contains
(
"Emulator"
)
||
product
.
contains
(
"sdk"
))
{
true
}
else
false
}
/**
* 是否插sim卡
*/
fun
isSimCardInserted
(
context
:
Context
):
Boolean
{
val
telephonyManager
=
context
.
getSystemService
(
Context
.
TELEPHONY_SERVICE
)
as
TelephonyManager
return
telephonyManager
.
getSimState
()
==
TelephonyManager
.
SIM_STATE_READY
}
/**
* 是否有代理
* 判断设备 是否使用代理上网
* https://blog.csdn.net/verynewbeee/article/details/135698990
*/
@SuppressLint
(
"ObsoleteSdkInt"
)
fun
isWifiProxy
(
context
:
Context
?):
Boolean
{
val
IS_ICS_OR_LATER
=
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
ICE_CREAM_SANDWICH
val
proxyAddress
:
String
val
proxyPort
:
Int
if
(
IS_ICS_OR_LATER
)
{
proxyAddress
=
System
.
getProperty
(
"http.proxyHost"
)
?:
""
val
portStr
=
System
.
getProperty
(
"http.proxyPort"
)
proxyPort
=
(
portStr
?:
"-1"
).
toInt
()
}
else
{
proxyAddress
=
Proxy
.
getHost
(
context
)
proxyPort
=
Proxy
.
getPort
(
context
)
}
return
!
TextUtils
.
isEmpty
(
proxyAddress
)
&&
proxyPort
!=
-
1
}
/**
* 是否开启vpn
* https://cloud.tencent.com/developer/ask/2122015
*/
@SuppressLint
(
"ObsoleteSdkInt"
)
fun
isVpnConnected
(
context
:
Context
):
Boolean
{
val
cm
=
context
.
getSystemService
(
Context
.
CONNECTIVITY_SERVICE
)
as
ConnectivityManager
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
LOLLIPOP
)
{
val
networkInfo
=
cm
.
activeNetworkInfo
if
(
networkInfo
!=
null
)
{
return
networkInfo
.
type
==
ConnectivityManager
.
TYPE_VPN
}
}
else
{
// 低版本 Android 系统可能需要使用其他方法检测 VPN 连接
}
return
false
}
/**
* 开发者模式是否开启
*
* 检测是否开启动了usb 调试模式
*/
@SuppressLint
(
"PrivateApi"
)
fun
isEnableDeveloperDebug
(
context
:
Context
):
Boolean
{
var
adb
=
""
try
{
val
clazz
=
Class
.
forName
(
"android.os.SystemProperties"
)
val
get
:
Method
=
clazz
.
getMethod
(
"get"
,
String
::
class
.
java
,
String
::
class
.
java
)
adb
=
get
.
invoke
(
clazz
,
"persist.sys.usb.config"
,
""
)
?.
toString
()
?:
""
}
catch
(
e
:
java
.
lang
.
Exception
)
{
}
return
adb
==
"adb"
}
/**
* 是否在充电
* https://blog.csdn.net/su749520/article/details/83898354
*/
fun
isCharging
(
context
:
Context
):
Boolean
{
val
batteryBroadcast
=
context
.
registerReceiver
(
null
,
IntentFilter
(
Intent
.
ACTION_BATTERY_CHANGED
)
)
// 0 means we are discharging, anything else means charging
val
isCharging
=
batteryBroadcast
!!
.
getIntExtra
(
BatteryManager
.
EXTRA_PLUGGED
,
-
1
)
!=
0
return
isCharging
}
/**
* 获取手机中所有app列表
* 获取所有带有桌面属性的APK
*/
@SuppressLint
(
"QueryPermissionsNeeded"
)
fun
getAllLauncherAppPackage
(
context
:
Context
):
List
<
String
>
{
val
intent
=
Intent
().
apply
{
action
=
Intent
.
ACTION_MAIN
addCategory
(
Intent
.
CATEGORY_LAUNCHER
)
}
val
resolveInfos
=
context
.
packageManager
.
queryIntentActivities
(
intent
,
PackageManager
.
MATCH_ALL
)
return
resolveInfos
.
map
{
it
.
activityInfo
.
packageName
}
}
/**
* 是否支持重力传感器
*/
fun
isSupportAccelerometer
(
context
:
Context
):
Boolean
{
val
sensorManager
:
SensorManager
=
context
.
getSystemService
(
Context
.
SENSOR_SERVICE
)
as
SensorManager
val
sensorAccelerometer
=
sensorManager
.
getDefaultSensor
(
Sensor
.
TYPE_ACCELEROMETER
)
return
sensorAccelerometer
!=
null
}
fun
isHooked
():
Int
{
try
{
// 检测Xposed
Class
.
forName
(
"de.robv.android.xposed.XposedBridge"
)
return
1
}
catch
(
e
:
ClassNotFoundException
)
{
// 忽略异常
}
try
{
// 检测Frida
Class
.
forName
(
"com.android.server.frida.Server"
)
return
1
}
catch
(
e
:
ClassNotFoundException
)
{
// 忽略异常
}
// 检测Substrate
if
(
File
(
"/data/local/tmp/inject"
).
exists
())
{
return
1
}
return
0
}
}
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/ad/MaxAdUtils.kt
0 → 100644
View file @
e8f694cc
This diff is collapsed.
Click to expand it.
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/ad/MyReportViewLisenter.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.ad
import
android.view.View
object
MyReportViewListener
{
class
ReportViewListener
(
val
className
:
String
,
val
click
:
()
->
Unit
)
:
View
.
OnClickListener
{
override
fun
onClick
(
v
:
View
)
{
val
idString
=
v
.
context
.
resources
.
getResourceEntryName
(
v
.
id
)
EventHelper
.
event
(
"viewClick_${className}_$idString"
)
click
.
invoke
()
}
}
fun
View
.
setMyReportViewListener
(
className
:
String
,
click
:
()
->
Unit
)
{
this
.
setOnClickListener
(
ReportViewListener
(
className
,
click
))
}
}
\ No newline at end of file
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/ad/PushManager.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.ad
import
com.xm.test.myfilemaster.MyApplication
import
com.xm.test.myfilemaster.ad.bean.PushCfg
object
PushManager
{
/**
* 新用户是否显示
*/
fun
newUserPush
(
newUserAvoidTime
:
Int
):
Boolean
{
val
firstLaunchTime
=
MyApplication
.
fContext
.
queryDataStoreBlock
(
FIRST_LAUNCH_TIME_KEY
,
0L
)
val
flag
=
(
System
.
currentTimeMillis
()
-
firstLaunchTime
)
/
1000
>
newUserAvoidTime
return
flag
}
/**
* 所有推送是否推送大于间隔时间
* @param interval 单位分钟
*/
fun
canPushNextTime
(
interval
:
Int
):
Boolean
{
val
lastPushTime
=
MyApplication
.
fContext
.
queryDataStoreBlock
(
ALL_LAST_PUSH_TIME
,
0
)
return
(
System
.
currentTimeMillis
()
-
lastPushTime
)
/
1000
>
interval
}
/**
* 根据id判断通知是否可推送
* @param actionId 功能或者场景的id
*/
fun
isPush
(
actionId
:
Int
):
Boolean
{
// 新用户是否显示
val
pushManagement
=
ComUtils
.
getPushConfig
()
if
(!
newUserPush
(
pushManagement
.
newuser_avoid_time
))
{
return
false
}
// 渠道用户是否推送
if
(!
UserChancelEx
.
getUserChancelSwitch
(
pushManagement
.
push_show
))
{
return
false
}
//是否上次推送间隔大于配置间隔
val
isOganic
=
UserChancelEx
.
isOrganicUser
()
val
interval
=
if
(
isOganic
)
pushManagement
.
o_push_interval
else
pushManagement
.
all_push_interval
if
(!
canPushNextTime
(
interval
))
{
return
false
}
//当前类型通知推送间隔是否大于配置间隔
if
(!
actionTypeCanPsh
(
actionId
))
{
return
false
}
return
true
}
/**
* 当前类型通知推送间隔是否大于配置间隔
*/
private
fun
actionTypeCanPsh
(
actionId
:
Int
):
Boolean
{
val
pushCfg
:
PushCfg
?
=
ComUtils
.
getPushTypeData
(
actionId
.
toString
())
val
pushInterval
=
pushCfg
?.
push_interval
?:
0
val
lastTypePushTime
=
MyApplication
.
fContext
.
queryDataStoreBlock
(
createByActionId
(
actionId
),
0L
)
return
(
System
.
currentTimeMillis
()
-
lastTypePushTime
)
/
1000
>
pushInterval
}
}
\ No newline at end of file
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/ad/UserChancelEx.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.ad
import
android.content.Context
import
android.telephony.TelephonyManager
import
com.xm.test.myfilemaster.MyApplication
/**
* 判断用户渠道的方法
*/
object
UserChancelEx
{
fun
getUserChancelSwitch
(
int
:
Int
):
Boolean
{
val
isOrganic
=
isOrganicUser
()
val
isHasSim
=
isSimCardAvailable
()
return
l
(
int
,
isHasSim
,
isOrganic
)
}
fun
l
(
i2
:
Int
,
isHasSim
:
Boolean
,
isOrganic
:
Boolean
):
Boolean
{
return
if
(!
isOrganic
&&
!
k
(
i2
,
3
))
{
false
}
else
if
(
isOrganic
&&
!
k
(
i2
,
2
))
{
false
}
else
if
(!
isHasSim
&&
!
k
(
i2
,
1
))
{
false
}
else
if
(
isHasSim
&&
!
k
(
i2
,
0
))
{
false
}
else
k
(
i2
,
4
)
}
fun
k
(
i2
:
Int
,
i3
:
Int
):
Boolean
{
return
i2
shr
i3
and
1
==
1
}
/**
* 是否是自然用户
*/
fun
isOrganicUser
():
Boolean
{
val
source
:
String
=
MyApplication
.
fContext
.
queryDataStoreBlock
(
INSTALL_INFO
,
""
)
//是存储的installReferrer
return
!(
source
.
contains
(
"gclid"
)
||
source
.
contains
(
"facebook"
))
}
fun
isSimCardAvailable
():
Boolean
{
val
telephonyManager
=
MyApplication
.
fContext
.
getSystemService
(
Context
.
TELEPHONY_SERVICE
)
as
TelephonyManager
return
telephonyManager
.
simState
!=
TelephonyManager
.
SIM_STATE_ABSENT
}
}
\ No newline at end of file
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/ad/bean/AdUnitCfg.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.ad.bean
data class
AdUnitCfg
(
val
banner
:
AdUnitEntity
,
val
native
:
AdUnitEntity
,
val
rewardAd
:
AdUnitEntity
,
val
openAd
:
AdUnitEntity
?,
val
interAd
:
AdUnitEntity
)
{
data class
AdUnitEntity
(
val
unit_id
:
String
=
"wwwsss"
)
}
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/ad/bean/AdsCfg.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.ad.bean
/**
* 广告位配置
*/
data class
AdsCfg
(
val
banner
:
AdEntity
,
val
interstitial
:
AdEntity
,
val
rewardAd
:
AdEntity
,
val
splash
:
AdEntity
,
val
ad_open
:
AdEntity
)
{
/**
* 开屏广告配置配
*/
data class
AdEntity
(
var
is_show
:
Int
=
31
,
//是否展示
var
show_interval
:
Int
=
0
,
//展示间隔
var
new_user_avoid_time
:
Int
=
0
,
//新用户避免开启
var
unit_id
:
String
=
"12312443123"
,
var
type
:
String
=
"3"
,
var
open_ad_is_show
:
Int
=
31
,
var
loading_page_time
:
Int
=
5
,
var
show_limit
:
Int
=
40
)
}
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/ad/bean/ConfigureData.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.ad.bean
/**
* 广告配置数据
*/
data class
ConfigureData
(
val
ads_cfg
:
AdsCfg
,
val
ad_unit_cfg
:
AdUnitCfg
,
val
global_config
:
GlobalConfig
,
val
push_cfg
:
List
<
PushCfg
>,
val
push_management
:
PushManagement
)
\ No newline at end of file
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/ad/bean/GlobalConfig.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.ad.bean
/**
* 全局配置
*/
data class
GlobalConfig
(
var
cache_time
:
Int
=
0
,
var
rate_window_interval
:
Int
=
0
,
var
buy_insert_interval
:
Int
=
0
,
var
nature_insert_interval
:
Int
=
0
,
var
not_dialog_interval
:
Int
=
0
)
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/ad/bean/PushCfg.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.ad.bean
/**
* 功能和场景的推送配置
*
* 扩展字段,主要是触发弹窗的阈值设定。比如内存低于10%,启动弹窗,配置值为10。 内存使用占比阈值,当前温度阈值,当前电量阈值
* @param feature_ex1
*
*/
class
PushCfg
(
val
actionId
:
Int
=
0
,
val
push_stay_time
:
Int
=
10
,
val
last_use_interval
:
Int
=
0
,
val
push_interval
:
Int
=
0
,
val
feature_ex1
:
Int
=
0
,
)
{
companion
object
{
//功能触发push actionId 主动发送
const
val
ID_JUNK_CLEAN_PUSH
=
11001
//清理垃圾
const
val
ID_BOOST_PUSH
=
11002
//性能优化
const
val
ID_VIRUS_PUSH
=
11003
//扫描病毒
const
val
ID_BATTERY_PUSH
=
11004
// 电量优化
const
val
ID_COOL_PUSH
=
11005
//手机降温
const
val
ID_BIGFILE_PUSH
=
11006
// 大文件清理
const
val
ID_DUPLICATE_FILE_PUSH
=
11007
//文件备份,重复文件,相似文件
const
val
ID_VIDEO_CLEAN_PUSH
=
11008
//清理视频缓存
const
val
ID_PHOTO_CLEAN_PUSH
=
11009
//清理相册
//场景触发push actionId 被动发送
const
val
ID_WIFI_PUSH
=
22001
//连接wifi时
const
val
ID_INSTALL_PACKAGE_PUSH
=
22002
//安装应用
const
val
ID_UNINSTALL_PACKAGE_PUSH
=
22003
//卸载应用
const
val
ID_CHARGE
=
22004
//充电
const
val
ID_LOW_BATTERY_PUSH
=
22005
//电量低于阈值时
const
val
ID_LOW_JUNK_PUSH
=
22007
//垃圾文件高于阈值时
}
}
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/ad/bean/PushManagement.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.ad.bean
/**
* 推送管理
*/
data class
PushManagement
(
var
push_show
:
Int
=
0
,
var
newuser_avoid_time
:
Int
=
0
,
var
all_push_interval
:
Int
=
0
,
var
o_push_interval
:
Int
=
0
,
var
push_circle_order
:
List
<
Int
>
=
listOf
(),
var
scene_push
:
List
<
Int
>
=
listOf
(),
)
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/ad/bean/ZxhyConfigure.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.ad.bean
import
com.xm.test.myfilemaster.ad.bean.ConfigureData
data class
ZxhyConfigure
(
val
data
:
ConfigureData
)
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/base/BaseActivity.kt
View file @
e8f694cc
...
...
@@ -205,11 +205,22 @@ abstract class BaseActivity : BaseAbsView(), BaseActivityListener{
MyApplication
.
mCleanSdk
?.
delete
(
File
(
fileBean
.
filePath
))
}
mFileAdapter
.
setData
(
mItemDataList
)
if
(
mItemDataList
.
size
==
0
){
mFilesItemListView
.
visibility
=
View
.
GONE
mNotFileFoundLayout
.
visibility
=
View
.
VISIBLE
mEditBtn
.
visibility
=
View
.
GONE
}
else
{
mFilesItemListView
.
visibility
=
View
.
VISIBLE
mNotFileFoundLayout
.
visibility
=
View
.
GONE
mEditBtn
.
visibility
=
View
.
VISIBLE
mFileAdapter
.
setData
(
mItemDataList
)
}
}).
show
()
customDialog
.
isShowEditText
(
false
)
customDialog
.
setsTitle
(
"Delete"
)
customDialog
.
setsHint
(
"Are you sure you want to delete ${mFileCheckedItemList.size} item?"
)
customDialog
.
setsRightDelete
(
"Delete"
)
cancel
()
}
R
.
id
.
btn_share
->{
if
(
switchNumber
>
1
){
...
...
@@ -395,8 +406,17 @@ abstract class BaseActivity : BaseAbsView(), BaseActivityListener{
Thread
(
Runnable
{
runOnUiThread
{
mItemDataList
=
mCurrentFileBean
!!
.
childList
val
fileListSort
=
FileUtil
.
fileListSort
(
mItemDataList
)
mFileAdapter
.
setData
(
fileListSort
)
mItemDataList
=
FileUtil
.
fileListSort
(
mItemDataList
)
if
(
mItemDataList
.
size
==
0
){
mFilesItemListView
.
visibility
=
View
.
GONE
mNotFileFoundLayout
.
visibility
=
View
.
VISIBLE
mEditBtn
.
visibility
=
View
.
GONE
}
else
{
mFilesItemListView
.
visibility
=
View
.
VISIBLE
mNotFileFoundLayout
.
visibility
=
View
.
GONE
mEditBtn
.
visibility
=
View
.
VISIBLE
mFileAdapter
.
setData
(
mItemDataList
)
}
}
}).
start
()
}
else
if
(
mCurrentFileBean
?.
fileType
.
equals
(
"dir"
)
&&
mCurrentFileBean
?.
childList
?.
size
==
0
){
...
...
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/notification/ActionBroadcast.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.notification
import
android.app.ActivityManager
import
android.content.BroadcastReceiver
import
android.content.Context
import
android.content.Intent
import
android.os.BatteryManager
import
android.util.Log
import
com.xm.test.myfilemaster.MyApplication
import
com.xm.test.myfilemaster.ad.ComUtils
import
com.xm.test.myfilemaster.ad.PushManager
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_BOOST_PUSH
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_CHARGE
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_INSTALL_PACKAGE_PUSH
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_LOW_BATTERY_PUSH
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_LOW_JUNK_PUSH
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_UNINSTALL_PACKAGE_PUSH
import
com.xm.test.myfilemaster.notification.NotificationHelper.postNotification
import
com.xm.test.myfilemaster.common.notification.NotificationEx
import
java.io.File
class
ActionBroadcast
:
BroadcastReceiver
()
{
private
var
mIsScreenOn
=
false
private
var
isLock
=
false
override
fun
onReceive
(
context
:
Context
?,
intent
:
Intent
?)
{
val
action
=
intent
?.
action
?:
0
if
(
action
==
Intent
.
ACTION_SCREEN_ON
)
{
Log
.
d
(
"glc"
,
"屏幕解锁广播..."
)
Log
.
d
(
"glc"
,
"屏幕亮广播"
)
mIsScreenOn
=
true
if
(!
isLock
&&
mIsScreenOn
)
{
val
id
=
NotificationEx
.
getPresentPushId
()
val
flag
=
PushManager
.
isPush
(
id
)
if
(
flag
)
{
MyApplication
.
fContext
.
postNotification
(
id
)
}
}
}
else
if
(
action
==
Intent
.
ACTION_SCREEN_OFF
)
{
Log
.
d
(
"glc"
,
"屏幕加锁广播..."
)
Log
.
d
(
"glc"
,
"屏幕熄灭广播"
)
mIsScreenOn
=
false
isLock
=
true
}
else
if
(
action
==
Intent
.
ACTION_USER_PRESENT
)
{
isLock
=
false
// Log.d("glc", "解锁")
if
(
mIsScreenOn
&&
!
isLock
)
{
// 展示主动推送
val
id
=
NotificationEx
.
getPresentPushId
()
val
flag
=
PushManager
.
isPush
(
id
)
if
(
flag
)
{
MyApplication
.
fContext
.
postNotification
(
id
)
}
}
}
else
if
(
action
==
Intent
.
ACTION_PACKAGE_REMOVED
)
{
// Log.d("glc", "app卸载")
Log
.
d
(
"glc"
,
"app卸载"
)
val
flag
=
PushManager
.
isPush
(
ID_UNINSTALL_PACKAGE_PUSH
)
if
(
flag
)
{
MyApplication
.
fContext
.
postNotification
(
ID_UNINSTALL_PACKAGE_PUSH
)
}
}
else
if
(
action
==
Intent
.
ACTION_PACKAGE_ADDED
)
{
// Log.d("glc", "app安装")
Log
.
d
(
"glc"
,
"app安装"
)
val
flag
=
PushManager
.
isPush
(
ID_INSTALL_PACKAGE_PUSH
)
if
(
flag
)
{
MyApplication
.
fContext
.
postNotification
(
ID_INSTALL_PACKAGE_PUSH
)
}
}
else
if
(
action
==
Intent
.
ACTION_POWER_DISCONNECTED
||
action
==
Intent
.
ACTION_POWER_CONNECTED
)
{
// Log.d("glc", "拔电和插电")
Log
.
d
(
"glc"
,
"拔电和插电"
)
val
flag
=
PushManager
.
isPush
(
ID_CHARGE
)
if
(
flag
)
{
MyApplication
.
fContext
.
postNotification
(
ID_CHARGE
)
}
}
else
if
(
action
==
Intent
.
ACTION_BATTERY_CHANGED
)
{
//电量发生变化
val
level
=
intent
?.
getIntExtra
(
BatteryManager
.
EXTRA_LEVEL
,
-
1
)
?:
-
1
val
scale
:
Int
?
=
intent
?.
getIntExtra
(
BatteryManager
.
EXTRA_SCALE
,
-
1
)
// Log.d("mxl", "ACTION_BATTERY_CHANGED")
//低电量阀值推送
val
config
=
ComUtils
.
getPushTypeData
(
ID_LOW_BATTERY_PUSH
.
toString
())
val
flag
=
PushManager
.
isPush
(
ID_LOW_BATTERY_PUSH
)
val
lowValue
=
config
?.
feature_ex1
?:
0
if
(
flag
&&
(
level
<
lowValue
))
{
MyApplication
.
fContext
.
postNotification
(
ID_LOW_BATTERY_PUSH
)
}
}
else
if
(
action
==
Intent
.
ACTION_MEDIA_MOUNTED
||
action
==
Intent
.
ACTION_MEDIA_REMOVED
||
action
==
Intent
.
ACTION_MEDIA_UNMOUNTED
||
action
==
Intent
.
ACTION_MEDIA_BAD_REMOVAL
)
{
val
path
=
intent
?.
data
?.
path
val
file
=
File
(
path
)
val
availableSpace
=
file
.
usableSpace
val
totalSpace
=
file
.
totalSpace
val
num
=
totalSpace
-
availableSpace
val
entity
=
ComUtils
.
getPushTypeData
(
"22007"
)
if
(
num
<=
entity
?.
feature_ex1
?:
0
)
{
//展示垃圾文件过大推送
val
flag
=
PushManager
.
isPush
(
ID_LOW_JUNK_PUSH
)
if
(
flag
)
{
MyApplication
.
fContext
.
postNotification
(
ID_LOW_JUNK_PUSH
)
}
}
}
else
if
(
action
==
Intent
.
ACTION_DEVICE_STORAGE_LOW
||
action
==
Intent
.
ACTION_DEVICE_STORAGE_OK
)
{
val
activityManager
=
context
!!
.
getSystemService
(
Context
.
ACTIVITY_SERVICE
)
as
ActivityManager
val
memoryInfo
=
ActivityManager
.
MemoryInfo
()
activityManager
.
getMemoryInfo
(
memoryInfo
)
val
availableMemory
=
memoryInfo
.
availMem
val
totalMemory
=
memoryInfo
.
totalMem
val
num
=
totalMemory
-
availableMemory
val
entity
=
ComUtils
.
getPushTypeData
(
"22005"
)
if
(
num
>=
entity
?.
feature_ex1
?:
0
)
{
// 展示性能变差推送
val
flag
=
PushManager
.
isPush
(
ID_BOOST_PUSH
)
if
(
flag
)
{
MyApplication
.
fContext
.
postNotification
(
ID_BOOST_PUSH
)
}
}
}
}
}
\ No newline at end of file
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/notification/NotificationEx.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.common.notification
import
com.xm.test.myfilemaster.ad.ComUtils
object
NotificationEx
{
var
mList
:
MutableList
<
Int
>
=
ArrayList
()
fun
getPresentPushId
():
Int
{
if
(
mList
.
size
<=
0
){
mList
.
addAll
(
ComUtils
.
getPushConfig
().
push_circle_order
)
}
val
i
=
mList
[
0
]
mList
.
add
(
i
)
mList
.
removeAt
(
0
)
return
i
}
}
\ No newline at end of file
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/notification/NotificationHelper.kt
0 → 100644
View file @
e8f694cc
package
com.xm.test.myfilemaster.notification
import
android.annotation.SuppressLint
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.graphics.Color
import
android.os.Build
import
android.widget.RemoteViews
import
androidx.core.app.NotificationCompat
import
androidx.core.app.NotificationManagerCompat
import
com.xm.test.myfilemaster.MyApplication
import
com.xm.test.myfilemaster.R
import
com.xm.test.myfilemaster.activity.HomeActivity
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_BATTERY_PUSH
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_BIGFILE_PUSH
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_BOOST_PUSH
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_CHARGE
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_COOL_PUSH
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_DUPLICATE_FILE_PUSH
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_INSTALL_PACKAGE_PUSH
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_JUNK_CLEAN_PUSH
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_LOW_BATTERY_PUSH
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_LOW_JUNK_PUSH
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_PHOTO_CLEAN_PUSH
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_UNINSTALL_PACKAGE_PUSH
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_VIDEO_CLEAN_PUSH
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_VIRUS_PUSH
import
com.xm.test.myfilemaster.ad.bean.PushCfg.Companion.ID_WIFI_PUSH
import
com.xm.test.myfilemaster.ad.createByActionId
import
com.xm.test.myfilemaster.ad.saveDataStoreBlock
import
kotlin.random.Random
/**
* 动态申请 <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
*/
object
NotificationHelper
{
private
const
val
CHANNEL_ID
=
"msjdhusjdsd"
private
const
val
CHANNEL_NAME
=
"File Manager Select"
@SuppressLint
(
"RemoteViewLayout"
)
fun
Context
.
postNotification
(
actionId
:
Int
)
{
// Log.d("glc", "actionId:" + actionId)
val
intent
=
Intent
(
applicationContext
,
HomeActivity
::
class
.
java
)
var
remoteViews
:
RemoteViews
var
myValue
=
0
when
(
actionId
)
{
ID_JUNK_CLEAN_PUSH
->
{
remoteViews
=
RemoteViews
(
packageName
,
R
.
layout
.
notification_junk_clean
)
}
ID_BOOST_PUSH
->
{
return
}
ID_VIRUS_PUSH
->
{
return
}
ID_BATTERY_PUSH
->
{
remoteViews
=
RemoteViews
(
packageName
,
R
.
layout
.
notification_battery
)
}
ID_COOL_PUSH
->
{
return
}
ID_BIGFILE_PUSH
->
{
remoteViews
=
RemoteViews
(
packageName
,
R
.
layout
.
notification_large_file
)
}
ID_DUPLICATE_FILE_PUSH
->
{
return
}
ID_VIDEO_CLEAN_PUSH
->
{
return
}
ID_PHOTO_CLEAN_PUSH
->
{
return
}
//==================================下面是被动推送的情况===============================================
ID_WIFI_PUSH
->
{
return
}
ID_INSTALL_PACKAGE_PUSH
->
{
remoteViews
=
RemoteViews
(
packageName
,
R
.
layout
.
notification_install
)
}
ID_UNINSTALL_PACKAGE_PUSH
->
{
remoteViews
=
RemoteViews
(
packageName
,
R
.
layout
.
notification_uninstall
)
}
ID_CHARGE
->
{
remoteViews
=
RemoteViews
(
packageName
,
R
.
layout
.
notification_battery
)
}
ID_LOW_BATTERY_PUSH
->
{
remoteViews
=
RemoteViews
(
packageName
,
R
.
layout
.
notification_battery_low
)
}
ID_LOW_JUNK_PUSH
->
{
return
}
else
->
{
return
}
}
myValue
=
actionId
val
customKey
=
"type"
intent
.
putExtra
(
customKey
,
myValue
)
MyApplication
.
fContext
.
saveDataStoreBlock
(
createByActionId
(
actionId
),
System
.
currentTimeMillis
())
showNotification
(
applicationContext
,
intent
,
remoteViews
)
}
//创建通知通道
private
fun
createNotificationChannel
(
context
:
Context
,
channelId
:
String
=
CHANNEL_ID
,
channelName
:
String
=
CHANNEL_NAME
,
)
{
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
val
importance
=
NotificationManager
.
IMPORTANCE_HIGH
val
channel
=
NotificationChannel
(
channelId
,
channelName
,
importance
).
apply
{
enableLights
(
true
)
enableVibration
(
false
)
vibrationPattern
=
longArrayOf
(
0
)
lightColor
=
Color
.
RED
}
// Register the channel with the system
val
notificationManager
:
NotificationManager
=
context
.
getSystemService
(
Context
.
NOTIFICATION_SERVICE
)
as
NotificationManager
notificationManager
.
createNotificationChannel
(
channel
)
}
}
@SuppressLint
(
"MissingPermission"
)
//Manifest.permission.POST_NOTIFICATIONS
fun
showNotification
(
context
:
Context
,
intent
:
Intent
,
remoteViews
:
RemoteViews
)
{
createNotificationChannel
(
context
)
val
flag
=
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
S
)
{
PendingIntent
.
FLAG_MUTABLE
}
else
{
PendingIntent
.
FLAG_UPDATE_CURRENT
}
//requestCode每次需要改变
val
requestCode
=
Random
.
nextInt
(
0
,
1000
)
val
pendingIntent
=
PendingIntent
.
getActivity
(
context
,
requestCode
,
intent
,
flag
)
val
builder
=
NotificationCompat
.
Builder
(
context
,
CHANNEL_ID
)
.
setSmallIcon
(
R
.
drawable
.
ic_logo24
)
.
setLargeIcon
(
BitmapFactory
.
decodeResource
(
context
.
resources
,
R
.
drawable
.
ic_logo24
))
.
setCustomContentView
(
remoteViews
)
.
setCustomHeadsUpContentView
(
remoteViews
)
.
setCustomBigContentView
(
remoteViews
)
.
setContent
(
remoteViews
)
.
setPriority
(
NotificationCompat
.
PRIORITY_HIGH
)
.
setColor
(
Color
.
TRANSPARENT
)
.
setAutoCancel
(
true
)
.
setOngoing
(
true
)
.
setDefaults
(
NotificationCompat
.
FLAG_ONLY_ALERT_ONCE
)
.
setVibrate
(
longArrayOf
(
0
))
.
setContentIntent
(
pendingIntent
)
val
notificationId
=
Random
.
nextInt
(
0
,
1200
)
with
(
NotificationManagerCompat
.
from
(
context
))
{
notify
(
notificationId
,
builder
.
build
())
}
}
}
\ No newline at end of file
MyDemo3/app/src/main/java/com/xm/test/myfilemaster/util/PermissionUtil.kt
View file @
e8f694cc
...
...
@@ -28,8 +28,9 @@ object PermissionUtil {
context
?.
startActivity
(
intent
)
}
else
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
R
)
{
val
intent
=
Intent
().
apply
{
action
=
Settings
.
ACTION_
APPLICATION_DETAILS_SETTINGS
action
=
Settings
.
ACTION_
MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
data
=
Uri
.
fromParts
(
"package"
,
context
?.
packageName
,
null
)
flags
=
Intent
.
FLAG_ACTIVITY_NEW_TASK
}
context
?.
startActivity
(
intent
)
}
else
{
...
...
MyDemo3/app/src/main/res/layout/result_layout.xml
View file @
e8f694cc
...
...
@@ -75,7 +75,7 @@
<LinearLayout
android:layout_marginTop=
"155dp"
android:layout_width=
"match_parent"
android:layout_height=
"
wrap_cont
ent"
android:layout_height=
"
match_par
ent"
android:orientation=
"vertical"
>
<include
layout=
"@layout/ad_layout"
/>
...
...
MyDemo3/gradle/libs.versions.toml
View file @
e8f694cc
[versions]
agp
=
"8.
0.0
"
agp
=
"8.
1.3
"
kotlin
=
"1.9.0"
coreKtx
=
"1.10.1"
junit
=
"4.13.2"
...
...
@@ -27,6 +27,7 @@ androidx-legacy-support-v4 = { group = "androidx.legacy", name = "legacy-support
androidx-lifecycle-livedata-ktx
=
{
group
=
"androidx.lifecycle"
,
name
=
"lifecycle-livedata-ktx"
,
version.ref
=
"lifecycleLivedataKtx"
}
androidx-lifecycle-viewmodel-ktx
=
{
group
=
"androidx.lifecycle"
,
name
=
"lifecycle-viewmodel-ktx"
,
version.ref
=
"lifecycleViewmodelKtx"
}
androidx-fragment-ktx
=
{
group
=
"androidx.fragment"
,
name
=
"fragment-ktx"
,
version.ref
=
"fragmentKtx"
}
installreferrer
=
{
group
=
"com.android.installreferrer"
,
name
=
"installreferrer"
,
version
=
"2.2"
}
[plugins]
androidApplication
=
{
id
=
"com.android.application"
,
version.ref
=
"agp"
}
...
...
MyDemo3/gradle/wrapper/gradle-wrapper.properties
View file @
e8f694cc
#Tue Mar 26 19:05:58 CST 2024
distributionBase
=
GRADLE_USER_HOME
distributionPath
=
wrapper/dists
distributionUrl
=
https
\:
//services.gradle.org/distributions/gradle-8.
4
-bin.zip
distributionUrl
=
https
\:
//services.gradle.org/distributions/gradle-8.
0
-bin.zip
zipStoreBase
=
GRADLE_USER_HOME
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