Commit 33a08f5d authored by wanglei's avatar wanglei

...

parent 620a9401
......@@ -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
......@@ -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">
......
......@@ -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) {
......
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")
}
})
}
}
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
}
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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment