Commit d96b2308 authored by wanglei's avatar wanglei

...

parent 80da34d2
......@@ -3,34 +3,11 @@
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<!-- fcm 添加以下权限 -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission
android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
<queries>
<intent>
<action android:name="android.intent.action.MAIN" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
</intent>
</queries>
<application
android:name=".MyApplication"
android:allowBackup="true"
......@@ -75,12 +52,7 @@
android:launchMode="singleTop"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".activity.DeviceScanInfoActivity"
android:exported="false"
android:launchMode="singleTop"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".activity.SettingActivity"
android:exported="false"
......@@ -95,28 +67,6 @@
android:name=".activity.PrepareScanActivity"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".activity.RecentAppActivity"
android:exported="true"
android:launchMode="singleTop"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".activity.PermissionManagerActivity"
android:exported="false"
android:launchMode="singleTop"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".activity.AppManagerActivity"
android:exported="false"
android:screenOrientation="portrait"
android:theme="@style/Theme.clean"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".activity.BatteryInfoActivity"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".activity.ScanJunkActivity"
......@@ -141,14 +91,8 @@
android:launchMode="singleTop"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".notificationclean.NotificationGuestActivity"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".notificationclean.NotificationCleanActivity"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".activity.ResultActivity"
android:screenOrientation="portrait"
......@@ -157,10 +101,7 @@
android:name=".activity.RepeatPhotoActivity"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".activity.NetWorkActivity"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".activity.PrivacyWebActivity"
android:screenOrientation="portrait"
......@@ -178,39 +119,9 @@
<meta-data
android:name="com.google.android.gms.ads.flag.NATIVE_AD_DEBUGGER_ENABLED"
android:value="false" />
<service
android:name=".display.fcm.MyFirebaseMessagingService"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<!-- 注册广播 -->
<receiver
android:name=".display.fcm.MyFirebaseMessagingReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.test.fast.cleanerjunk" />
</intent-filter>
</receiver>
<service
android:name=".display.NotificationService"
android:permission="android.permission.FOREGROUND_SERVICE" />
<service
android:name=".notificationclean.AppNotificationListenerService"
android:exported="true"
android:label="AppNotification service"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
<service
android:name=".service.FlashlightService"
android:exported="true"
......
......@@ -11,7 +11,6 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.view.isVisible
import com.test.easy.easycleanerjunk.databinding.ActivityLayoutSplashBinding
import com.test.easy.easycleanerjunk.display.CloseNotificationReceiver
import com.test.easy.easycleanerjunk.display.NotificationHelper
import com.test.easy.easycleanerjunk.display.NotificationService
import com.test.easy.easycleanerjunk.helps.BaseActivity
import com.test.easy.easycleanerjunk.helps.ConfigHelper
......
......@@ -16,7 +16,6 @@ import com.test.easy.easycleanerjunk.bean.ConfigBean.Companion.ID_PHOTO_COMPRESS
import com.test.easy.easycleanerjunk.bean.ConfigBean.Companion.ID_SCREENSHOT_CLEAN
import com.test.easy.easycleanerjunk.bean.ConfigBean.Companion.ID_SIMILAR_IMAGE
import com.test.easy.easycleanerjunk.helps.ConfigHelper
import com.test.easy.easycleanerjunk.notificationclean.NotificationGuestActivity
object SplashJumpUtils {
......
package com.test.easy.easycleanerjunk.adapter
import android.annotation.SuppressLint
import android.text.format.Formatter
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.test.easy.easycleanerjunk.R
import com.test.easy.easycleanerjunk.bean.AppBean
import com.test.easy.easycleanerjunk.databinding.ItemAppListBinding
import com.test.easy.easycleanerjunk.view.XmlEx.inflate
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
class AppListAdapter(
val itemClick: (data: AppBean) -> Unit, val itemSelect: ((selectList: List<AppBean>) -> Unit)? = null
) : RecyclerView.Adapter<AppListAdapter.AAAA>() {
private var list = arrayListOf<AppBean>()
inner class AAAA(view: View) : ViewHolder(view) {
val binding = ItemAppListBinding.bind(view)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AAAA {
return AAAA(R.layout.item_app_list.inflate(parent))
}
override fun getItemCount(): Int {
return list.size
}
@SuppressLint("SimpleDateFormat")
override fun onBindViewHolder(holder: AAAA, position: Int) {
}
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: AAAA, position: Int, payloads: MutableList<Any>) {
val data = list[position]
val context = holder.itemView.context
if (payloads.isEmpty()) {
holder.binding.tvAppName.text = data.appName
holder.binding.ivIcon.setImageDrawable(data.icIcon)
val dateFormat = SimpleDateFormat("MM dd", Locale.ENGLISH)
val installTimeDate = Date(data.installTime)
val installTime = String.format("%tb", installTimeDate) + " " + String.format("%te", installTimeDate)
holder.binding.tvAppInstall.text = "Installed: $installTime"
if (data.appSize == -1L) {
holder.binding.tvAppSize.text = "Size used: need permission"
} else {
val size = Formatter.formatFileSize(context, data.appSize)
holder.binding.tvAppSize.text = "Size used: $size"
}
when (data.lastUsedTime) {
-1L -> {
holder.binding.tvAppLastUse.text = "Last use: need permission"
}
-2L -> {
holder.binding.tvAppLastUse.text = "Last use: more 30 days no use"
}
else -> {
// val lastTime = dateFormat.format(data.lastUsedTime)
val lastTimeDate = Date(data.lastUsedTime)
val lastTime = String.format("%tb", lastTimeDate) + " " + String.format("%te", lastTimeDate)
holder.binding.tvAppLastUse.text = "Last use: $lastTime"
}
}
holder.binding.ivSelector.isSelected = data.isSelected
holder.binding.ivSelector.setOnClickListener {
data.isSelected = !data.isSelected
holder.binding.ivSelector.isSelected = data.isSelected
notifyItemChanged(position, "sdadd")
val selectedList = list.filter { it.isSelected }
itemSelect?.invoke(selectedList)
}
holder.binding.root.setOnClickListener {
itemClick.invoke(data)
}
} else {
holder.binding.ivSelector.isSelected = data.isSelected
super.onBindViewHolder(holder, position, payloads)
}
}
@SuppressLint("NotifyDataSetChanged")
fun setData(dataList: List<AppBean>) {
list.clear()
list.addAll(dataList)
notifyDataSetChanged()
}
fun removeData(appBean: AppBean) {
list.remove(appBean)
notifyDataSetChanged()
}
}
\ No newline at end of file
package com.test.easy.easycleanerjunk.adapter
import android.annotation.SuppressLint
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.test.easy.easycleanerjunk.R
import com.test.easy.easycleanerjunk.bean.PermissionBean
import com.test.easy.easycleanerjunk.databinding.ItemPermissionBinding
import com.test.easy.easycleanerjunk.view.XmlEx.inflate
class PermissionAdapter : RecyclerView.Adapter<PermissionAdapter.CCCC>() {
private val permissionBeans = arrayListOf<PermissionBean>()
inner class CCCC(view: View) : ViewHolder(view) {
val binding = ItemPermissionBinding.bind(view)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CCCC {
return CCCC(R.layout.item_permission.inflate(parent))
}
override fun getItemCount(): Int {
return permissionBeans.size
}
override fun onBindViewHolder(holder: CCCC, position: Int) {
val context = holder.itemView.context
val data = permissionBeans[position]
holder.binding.tvTitle.text = context.getString(data.permissionTittle)
holder.binding.tvDesc.text = context.getString(data.permissionDesc)
if (data.isAuthorized) {
holder.binding.tvAuthorized.visibility = View.VISIBLE
if (data.isSensitive) {
holder.binding.tvAuthorized.background = ContextCompat.getDrawable(context, R.drawable.bg_corners_granted)
holder.binding.tvAuthorized.setTextColor(ContextCompat.getColor(context, R.color.color_fcad45))
} else {
holder.binding.tvAuthorized.background = ContextCompat.getDrawable(context, R.drawable.bg_corners_d9e2fd)
holder.binding.tvAuthorized.setTextColor(ContextCompat.getColor(context, R.color.theme_color))
}
} else {
holder.binding.tvAuthorized.visibility = View.GONE
}
}
@SuppressLint("NotifyDataSetChanged")
fun setData(permissions: List<PermissionBean>) {
permissionBeans.clear()
permissionBeans.addAll(permissions)
notifyDataSetChanged()
}
}
\ No newline at end of file
package com.test.easy.easycleanerjunk.adapter
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.provider.Settings
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.test.easy.easycleanerjunk.R
import com.test.easy.easycleanerjunk.bean.AppBean
import com.test.easy.easycleanerjunk.databinding.ItemAppRecentBinding
import com.test.easy.easycleanerjunk.databinding.ItemAppScreenTimeBinding
import com.test.easy.easycleanerjunk.helps.NetworkStatsHelper
import com.test.easy.easycleanerjunk.helps.TimeUtils
import com.test.easy.easycleanerjunk.view.XmlEx.inflate
class RecentAppAdapter(val activity: Activity, val modeUI: String = UI_LAUNCHES_MODE) : RecyclerView.Adapter<RecentAppAdapter.DDD>() {
private var appBeans = arrayListOf<AppBean>()
private var numberMode = UI_MODE_ALL
inner class DDD(view: View) : ViewHolder(view)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DDD {
return if (modeUI == UI_LAUNCHES_MODE) {
DDD(R.layout.item_app_recent.inflate(parent))
} else {
DDD(R.layout.item_app_screen_time.inflate(parent))
}
}
override fun getItemCount(): Int {
return appBeans.size
}
@SuppressLint("StringFormatMatches", "SetTextI18n")
override fun onBindViewHolder(holder: DDD, position: Int) {
val context = holder.itemView.context
val data = appBeans[position]
if (modeUI == UI_LAUNCHES_MODE) {
val binding = ItemAppRecentBinding.bind(holder.itemView)
binding.ivIcon.setImageDrawable(data.icIcon)
binding.tvName.text = data.appName
val number = when (numberMode) {
UI_MODE_ALL -> data.launchTimes
UI_MODE_FOREGROUND -> data.foregroundTimes
UI_MODE_BACKGROUND -> data.backgroundTimes
else -> 0
}
binding.tvNumber.text = "$number Launches"
binding.tvStop.background = if (data.isRunning) {
ContextCompat.getDrawable(context, R.drawable.bg_corners_4772ff)
} else {
ContextCompat.getDrawable(context, R.drawable.bg_corners_bfbfbf)
}
binding.tvStop.setOnClickListener {
if (NetworkStatsHelper.canStop(activity, data.pkg)) {
// 跳转到当前应用的应用信息界面
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
// 如果要跳转到其他应用的应用信息界面,需要传入那个应用的包名
intent.setData(Uri.parse("package:${data.pkg}"))
context.startActivity(intent)
}
}
val bg = if (NetworkStatsHelper.canStop(activity, data.pkg)) {
R.drawable.bg_corners_4772ff
} else {
R.drawable.bg_corners_bfbfbf
}
binding.tvStop.background = ContextCompat.getDrawable(context, bg)
}
if (modeUI == UI_SCREEN_TIME_MODE) {
val binding = ItemAppScreenTimeBinding.bind(holder.itemView)
binding.ivIcon.setImageDrawable(data.icIcon)
binding.tvName.text = data.appName
binding.tvManage.setOnClickListener {
// 跳转到当前应用的应用信息界面
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
// 如果要跳转到其他应用的应用信息界面,需要传入那个应用的包名
intent.setData(Uri.parse("package:${data.pkg}"))
context.startActivity(intent)
}
binding.tvTime.text = TimeUtils.longToHoursAndMinutes(data.screenTime)
val max = appBeans.maxOf { it.screenTime }
binding.progressBar.progress = ((data.screenTime.toFloat() / max.toFloat()) * 100).toInt()
}
}
fun setNumberMode(mode: Int) {
numberMode = mode
}
@SuppressLint("NotifyDataSetChanged")
fun setData(dataList: List<AppBean>) {
appBeans.clear()
appBeans.addAll(dataList)
if (modeUI == UI_LAUNCHES_MODE) {
when (numberMode) {
UI_MODE_ALL -> appBeans.sortByDescending { it.launchTimes }
UI_MODE_FOREGROUND -> appBeans.sortByDescending { it.foregroundTimes }
UI_MODE_BACKGROUND -> appBeans.sortByDescending { it.backgroundTimes }
}
} else {
appBeans.sortByDescending { it.screenTime }
}
notifyDataSetChanged()
}
companion object {
const val UI_MODE_ALL = 5
const val UI_MODE_FOREGROUND = 25
const val UI_MODE_BACKGROUND = 35
const val UI_LAUNCHES_MODE = "LAUNCHES_UI"
const val UI_SCREEN_TIME_MODE = "SCREEN_TIME_UI"
}
}
\ No newline at end of file
package com.test.easy.easycleanerjunk.display
import android.annotation.SuppressLint
import android.app.PendingIntent
import android.app.PendingIntent.FLAG_MUTABLE
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.widget.RemoteViews
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.test.easy.easycleanerjunk.R
import com.test.easy.easycleanerjunk.activity.splash.NewSplashActivity
import com.test.easy.easycleanerjunk.bean.ConfigBean.Companion.ID_APP_MANAGER
import com.test.easy.easycleanerjunk.bean.ConfigBean.Companion.ID_JUNK_CLEAN_PUSH
import com.test.easy.easycleanerjunk.bean.ConfigBean.Companion.ID_LARGE_FILE_PUSH
import com.test.easy.easycleanerjunk.bean.ConfigBean.Companion.ID_PHOTO_COMPRESS
import com.test.easy.easycleanerjunk.bean.ConfigBean.Companion.ID_SCREENSHOT_CLEAN
import com.test.easy.easycleanerjunk.bean.ConfigBean.Companion.ID_SIMILAR_IMAGE
import com.test.easy.easycleanerjunk.helps.BaseApplication
import com.test.easy.easycleanerjunk.helps.ComUtils
import com.test.easy.easycleanerjunk.utils.SPUtils
import kotlin.random.Random
/**
* 推送的帮助类
*/
object NotificationHelper {
private val TAG = "NotificationHelper"
val notificationId = 19086
/**
* 当前APP支持的通知类型
*/
val supportNotification = arrayListOf(
ID_JUNK_CLEAN_PUSH,
ID_LARGE_FILE_PUSH,
ID_PHOTO_COMPRESS,
ID_APP_MANAGER,
ID_SIMILAR_IMAGE,
)
/**
* 过滤可推送actionId
*/
fun filterAction(pushCircleOrder: List<Int>): ArrayList<Int> {
//过滤已有功能
val filterList = arrayListOf<Int>()
pushCircleOrder.forEach { action ->
if (supportNotification.contains(action)) {
filterList.add(action)
}
}
return filterList
}
/**
* 获取当前的推送id
*/
fun getPresentPushId(): Int {
val pushCircleOrder = supportNotification
Log.d(TAG, "push_circle_order=$pushCircleOrder")
val tempList = arrayListOf<Int>()
val json = SPUtils.getInstance().getString("push_circle_order", "")
if ((json == "") or (json == "null")) {//初始化
val filterList = filterAction(pushCircleOrder)
val initJson = Gson().toJson(filterList)
SPUtils.getInstance().getString("push_circle_order", initJson)
tempList.addAll(filterList)
} else {
var array = emptyArray<Int>()
try {
array = Gson().fromJson(json, object : TypeToken<Array<Int>>() {})
} catch (e: Exception) {
Log.e("getPresentPushId", "gson error")
}
tempList.addAll(array)
if (tempList.isEmpty()) {
val filterList = filterAction(pushCircleOrder)
val saveJson = Gson().toJson(filterList)
SPUtils.getInstance().put("push_circle_order", saveJson)
tempList.addAll(filterList)
}
}
val i = tempList[0]
tempList.remove(i)
val usedJson = Gson().toJson(tempList)
SPUtils.getInstance().put("push_circle_order", usedJson)
return i
}
/**
* 发送通知对于
* @param extra 额外参数
*/
@SuppressLint("RemoteViewLayout")
fun Context.postActionNotification(actionId: Int, extra: Int? = null, pushStayTime: Long? = null) {
val remoteViews = RemoteViews(packageName, R.layout.notification_common_notify)
when (actionId) {
ID_JUNK_CLEAN_PUSH -> {
remoteViews.setImageViewResource(R.id.iv_icon, R.mipmap.t_cleanjunk)
remoteViews.setTextViewText(R.id.tv_desc, "Clean up remaining junk files")
remoteViews.setTextViewText(R.id.tv_btn, "Clean up")
}
ID_LARGE_FILE_PUSH -> {
remoteViews.setImageViewResource(R.id.iv_icon, R.mipmap.t_large)
remoteViews.setTextViewText(R.id.tv_desc, "Clean big files to free up storage space")
remoteViews.setTextViewText(R.id.tv_btn, "Clean up")
}
ID_PHOTO_COMPRESS -> {
remoteViews.setImageViewResource(R.id.iv_icon, R.mipmap.t_photo)
remoteViews.setTextViewText(R.id.tv_desc, "Compress images to release more space")
remoteViews.setTextViewText(R.id.tv_btn, "Compress")
}
ID_APP_MANAGER -> {
remoteViews.setImageViewResource(R.id.iv_icon, R.mipmap.t_appmanager)
remoteViews.setTextViewText(R.id.tv_desc, "Check apps size and uninstall junk apps to release storage space")
remoteViews.setTextViewText(R.id.tv_btn, "Manage")
}
ID_SIMILAR_IMAGE -> {
remoteViews.setImageViewResource(R.id.iv_icon, R.mipmap.t_similar)
remoteViews.setTextViewText(R.id.tv_desc, "Check similar photos to release more space")
remoteViews.setTextViewText(R.id.tv_btn, "Clean up")
}
ID_SCREENSHOT_CLEAN -> {
remoteViews.setImageViewResource(R.id.iv_icon, R.mipmap.screenshot)
remoteViews.setTextViewText(R.id.tv_desc, "Detected lots of screenshots? Free up your storage space now!")
remoteViews.setTextViewText(R.id.tv_btn, "Clean up")
}
//==================================下面是被动推送的情况===============================================
else -> {
return
}
}
val flag = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) FLAG_MUTABLE else FLAG_UPDATE_CURRENT
//cancel事件,经过测试Intent.action这里无法传递参数
val cancelIntent = Intent(this, CloseNotificationReceiver::class.java)
val cancelRequestCode = Random.nextInt(0, 1000)
val cancelPendingIntent = PendingIntent.getBroadcast(BaseApplication.context, cancelRequestCode, cancelIntent, flag)
remoteViews.setOnClickPendingIntent(R.id.fl_cancel, cancelPendingIntent)
val intent = Intent(applicationContext, NewSplashActivity::class.java)
val title: String = ""
val desc: String = ""
intent.putExtra("title", title)
intent.putExtra("desc", desc)
val customKey = "type"
intent.putExtra(customKey, actionId)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
val bundle = Bundle()
bundle.putInt(customKey, actionId)
intent.putExtras(bundle)
val uri =
Uri.parse("cleanapp://com.test.fast.cleanerjunk/com.test.fast.cleanerjunk.activity.splash.NewSplashActivity?type=$actionId")
intent.data = uri
// intent.data = Uri.parse("myapp://splash?type=$actionId")
//按钮事件
val btnRequestCode = Random.nextInt(0, 1000)
val btnPendingIntent = PendingIntent.getActivity(BaseApplication.context, btnRequestCode, intent, flag)
remoteViews.setOnClickPendingIntent(R.id.fl_btn, btnPendingIntent)
//每种类型保存值
SPUtils.getInstance().put(actionId.toString(), System.currentTimeMillis())
//大间隔所需值
SPUtils.getInstance().put("all_last_push_time", System.currentTimeMillis())
val requestCode = Random.nextInt(0, 1000)
val pendingIntent = PendingIntent.getActivity(applicationContext, requestCode, intent, FLAG_UPDATE_CURRENT or FLAG_MUTABLE)
NotificationUtils.showNotification(
applicationContext,
notificationId,
remoteViews,
R.id.fl_cancel,
pendingIntent,
pushStayTime ?: 0
)
}
}
......@@ -9,16 +9,12 @@ import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.Build
import android.service.notification.StatusBarNotification
import android.util.Log
import android.widget.RemoteViews
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.test.easy.easycleanerjunk.R
import com.test.easy.easycleanerjunk.activity.ScanJunkActivity
import com.test.easy.easycleanerjunk.activity.home.NewMainActivity
import com.test.easy.easycleanerjunk.display.NotificationHelper.postActionNotification
import com.test.easy.easycleanerjunk.helps.BaseApplication
import com.test.easy.easycleanerjunk.service.FlashlightService
......@@ -174,32 +170,4 @@ object NotificationUtils {
return notification
}
fun sendTimerPush(s: Long) {
Log.d(TAG, "sendTimerPush")
val id = NotificationHelper.getPresentPushId()
val isPush = PushStrategy.isPush(id)
val log = "isPush=$isPush " + "id=${id} "
Log.d(TAG, log)
if (isPush) {
BaseApplication.context.postActionNotification(id, null, s)
}
}
fun isNotificationExist(context: Context, notificationId: Int): Boolean {
// 获取 NotificationManagerCompat 实例
val notificationManager = NotificationManagerCompat.from(context)
// 获取当前活动的通知列表
val notifications: MutableList<StatusBarNotification> = notificationManager.activeNotifications
// 检查指定的通知是否在列表中
for (notification in notifications) {
if (notification.id == notificationId) {
return true
}
}
return false
}
}
......@@ -14,7 +14,6 @@ import com.test.easy.easycleanerjunk.activity.photocompress.photo.StartCompressi
import com.test.easy.easycleanerjunk.databinding.FragmentLayoutHomeBinding
import com.test.easy.easycleanerjunk.helps.BaseFragment
import com.test.easy.easycleanerjunk.helps.KotlinExt.setOnClickListener
import com.test.easy.easycleanerjunk.notificationclean.NotificationGuestActivity
import com.test.easy.easycleanerjunk.utils.BarUtils
class HomeFragment : BaseFragment<FragmentLayoutHomeBinding>() {
......
package com.test.easy.easycleanerjunk.notificationclean
import android.app.Notification
import android.service.notification.NotificationListenerService
import android.service.notification.StatusBarNotification
import android.util.Log
import com.test.easy.easycleanerjunk.helps.BaseApplication
import com.test.easy.easycleanerjunk.helps.ConfigHelper
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
class AppNotificationListenerService : NotificationListenerService() {
override fun onCreate() {
super.onCreate()
}
override fun onListenerConnected() {
super.onListenerConnected()
Log.e("MXL", "onListenerConnected: ")
ConfigHelper.isOpenNotification = true
}
override fun onNotificationPosted(sbn: StatusBarNotification) {
// 当通知被发布时调用
// 可以在这里获取通知的详细信息
val notification = sbn.notification
// 获取通知的标题和内容等
val extras = notification.extras
val title = extras.getCharSequence(Notification.EXTRA_TITLE)
val text = extras.getCharSequence(Notification.EXTRA_TEXT)
// 处理通知信息...
// Log.e("MXL", "onNotificationPosted: $extras")
// val data = NotificationData()
// data.packageName = sbn.packageName;
// data.notificationTitle = title.toString()
// data.notificationText = text.toString()
// db?.notificationDao()?.insert(data)
MainScope().launch(Dispatchers.IO) {
if (title?.isNotBlank() == true) {
HistoryDatabase.getInstance(BaseApplication.context)?.historyDao()?.insert(
NotificationData(
sbn.packageName,
title.toString(),
text.toString(),
System.currentTimeMillis()
)
)
}
}
//dbHelper.addContacts(NotifBean(null,null,"${title}","${text}",null,null))
}
override fun onNotificationRemoved(sbn: StatusBarNotification) {
// 当通知被移除时调用
}
}
\ No newline at end of file
package com.test.easy.easycleanerjunk.notificationclean
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(entities = [NotificationData::class], version = 1, exportSchema = false)
abstract class HistoryDatabase : RoomDatabase() {
abstract fun historyDao(): NotfiDao
companion object {
@Volatile
private var mInstance: HistoryDatabase? = null
private const val DATA_BASE_NAME = "notify_clean.db"
@JvmStatic
fun getInstance(context: Context): HistoryDatabase? {
if (mInstance == null) {
synchronized(HistoryDatabase::class.java) {
if (mInstance == null) {
mInstance = createInstance(context)
}
}
}
return mInstance
}
private fun createInstance(context: Context): HistoryDatabase {
return Room.databaseBuilder(
context.applicationContext,
HistoryDatabase::class.java,
DATA_BASE_NAME
).build()
}
}
}
\ No newline at end of file
package com.test.easy.easycleanerjunk.notificationclean
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
@Dao
interface NotfiDao {
@Query("SELECT * FROM Noticationt")
fun getAll(): LiveData<List<NotificationData>>
@Insert
fun insert(history: NotificationData)
@Delete
fun delete(it: NotificationData)
@Query("DELETE FROM Noticationt")
fun deleteAll()
}
\ No newline at end of file
package com.test.easy.easycleanerjunk.notificationclean
import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color
import android.provider.Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.activity.OnBackPressedCallback
import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.test.easy.easycleanerjunk.R
import com.test.easy.easycleanerjunk.databinding.ActivityLayoutTionCleanBinding
import com.test.easy.easycleanerjunk.helps.BaseActivity
import com.test.easy.easycleanerjunk.helps.ConfigHelper
import com.test.easy.easycleanerjunk.helps.KotlinExt.toFormatTime
import com.test.easy.easycleanerjunk.helps.LogEx
import com.test.easy.easycleanerjunk.helps.ads.AdmobUtils
import com.test.easy.easycleanerjunk.utils.BarUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import kotlin.random.Random
class NotificationCleanActivity : BaseActivity<ActivityLayoutTionCleanBinding>() {
private val TAG = "NotificationCleanActivity"
private val historyDao by lazy {
HistoryDatabase.getInstance(this)?.historyDao()
}
private val notificationList = mutableListOf<NotificationData>()
private var isRequest = 0
override val binding: ActivityLayoutTionCleanBinding by lazy {
ActivityLayoutTionCleanBinding.inflate(layoutInflater)
}
override fun initView() {
BarUtils.setStatusBarLightMode(this, true)
BarUtils.setStatusBarColor(this, Color.TRANSPARENT)
binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
binding.idGant.setOnClickListener {
val intent = Intent(ACTION_NOTIFICATION_LISTENER_SETTINGS)
launcher.launch(intent) {
LogEx.logDebug(TAG, "launcher callBack")
val serviceIntent = Intent(this, AppNotificationListenerService::class.java)
startService(serviceIntent)
if (ConfigHelper.isOpenNotification) {
binding.idNeedNotifcationPremison.isVisible = false
playAnimal()
} else {
finishToMain()
}
}
}
binding.idBackNotification.setOnClickListener {
onBackPressedDispatcher.onBackPressed()
}
onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
AdmobUtils.showInterstitialAd(this@NotificationCleanActivity) {
finishToMain()
}
}
})
binding.idTvCleanAllT.setOnClickListener {
AdmobUtils.showInterstitialAd(this) {
MainScope().launch(Dispatchers.IO) {
historyDao?.deleteAll()
}
mAdapter.notifyDataSetChanged()
showEmptyData()
}
}
historyDao?.getAll()?.observe(this) {
if (it.isNotEmpty()) {
binding.idNoNotification.isVisible = false
binding.idNotifyClean.isVisible = true
binding.idViewLine.isVisible = true
binding.idTvCleanAllT.isVisible = true
notificationList.clear()
notificationList.addAll(it)
binding.idNotifyClean.run {
layoutManager = LinearLayoutManager(this@NotificationCleanActivity)
adapter = mAdapter
mAdapter.notifyDataSetChanged()
}
} else {
showEmptyData()
}
}
if (ConfigHelper.isOpenNotification) {
val serviceIntent = Intent(this, AppNotificationListenerService::class.java)
startService(serviceIntent)
binding.idNeedNotifcationPremison.isVisible = false
playAnimal()
} else {
binding.idNeedNotifcationPremison.isVisible = true
}
}
override fun onStart() {
super.onStart()
// val intent = Intent(this, AppNotificationListenerService::class.java)
// startService(intent)
// binding.idNeedNotifcationPremison.isVisible = !ConfigHelper.isOpenNotification
// binding.idImgShezhi.isVisible = false
// if (ConfigHelper.isOpenNotification) {
// isRequest += 1
// playAnimal()
// }
}
private fun playAnimal() {
if (isRequest == 1) {
binding.idLlAnimation.isVisible = true
binding.root.postDelayed({
binding.idLlAnimation.isVisible = false
AdmobUtils.showInterstitialAd(this)
}, Random.nextLong(3000, 4500))
}
}
private fun showEmptyData() {
binding.idNotifyClean.isVisible = false
binding.idNoNotification.isVisible = true
binding.idViewLine.isVisible = false
binding.idTvCleanAllT.isVisible = false
}
override fun onDestroy() {
super.onDestroy()
binding.idAnimation?.clearAnimation()
}
private val mAdapter by lazy {
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val ivImage: ImageView
val tvTitle: TextView
val tvContent: TextView
val tvTime: TextView
val ivBig: ImageView
init {
ivImage = view.findViewById(R.id.id_t_icon)
tvTitle = view.findViewById(R.id.id_title)
tvContent = view.findViewById(R.id.id_content)
tvTime = view.findViewById(R.id.id_time)
ivBig = view.findViewById(R.id.id_big_img)
}
}
object : RecyclerView.Adapter<ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(this@NotificationCleanActivity).inflate(
R.layout.item_tion_cleaner, parent, false
)
return ViewHolder(view)
}
override fun getItemCount() = notificationList.size
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val c = ConfigHelper.appList?.firstOrNull {
it.packageName == notificationList[position].packageName
}
holder.ivImage.setImageDrawable(c?.icon)
if (notificationList[position].notificationText.isNotBlank()) {
holder.tvContent.visibility = View.VISIBLE
holder.tvContent.text = notificationList[position].notificationText
} else {
holder.tvContent.visibility = View.GONE
}
holder.tvTitle.text = notificationList[position].notificationTitle
holder.tvTime.text = notificationList[position].notificaonTime.toFormatTime()
holder.itemView.setOnClickListener {
MainScope().launch(Dispatchers.IO) {
historyDao?.delete(notificationList[position])
}
notifyDataSetChanged()
val intent =
packageManager.getLaunchIntentForPackage(notificationList[position].packageName)
if (intent != null) {
startActivity(intent)
}
}
}
override fun onBindViewHolder(
holder: ViewHolder,
position: Int,
payloads: MutableList<Any>
) {
super.onBindViewHolder(holder, position, payloads)
}
}
}
}
package com.test.easy.easycleanerjunk.notificationclean
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "Noticationt")
data class NotificationData(
@ColumnInfo
val packageName: String,
@ColumnInfo
var notificationTitle: String,
@ColumnInfo
val notificationText: String,
@ColumnInfo
val notificaonTime: Long,
@PrimaryKey(autoGenerate = true)
val id: Long = 0
)
\ No newline at end of file
package com.test.easy.easycleanerjunk.notificationclean
import android.content.Intent
import android.graphics.Color
import androidx.activity.OnBackPressedCallback
import androidx.core.view.updatePadding
import com.test.easy.easycleanerjunk.databinding.ActivityLayoutTionGuestBinding
import com.test.easy.easycleanerjunk.helps.BaseActivity
import com.test.easy.easycleanerjunk.helps.ads.AdmobUtils
import com.test.easy.easycleanerjunk.utils.BarUtils
import com.test.easy.easycleanerjunk.utils.SPUtils
import kotlin.random.Random
class NotificationGuestActivity : BaseActivity<ActivityLayoutTionGuestBinding>() {
override val binding: ActivityLayoutTionGuestBinding by lazy {
ActivityLayoutTionGuestBinding.inflate(layoutInflater)
}
override fun initView() {
BarUtils.setStatusBarLightMode(this, true)
BarUtils.setStatusBarColor(this, Color.TRANSPARENT)
binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
binding.idTzGuest.imageAssetsFolder = "easy_tz_scan/images/"
binding.idTzGuest.setAnimation("easy_tz_scan/data.json")
binding.idTzGuest.playAnimation()
SPUtils.getInstance().put("notification_guest", true)
binding.root.postDelayed({
AdmobUtils.showInterstitialAd(this) {
startActivity(Intent(this, NotificationCleanActivity::class.java))
finish()
}
}, Random.nextLong(2500, 4000))
binding.idTvTryNow.setOnClickListener {
startActivity(Intent(this, NotificationCleanActivity::class.java))
finish()
}
binding.idTGuanbi.setOnClickListener {
onBackPressedDispatcher.onBackPressed()
}
onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
AdmobUtils.showInterstitialAd(this@NotificationGuestActivity) {
finishToMain()
}
}
})
}
}
\ 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