Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Sign in / Register
Toggle navigation
F
File Recovery RecycleBin
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
File Recovery RecycleBin
Commits
33a08f5d
Commit
33a08f5d
authored
Nov 09, 2024
by
wanglei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
...
parent
620a9401
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
297 additions
and
39 deletions
+297
-39
build.gradle
app/build.gradle
+4
-0
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+8
-2
MyApplication.kt
...ain/java/com/base/filerecoveryrecyclebin/MyApplication.kt
+2
-0
FCMManager.kt
...in/java/com/base/filerecoveryrecyclebin/fcm/FCMManager.kt
+55
-37
StayJobService.kt
...com/base/filerecoveryrecyclebin/service/StayJobService.kt
+186
-0
RepeatingWorker.kt
...a/com/base/filerecoveryrecyclebin/work/RepeatingWorker.kt
+42
-0
No files found.
app/build.gradle
View file @
33a08f5d
...
...
@@ -119,4 +119,8 @@ dependencies {
//google 内购订阅
def
billing_version
=
"7.0.0"
implementation
"com.android.billingclient:billing:$billing_version"
//work
implementation
(
"androidx.work:work-runtime-ktx:2.7.1"
)
// 请使用最新版本
}
\ No newline at end of file
app/src/main/AndroidManifest.xml
View file @
33a08f5d
...
...
@@ -250,9 +250,15 @@
android:name=
"com.google.android.gms.ads.flag.NATIVE_AD_DEBUGGER_ENABLED"
android:value=
"false"
/>
<!-- 常驻通知栏 -->
<!-- <service-->
<!-- android:name=".service.StayNotificationService"-->
<!-- android:foregroundServiceType="dataSync" />-->
<service
android:name=
".service.StayNotificationService"
android:foregroundServiceType=
"dataSync"
/>
android:name=
".service.StayJobService"
android:exported=
"false"
android:foregroundServiceType=
"dataSync"
android:permission=
"android.permission.BIND_JOB_SERVICE"
/>
<service
android:name=
".fcm.MessagingService"
android:exported=
"true"
>
...
...
app/src/main/java/com/base/filerecoveryrecyclebin/MyApplication.kt
View file @
33a08f5d
...
...
@@ -18,6 +18,7 @@ import com.base.filerecoveryrecyclebin.utils.ActivityManagerUtils
import
com.base.filerecoveryrecyclebin.utils.AppPreferences
import
com.base.filerecoveryrecyclebin.help.InstallHelps
import
com.base.filerecoveryrecyclebin.utils.LogEx
import
com.base.filerecoveryrecyclebin.work.schedulePeriodicWork
import
com.facebook.FacebookSdk
import
com.google.android.gms.ads.identifier.AdvertisingIdClient
import
kotlinx.coroutines.Dispatchers
...
...
@@ -72,6 +73,7 @@ class MyApplication : BaseApplication() {
InstallHelps
.
init
()
BlackUtils
.
requestBlack
()
initLifeListener
()
schedulePeriodicWork
(
this
)
}
if
(
ifAgreePrivacy
)
{
...
...
app/src/main/java/com/base/filerecoveryrecyclebin/fcm/FCMManager.kt
View file @
33a08f5d
package
com.base.filerecoveryrecyclebin.fcm
;
package
com.base.filerecoveryrecyclebin.fcm
import
android.content.Context;
import
android.util.Log;
import
android.content.Context
import
android.util.Log
import
com.base.filerecoveryrecyclebin.utils.AppPreferences
import
com.base.filerecoveryrecyclebin.utils.EventUtils
import
com.base.filerecoveryrecyclebin.utils.EventUtils.event
import
com.base.filerecoveryrecyclebin.utils.LogEx
import
com.google.android.gms.tasks.OnCompleteListener
import
com.google.android.gms.tasks.Task
import
com.google.firebase.FirebaseApp
import
com.google.firebase.messaging.FirebaseMessaging
import
org.json.JSONObject
import
androidx.annotation.NonNull;
import
com.base.filerecoveryrecyclebin.utils.EventUtils;
import
com.google.android.gms.tasks.OnCompleteListener;
import
com.google.android.gms.tasks.Task;
import
com.google.firebase.FirebaseApp;
import
com.google.firebase.messaging.FirebaseMessaging;
public
class
FCMManager
{
public
static
void
initFirebase
(
Context
context
)
{
FirebaseApp
.
initializeApp
(
context
);
object
FCMManager
{
fun
initFirebase
(
context
:
Context
?)
{
FirebaseApp
.
initializeApp
(
context
!!
)
getToken
()
}
public
static
void
subscribeToTopic
(
String
topic
)
{
fun
subscribeToTopic
(
topic
:
String
)
{
FirebaseMessaging
.
getInstance
().
subscribeToTopic
(
topic
)
.
addOnCompleteListener
(
new
OnCompleteListener
<
Void
>()
{
@Override
public
void
onComplete
(
@NonNull
Task
<
Void
>
task
)
{
if
(
task
.
isSuccessful
())
{
Log
.
d
(
"FCMUtil"
,
"suc:"
+
topic
);
EventUtils
.
INSTANCE
.
event
(
"FCM_Topic_"
+
topic
,
null
,
null
,
false
);
.
addOnCompleteListener
{
task
->
if
(
task
.
isSuccessful
)
{
getToken
()
Log
.
d
(
"FCMUtil"
,
"suc:$topic"
)
event
(
"FCM_Topic_$topic"
,
null
,
null
,
false
)
}
else
{
Log
.
d
(
"FCMUtil"
,
"fail"
);
Log
.
d
(
"FCMUtil"
,
"fail"
)
}
}
});
}
public
static
void
unsubscribeFromTopic
(
String
topic
)
{
FirebaseMessaging
.
getInstance
().
unsubscribeFromTopic
(
topic
)
.
addOnCompleteListener
(
new
OnCompleteListener
<
Void
>()
{
@Override
public
void
onComplete
(
@NonNull
Task
<
Void
>
task
)
{
if
(
task
.
isSuccessful
())
{
fun
unsubscribeFromTopic
(
topic
:
String
?)
{
FirebaseMessaging
.
getInstance
().
unsubscribeFromTopic
(
topic
!!
)
.
addOnCompleteListener
{
task
->
if
(
task
.
isSuccessful
)
{
}
else
{
}
}
});
}
fun
getToken
()
{
FirebaseMessaging
.
getInstance
().
token
.
addOnCompleteListener
(
object
:
OnCompleteListener
<
String
>
{
override
fun
onComplete
(
task
:
Task
<
String
>)
{
LogEx
.
logDebug
(
"FCM"
,
"onComplete ${task.isSuccessful}"
)
if
(!
task
.
isSuccessful
)
{
Log
.
e
(
"FCM"
,
"Fetching FCM registration token failed"
,
task
.
exception
)
return
}
// Get new FCM registration token
val
token
:
String
=
task
.
result
LogEx
.
logDebug
(
"FCM"
,
"token=$token"
)
val
json
=
JSONObject
()
json
.
put
(
"token"
,
token
)
EventUtils
.
event
(
"fcm_message_received"
,
ext
=
json
)
AppPreferences
.
getInstance
().
put
(
"token"
,
token
)
// Handle new token
Log
.
d
(
"FCM"
,
"FCM Registration Token: $token"
)
}
})
}
}
app/src/main/java/com/base/filerecoveryrecyclebin/service/StayJobService.kt
0 → 100644
View file @
33a08f5d
package
com.base.filerecoveryrecyclebin.service
import
android.app.Notification
import
android.app.NotificationChannel
import
android.app.NotificationManager
import
android.app.PendingIntent
import
android.app.job.JobInfo
import
android.app.job.JobParameters
import
android.app.job.JobScheduler
import
android.app.job.JobService
import
android.content.ComponentName
import
android.content.Context
import
android.content.Intent
import
android.content.pm.ServiceInfo
import
android.graphics.BitmapFactory
import
android.graphics.drawable.Icon
import
android.os.Build
import
android.os.CountDownTimer
import
android.widget.RemoteViews
import
androidx.core.app.NotificationCompat
import
androidx.core.graphics.drawable.IconCompat
import
androidx.work.Configuration
import
com.base.filerecoveryrecyclebin.R
import
com.base.filerecoveryrecyclebin.activity.MainActivity
import
com.base.filerecoveryrecyclebin.utils.LogEx
/**
* 常驻通知栏
*/
class
StayJobService
:
JobService
()
{
init
{
val
builder
=
Configuration
.
Builder
()
builder
.
setJobSchedulerJobIdRange
(
0
,
1000
)
}
private
val
TAG
=
"StayJobService"
val
channelName
=
"Photo Recovery Foreground Service Channel"
val
channelId
=
"Photo_Recovery_Service_Id"
private
val
NOTIFICATION_PERMANENT_ID
=
199
companion
object
{
var
isRunning
=
false
private
const
val
JOB_INFO_ID
:
Int
=
101
private
const
val
JOB_PERIODIC
:
Long
=
5
*
1000L
fun
Context
.
startJob
()
{
if
(
isRunning
)
return
val
jobScheduler
=
getSystemService
(
JOB_SCHEDULER_SERVICE
)
as
JobScheduler
val
componentName
=
ComponentName
(
this
,
StayJobService
::
class
.
java
)
val
jobInfo
=
JobInfo
.
Builder
(
JOB_INFO_ID
,
componentName
)
.
setMinimumLatency
(
30000
)
.
build
()
jobScheduler
.
schedule
(
jobInfo
)
}
fun
createPermanentNotification
(
context
:
Context
):
Notification
{
val
channelName
=
"Permanent Foreground Service Channel"
val
channelId
=
"permanent_channel"
val
contentView
=
RemoteViews
(
context
.
packageName
,
R
.
layout
.
stay_notification_big
)
val
expendView
=
RemoteViews
(
context
.
packageName
,
R
.
layout
.
stay_notification_big
)
val
builder
=
NotificationCompat
.
Builder
(
context
,
channelId
)
val
smallIcon
=
IconCompat
.
createFromIcon
(
context
,
Icon
.
createWithResource
(
context
,
R
.
mipmap
.
logo
)
)
smallIcon
?.
let
{
builder
.
setSmallIcon
(
smallIcon
)
//设置状态栏内的小图标
}
val
nfIntent
=
Intent
(
context
,
MainActivity
::
class
.
java
)
val
pendingIntent
=
PendingIntent
.
getActivity
(
context
,
0
,
nfIntent
,
PendingIntent
.
FLAG_IMMUTABLE
)
builder
.
setLargeIcon
(
BitmapFactory
.
decodeResource
(
context
.
resources
,
R
.
mipmap
.
logo
)
)
builder
.
setContentTitle
(
context
.
resources
.
getString
(
R
.
string
.
app_name
))
builder
.
setContentIntent
(
pendingIntent
)
//设置PendingIntent
builder
.
setVisibility
(
NotificationCompat
.
VISIBILITY_PRIVATE
)
//设置通知公开可见
builder
.
setAutoCancel
(
false
)
builder
.
setOngoing
(
true
)
builder
.
setPriority
(
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
()
}
}
override
fun
onStartCommand
(
intent
:
Intent
?,
flags
:
Int
,
startId
:
Int
):
Int
{
if
(
fileObserver
==
null
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
Q
)
{
fileObserver
=
FileObserverExample
()
fileObserver
?.
startObserving
()
}
}
return
super
.
onStartCommand
(
intent
,
flags
,
startId
)
}
private
fun
startForeground
()
{
val
notification
=
createPermanentNotification
(
applicationContext
)
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
Q
)
{
startForeground
(
NOTIFICATION_PERMANENT_ID
,
notification
,
ServiceInfo
.
FOREGROUND_SERVICE_TYPE_DATA_SYNC
)
}
else
{
startForeground
(
NOTIFICATION_PERMANENT_ID
,
notification
)
}
isRunning
=
true
}
private
fun
notifyForeground
()
{
val
notificationManager
=
getSystemService
(
Context
.
NOTIFICATION_SERVICE
)
as
NotificationManager
notificationManager
.
notify
(
NOTIFICATION_PERMANENT_ID
,
createPermanentNotification
(
applicationContext
)
)
}
override
fun
onDestroy
()
{
isRunning
=
false
super
.
onDestroy
()
fileObserver
?.
stopObserving
()
}
override
fun
onCreate
()
{
LogEx
.
logDebug
(
TAG
,
"onCreate isRunning=$isRunning"
)
if
(!
isRunning
)
{
isRunning
=
true
startForeground
()
Timer
().
start
()
}
super
.
onCreate
()
}
override
fun
onStartJob
(
params
:
JobParameters
?):
Boolean
{
return
true
}
override
fun
onStopJob
(
params
:
JobParameters
?):
Boolean
{
return
false
}
private
inner
class
Timer
()
:
CountDownTimer
(
30000
,
1000
)
{
override
fun
onTick
(
millisUntilFinished
:
Long
)
{
}
override
fun
onFinish
()
{
notifyForeground
()
Timer
().
start
()
}
}
private
var
fileObserver
:
FileObserverExample
?
=
null
}
app/src/main/java/com/base/filerecoveryrecyclebin/work/RepeatingWorker.kt
0 → 100644
View file @
33a08f5d
package
com.base.filerecoveryrecyclebin.work
import
android.content.Context
import
androidx.work.Constraints
import
androidx.work.ExistingPeriodicWorkPolicy
import
androidx.work.NetworkType
import
androidx.work.PeriodicWorkRequestBuilder
import
androidx.work.WorkManager
import
androidx.work.Worker
import
androidx.work.WorkerParameters
import
com.base.filerecoveryrecyclebin.fcm.NotificationUtil
import
com.base.filerecoveryrecyclebin.utils.EventUtils
import
java.util.concurrent.TimeUnit
fun
schedulePeriodicWork
(
context
:
Context
)
{
val
request
=
PeriodicWorkRequestBuilder
<
RepeatingWorker
>(
15
,
TimeUnit
.
MINUTES
)
.
setConstraints
(
Constraints
.
Builder
().
setRequiredNetworkType
(
NetworkType
.
CONNECTED
).
build
()
)
.
build
()
WorkManager
.
getInstance
(
context
).
enqueueUniquePeriodicWork
(
"uniqueWorkName"
,
ExistingPeriodicWorkPolicy
.
KEEP
,
request
)
}
class
RepeatingWorker
(
val
appContext
:
Context
,
workerParams
:
WorkerParameters
)
:
Worker
(
appContext
,
workerParams
)
{
override
fun
doWork
():
Result
{
// 这里执行你的任务
// 例如,更新UI,发送网络请求等
EventUtils
.
event
(
"workmanager_live"
)
try
{
NotificationUtil
.
sendNotification
(
appContext
,
"WorkManager"
);
}
catch
(
e
:
Exception
)
{
EventUtils
.
event
(
"WorkManager Error"
)
}
return
Result
.
success
()
}
}
\ No newline at end of file
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