Commit 7e22f721 authored by mengcuiguang's avatar mengcuiguang

代码合并

parents 3ace952f 9adfd34d
......@@ -6,8 +6,10 @@ gradle.properties
/.idea
/.gradle
/build
#lib project
app/build
shareSdkLib/build
core/build
ktx/build
......
......@@ -54,17 +54,17 @@ android {
// 签名配置
signingConfigs {
debug {
// storeFile file(RELEASE_STORE_FILE)
// storePassword RELEASE_STORE_PASSWORD
// keyAlias RELEASE_KEY_ALIAS
// keyPassword RELEASE_KEY_PASSWORD
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
}
release {
// storeFile file(RELEASE_STORE_FILE)
// storePassword RELEASE_STORE_PASSWORD
// keyAlias RELEASE_KEY_ALIAS
// keyPassword RELEASE_KEY_PASSWORD
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
}
}
......@@ -78,7 +78,7 @@ android {
//混淆
minifyEnabled false
zipAlignEnabled false
shrinkResources false//打开
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
......@@ -93,7 +93,7 @@ android {
//混淆
minifyEnabled true
zipAlignEnabled true
shrinkResources true//打开
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
......@@ -111,7 +111,6 @@ android {
// 多渠道打包
productFlavors {
cleaner {}
cleanerpkg {}
}
......@@ -119,8 +118,14 @@ android {
flavor -> flavor.manifestPlaceholders = [CHANNEL_NAME_VALUE: name]
}
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [CHANNEL_NAME_VALUE: name]
// 自定义输出配置
applicationVariants.all { variant ->
variant.outputs.all { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
outputFileName = "${variant.productFlavors[0].name}_${defaultConfig.versionName}.apk"
}
}
}
repositories {
......@@ -150,8 +155,6 @@ dependencies {
implementation Deps.material
implementation Deps.circleimageview
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
debugImplementation Deps.leakCanary
......@@ -159,6 +162,7 @@ dependencies {
implementation Deps.banner
implementation Deps.glide
kapt Deps.glide_compiler
implementation Deps.photoView
implementation Deps.livedata_ktx
implementation Deps.viewPager2
......@@ -168,6 +172,8 @@ dependencies {
implementation Deps.koin_androidx_viewmodel
implementation Deps.grandcentrix_sharedPreference
implementation Deps.permissionx
implementation Deps.android_processes
// BASE64Decoder
implementation files('libs/sun.misc.BASE64Decoder.jar')
......
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
# By default, the flags in this file are appended to flags specified
# in /Users/mengcuiguang/Documents/softwareDevelopment/android-sdk-macosx/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
......@@ -12,10 +16,285 @@
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
#指定代码的压缩级别
-optimizationpasses 5
#包明不混合大小写
-dontusemixedcaseclassnames
#不去忽略非公共的库类
-dontskipnonpubliclibraryclasses
#优化 不优化输入的类文件
-dontoptimize
#预校验
-dontpreverify
#混淆时是否记录日志
-verbose
# 混淆时所采用的算法
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
#保护注解
-keepattributes *Annotation*
#保护内部类 保护反射
-keepattributes Exceptions, Signature, InnerClasses ,EnclosingMethod
# 保持哪些类不被混淆
-keep public class * extends android.app.Fragment
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.data.BroadcastReceiver
-keep public class * extends android.data.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
#如果有引用v4包可以添加下面这行
-keep public class * extends android.support.v4.app.Fragment
#忽略警告
-ignorewarnings
##记录生成的日志数据,gradle build时在本项目根目录输出##
#apk 包内所有 class 的内部结构
-dump class_files.txt
#未混淆的类和成员
-printseeds seeds.txt
#列出从 apk 中删除的代码
-printusage unused.txt
#混淆前后的映射
-printmapping mapping.txt
########记录生成的日志数据,gradle build时 在本项目根目录输出-end######
# ===================== 混淆保护自己项目的部分代码以及引用的第三方jar包library ================
#okhttp
-dontwarn com.squareup.okhttp.**
-keep class com.squareup.okhttp.** { *;}
-dontwarn okio.**
#忽略警告
-dontwarn retrofit.**
#保留一个完整的包
-keep class retrofit.** {
*;
}
#忽略警告
-dontwarn rx.internal.util.unsafe.**
#保留一个完整的包
-keep class rx.internal.util.unsafe.** {
*;
}
#忽略警告
-dontwarn uk.co.senab.photoview.**
#保留一个完整的包
-keep class uk.co.senab.photoview.** {
*;
}
#忽略警告
-dontwarn rx.internal.util.unsafe.**
#保留一个完整的包
-keep class rx.internal.util.unsafe.** {
*;
}
#忽略警告
-dontwarn com.mints.cleaner.model.bean.**
#保留实体类
-keep class com.mints.cleaner.model.bean.** {
*;
}
#忽略警告
-dontwarn com.mints.cleaner.widget.**
#保留实体类
-keep class com.mints.cleaner.widget.** {
*;
}
#系统的design 忽略警告
-dontwarn android.support.design.widget.**
#保留实体类
-keep class android.support.design.widget.** {
*;
}
#系统的renderscript 忽略警告
-dontwarn android.support.v8.renderscript.**
#保留实体类
-keep class android.support.v8.renderscript.** {
*;
}
#忽略警告
-dontwarn cn.com.library.rxbus.**
#保留实体类
-keep class cn.com.library.rxbus.** {*;}
#忽略警告
-dontwarn cn.fraudmetrix.sdk.**
#保留一个完整的包
-keep class cn.fraudmetrix.sdk.** {
*;
}
#忽略警告
-dontwarn com.nineoldandroids.**
#保留一个完整的包
-keep class com.nineoldandroids.** {
*;
}
#忽略警告
-dontwarn Decoder.**
#保留一个完整的包
-keep class Decoder.** {
*;
}
#忽略警告
-dontwarn com.nostra13.universalimageloader.**
#保留实体类
-keep class com.nostra13.universalimageloader.** {
*;
}
#忽略警告
-dontwarn com.megvii.**
#保留实体类
-keep class com.megvii.** { *; }
-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }
#如果引用了v4或者v7包
-dontwarn android.support.**
#如果用用到Gson解析包的,直接添加下面这几行就能成功混淆,不然会报错。
#gson
-keepattributes Signature
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
# ===================== 混淆保护自己项目的部分代码以及引用的第三方jar包library-end ================
-keep public class * extends android.view.View {
public <init>(android.data.Context);
public <init>(android.data.Context, android.util.AttributeSet);
public <init>(android.data.Context, android.util.AttributeSet, int);
public void set*(...);
}
#保持 native 方法不被混淆
-keepclasseswithmembernames class * {
native <methods>;
}
#保持自定义控件类不被混淆
-keepclasseswithmembers class * {
public <init>(android.data.Context, android.util.AttributeSet);
}
#保持自定义控件类不被混淆
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
#保持 Parcelable 不被混淆
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
#保持 Serializable 不被混淆
-keepnames class * implements java.io.Serializable
#保持 Serializable 不被混淆并且enum 类也不被混淆
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
!private <fields>;
!private <methods>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
#保持枚举 enum 类不被混淆 如果混淆报错,建议直接使用上面的 -keepclassmembers class * implements java.io.Serializable即可
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers class * {
public void *ButtonClicked(android.view.View);
}
#不混淆资源类
-keepclassmembers class **.R$* {
public static <fields>;
}
# 避免影响升级功能,需要keep住support包的类
-keep class android.support.**{*;}
# ===================== shareSDK START ================
-dontwarn com.mob.**
-dontwarn cn.sharesdk.**
-dontwarn **.R$*
-keep class cn.sharesdk.**{*;}
-keep class com.sina.**{*;}
-keep class **.R$* {*;}
-keep class **.R{*;}
-keep class com.mob.**{*;}
# ======================= shareSDK END ===============
# ===================== umeng START ================
-keep class com.umeng.** {*;}
-keepclassmembers class * {
public <init> (org.json.JSONObject);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep public class com.mints.cleaner.R$*{
public static final int *;
}
# ======================= umeng END ================
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
\ No newline at end of file
# ===================== TalkingData START ================
-dontwarn com.tendcloud.tenddata.**
-keep class com.tendcloud.** {*;}
-keep public class com.tendcloud.tenddata.** { public protected *;}
-keepclassmembers class com.tendcloud.tenddata.**{
public void *(***);
}
-keep class com.talkingdata.sdk.TalkingDataSDK {public *;}
-keep class com.apptalkingdata.** {*;}
-keep class dice.** {*; }
-dontwarn dice.**
# ======================= TalkingData END ================
......@@ -2,8 +2,25 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mints.cleaner">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.REORDER_TASKS" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<<<<<<< HEAD
<uses-permission android:name="android.permission.INTERNET" />
=======
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
>>>>>>> 0907_dev
<application
android:name=".App"
......@@ -11,18 +28,34 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
<<<<<<< HEAD
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@android:style/Theme.Light.NoTitleBar">
<!--屏幕适配-->
=======
android:persistent="true"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/CustomAppTheme">
<!-- 屏幕适配 -->
>>>>>>> 0907_dev
<meta-data
android:name="android.max_aspect"
android:value="2.4" />
<<<<<<< HEAD
<activity android:name=".ui.main.MainActivity"></activity>
<activity android:name=".ui.login.LoginActivity" />
<activity android:name=".ui.NavigationActivity">
=======
<activity
android:name=".ui.splash.SplashActivity"
android:excludeFromRecents="true"
android:configChanges="orientation|screenSize|keyboardHidden">
>>>>>>> 0907_dev
<intent-filter>
<action android:name="android.intent.action.MAIN" />
......@@ -30,12 +63,90 @@
</intent-filter>
</activity>
<<<<<<< HEAD
<activity android:name=".ui.splash.SplashActivity" />
<service
android:name=".InitAppService"
android:enabled="true"
android:exported="false" />
=======
<activity
android:name=".ui.NavigationActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:launchMode="singleTask"
android:screenOrientation="portrait"/>
<activity
android:name=".ui.multiClean.MultiCleanActivity"
android:launchMode="singleTop" />
<activity
android:name=".ui.albumClean.AlbumCleanActivity"
android:launchMode="singleTop" />
<activity android:name=".ui.login.LoginActivity" />
<activity
android:name=".ui.clean.CleanActivity"
android:launchMode="singleInstance"
android:theme="@style/CustomerTransparentTheme" />
<activity android:name=".ui.web.WebActivity" />
<activity android:name=".ui.fileClean.FileCleanActivity" />
<activity android:name=".ui.setting.SettingActivity" />
<activity
android:name=".ui.PreviewActivity"
android:launchMode="singleTop"
android:theme="@style/CustomerTransparentTheme" />
<!-- FileProvider -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
<!-- APPWIDGET -->
<receiver android:name=".appwidget.NewAppWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.mints.cleaner.appWidget.action.CLICK" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/new_app_widget_info" />
</receiver>
<!-- 保活唤醒 -->
<service
android:name=".service.ScreenService"
android:process=":screen" />
<service
android:name=".service.keep.KeepLiveManager$GrayInnerService"
android:process=":screen">
<intent-filter android:priority="1000">
<action android:name="service.keep.KeepLiveManager$GrayInnerService" />
</intent-filter>
</service>
<activity
android:name=".service.keep.PixelActivity"
android:excludeFromRecents="true"
android:finishOnTaskLaunch="false"
android:launchMode="singleInstance"
android:process=":screen"
android:theme="@style/LiveActivityStyle" />
<activity
android:name=".ui.AdActivity"
android:excludeFromRecents="true"
android:exported="true"
android:finishOnTaskLaunch="false"
android:launchMode="singleInstance"
android:process=":screen"
android:theme="@style/CustomerTransparentTheme" />
>>>>>>> 0907_dev
</application>
</manifest>
\ No newline at end of file
......@@ -37,7 +37,11 @@ class App : Application() {
private fun initThirdConfig() {
// 屏幕适配
<<<<<<< HEAD
initRudenessScreen()
=======
// initRudenessScreen()
>>>>>>> 0907_dev
// 生命周期
LifeManager().install(this)
......@@ -52,7 +56,10 @@ class App : Application() {
}
}
<<<<<<< HEAD
=======
>>>>>>> 0907_dev
}
/**
......
......@@ -15,4 +15,17 @@ object Constant {
const val DEFAULT_VALUE_SIZE = 15
const val DEFAULT_ARC_WIDTH = 15
const val DEFAULT_WAVE_HEIGHT = 40
<<<<<<< HEAD
=======
/**
* 应用包名
*/
const val MINTS_PKG_NAME = "com.mints.cleaner"
/**
* 首次弹出权限声明
*/
const val LOAN_PERMISSION_FLAG = "loan_permission_flag"
>>>>>>> 0907_dev
}
\ No newline at end of file
package com.mints.cleaner.adapter.albumClean
import android.widget.ImageView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.mints.cleaner.R
import com.mints.cleaner.model.bean.Image
import com.mints.cleaner.util.VersionUtils
import com.mints.cleaner.widget.RoundCheckBox
class AlbumCleanAdapter(layoutResId: Int, data: List<Image>) :
BaseQuickAdapter<Image, BaseViewHolder>(layoutResId, data) {
// 选中图片数据
private var mSelectImages = arrayListOf<Image>()
// 复选框选中状态
private var mCheckBoxTags = arrayListOf<Int>()
private var mSelectListener: OnImageSelectListener? = null
private var mItemClickListener: OnItemClickListener? = null
private val isAndroidQ: Boolean = VersionUtils.isAndroidQ()
override fun convert(helper: BaseViewHolder, item: Image) {
helper.getView<ImageView>(R.id.iv_item_album).run {
Glide.with(mContext).load(if (isAndroidQ) item.uri else item.path)
.apply(
RequestOptions()
.centerCrop()
.placeholder(drawable)
.dontAnimate()
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
)
.into(this)
setOnClickListener {
mItemClickListener?.let {
it.onItemClick(item, helper.adapterPosition)
}
}
}
helper.getView<RoundCheckBox>(R.id.cb_item).run {
setOnCheckedChangeListener(null)
tag = helper.adapterPosition
isChecked = mCheckBoxTags.contains(helper.adapterPosition)
setOnCheckedChangeListener { _, _ ->
if (mSelectImages.contains(item)) {
unSelectImage(item)
} else {
selectImage(item)
}
if (isChecked) {
mCheckBoxTags.add(helper.adapterPosition)
} else {
mCheckBoxTags.remove(helper.adapterPosition)
}
}
}
}
fun setOnImageSelectListener(listener: OnImageSelectListener?) {
mSelectListener = listener
}
fun setOnItemClickListener1(listener: OnItemClickListener?) {
mItemClickListener = listener
}
fun getSelectImageList(): List<Image> {
return mSelectImages
}
// 更新数据
fun refreshData(data: List<Image>) {
mData = data
notifyDataSetChanged()
}
// 清空复选框标识
fun cleanSelectImage() {
mSelectImages = arrayListOf()
mCheckBoxTags = arrayListOf()
mSelectListener?.let {
it.onImageSelect(mSelectImages.size)
}
notifyDataSetChanged()
}
// 全选
fun fullSelectImage() {
for (index in 0 until mData.size) {
mCheckBoxTags.add(index)
mSelectImages.add(mData[index])
}
mSelectListener?.let {
it.onImageSelect(mSelectImages.size)
}
notifyDataSetChanged()
}
// 取消全选
fun cancelFullSelectImage() {
// 取消全选
mSelectImages = arrayListOf()
mCheckBoxTags = arrayListOf()
mSelectListener?.let {
it.onImageSelect(mSelectImages.size)
}
notifyDataSetChanged()
}
/**
* 选中图片
*/
private fun selectImage(image: Image) {
mSelectImages.add(image)
mSelectListener?.let {
it.onImageSelect(mSelectImages.size)
}
}
/**
* 取消选中图片
*/
private fun unSelectImage(image: Image) {
mSelectImages.remove(image)
mSelectListener?.let {
it.onImageSelect(mSelectImages.size)
}
}
interface OnImageSelectListener {
fun onImageSelect(
selectCount: Int
)
}
interface OnItemClickListener {
fun onItemClick(image: Image, position: Int)
}
}
\ No newline at end of file
package com.mints.cleaner.adapter.fileClean
import android.widget.ImageView
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.mints.cleaner.R
import com.mints.cleaner.model.bean.CleanItem
class FileCleanAdapter(layoutResId: Int, data: List<CleanItem>) :
BaseQuickAdapter<CleanItem, BaseViewHolder>(layoutResId, data) {
override fun convert(helper: BaseViewHolder, item: CleanItem?) {
item?.let {
helper.setText(R.id.tv_title, it.title)
helper.setText(R.id.tv_info, it.info)
helper.getView<ImageView>(R.id.iv).setImageResource(it.image)
}
}
}
\ No newline at end of file
package com.mints.cleaner.adapter.home
import android.text.TextUtils
import android.widget.GridView
import android.widget.ImageView
import android.widget.SimpleAdapter
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.mints.cleaner.R
import com.mints.cleaner.model.bean.HomeMultiItem
import com.mints.cleaner.util.NetSpeed
import com.mints.cleaner.util.NetWorkUtils
class HomeAdapter : BaseMultiItemQuickAdapter<HomeMultiItem, BaseViewHolder> {
constructor(data: List<HomeMultiItem>) : super(data) {
addItemType(HomeMultiItem.ITEM_TOP, R.layout.item_clean_top)
addItemType(HomeMultiItem.ITEM_MID, R.layout.item_clean_mid)
addItemType(HomeMultiItem.ITEM_BOTTOM, R.layout.item_clean_bottom)
}
override fun convert(helper: BaseViewHolder, item: HomeMultiItem) {
when (helper.itemViewType) {
HomeMultiItem.ITEM_TOP -> {
helper.addOnClickListener(R.id.btn_clean)
setCleanTopItemStyle(helper)
}
HomeMultiItem.ITEM_MID -> {
val gridView = helper.getView<GridView>(R.id.gv_clean)
val simpleAdapter = SimpleAdapter(
gridView.context,
item?.gvDataList,
R.layout.item_gv_clean,
arrayOf("item_gv_icon", "item_gv_text"),
intArrayOf(R.id.item_gv_img, R.id.item_gv_text)
)
gridView.adapter = simpleAdapter
gridView.setOnItemClickListener { _, _, position, _ ->
onGridViewItemClickListener?.let {
it.onGridViewItemClick(position)
}
}
}
HomeMultiItem.ITEM_BOTTOM -> {
item.itemData?.let {
helper.setText(R.id.tv_title, it.title)
helper.setText(R.id.tv_info, it.info)
helper.getView<ImageView>(R.id.iv).setImageResource(it.image)
}
}
}
}
/**
* top样式
*/
private fun setCleanTopItemStyle(helper: BaseViewHolder) {
// 是否连网
val isNetwork = NetWorkUtils.isNetworkAvailable(mContext)
if (isNetwork) {
// 是否连接wifi
val wifiName = NetWorkUtils.getConnectWifiSsid(mContext)
if (!TextUtils.isEmpty(wifiName) && wifiName!!.contains(mContext.getString(R.string.no_wifi))) {
helper.setText(R.id.tv_wifi, mContext.getString(R.string.no_authorize))
helper.setText(R.id.tv_wifi_status, mContext.getString(R.string.no_connect_wifi))
} else {
helper.setText(R.id.tv_wifi, wifiName)
helper.setText(R.id.tv_wifi_status, mContext.getString(R.string.connect_wifi))
}
helper.setText(R.id.tv_wifi_speed, NetSpeed.getNetSpeed(mContext))
} else {
helper.setText(R.id.tv_wifi, mContext.getString(R.string.no_network))
helper.setText(R.id.tv_wifi_status, mContext.getString(R.string.no_connect_wifi))
}
}
private var onGridViewItemClickListener: OnGridViewItemClickListener? = null
fun setOnGridViewItemClickListener(listener: OnGridViewItemClickListener?) {
onGridViewItemClickListener = listener
}
interface OnGridViewItemClickListener {
fun onGridViewItemClick(position: Int)
}
}
\ No newline at end of file
package com.mints.cleaner.adapter.impl
import com.mints.cleaner.model.bean.FileBean
// TODO 公用接口回调
//interface OnImageSelectListener {
// fun onImageSelect(
// selectCount: Int
// )
//}
//
//interface OnItemClickListener {
// fun onItemClick(file: FileBean, position: Int)
//}
\ No newline at end of file
package com.mints.cleaner.adapter.multiClean
import android.widget.ImageView
import android.widget.TextView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.mints.cleaner.R
import com.mints.cleaner.model.bean.FileBean
import com.mints.cleaner.util.FormatUtils
import com.mints.cleaner.widget.RoundCheckBox
import com.mints.ktx.ext.dp2px
class MultiCleanAdapter(layoutResId: Int, data: List<FileBean>) :
BaseQuickAdapter<FileBean, BaseViewHolder>(layoutResId, data) {
// 选中图片数据
private var mSelectImages = arrayListOf<FileBean>()
// 复选框选中状态
private var mCheckBoxTags = arrayListOf<Int>()
private var mSelectListener: OnImageSelectListener? = null
private var mItemClickListener: OnItemClickListener? = null
override fun convert(helper: BaseViewHolder, item: FileBean) {
helper.getView<ImageView>(R.id.iv_item_multi).run {
Glide.with(mContext).load(item.image)
.apply(
RequestOptions()
.centerCrop()
.override(dp2px(80))
.placeholder(R.mipmap.ic_launcher)
.dontAnimate()
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
)
.into(this)
setOnClickListener {
mItemClickListener?.let {
it.onItemClick(item, helper.adapterPosition)
}
}
}
helper.getView<TextView>(R.id.tv_item_multi_name).text = item.name
helper.getView<TextView>(R.id.tv_item_multi_size).text = FormatUtils.formatFileSize(item.size)
helper.getView<TextView>(R.id.tv_item_multi_time).text = item.time
helper.getView<RoundCheckBox>(R.id.cb_item).run {
setOnCheckedChangeListener(null)
tag = helper.adapterPosition
isChecked = mCheckBoxTags.contains(helper.adapterPosition)
setOnCheckedChangeListener { _, _ ->
if (mSelectImages.contains(item)) {
unSelectImage(item)
} else {
selectImage(item)
}
if (isChecked) {
mCheckBoxTags.add(helper.adapterPosition)
} else {
mCheckBoxTags.remove(helper.adapterPosition)
}
}
}
}
fun setOnImageSelectListener(listener: OnImageSelectListener?) {
mSelectListener = listener
}
fun setOnItemClickListener1(listener: OnItemClickListener?) {
mItemClickListener = listener
}
fun getSelectImageList(): List<FileBean> {
return mSelectImages
}
// 更新数据
fun refreshData(data: List<FileBean>) {
mData = data
notifyDataSetChanged()
}
// 清空复选框标识
fun cleanSelectImage() {
mSelectImages = arrayListOf()
mCheckBoxTags = arrayListOf()
mSelectListener?.let {
it.onImageSelect(mSelectImages.size)
}
notifyDataSetChanged()
}
// 全选
fun fullSelectImage() {
for (index in 0 until mData.size) {
mCheckBoxTags.add(index)
mSelectImages.add(mData[index])
}
mSelectListener?.let {
it.onImageSelect(mSelectImages.size)
}
notifyDataSetChanged()
}
// 取消全选
fun cancelFullSelectImage() {
// 取消全选
mSelectImages = arrayListOf()
mCheckBoxTags = arrayListOf()
mSelectListener?.let {
it.onImageSelect(mSelectImages.size)
}
notifyDataSetChanged()
}
/**
* 选中图片
*/
private fun selectImage(image: FileBean) {
mSelectImages.add(image)
mSelectListener?.let {
it.onImageSelect(mSelectImages.size)
}
}
/**
* 取消选中图片
*/
private fun unSelectImage(file: FileBean) {
mSelectImages.remove(file)
mSelectListener?.let {
it.onImageSelect(mSelectImages.size)
}
}
interface OnImageSelectListener {
fun onImageSelect(
selectCount: Int
)
}
interface OnItemClickListener {
fun onItemClick(file: FileBean, position: Int)
}
}
\ No newline at end of file
package com.mints.cleaner.appwidget
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.widget.RemoteViews
import com.mints.cleaner.R
import com.mints.cleaner.ui.clean.CleanActivity
import com.mints.cleaner.util.LogUtil
import com.mints.cleaner.util.SystemUtils
import com.mints.ktx.ext.startKtxActivity
/**
* Implementation of App Widget functionality.
*/
class NewAppWidget : AppWidgetProvider() {
companion object {
const val CLICK_ACTION = "com.mints.cleaner.appWidget.action.CLICK"
}
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
// There may be multiple widgets active, so update all of them
val remoteViews = RemoteViews(context.packageName, R.layout.app_widget_clean)
remoteViews.setOnClickPendingIntent(
R.id.btn_clean,
getPendingIntent(context, R.id.btn_clean)
)
val memoryValue = getMemoryValue(context)
remoteViews.setTextViewText(
R.id.tv_memory,
"$memoryValue%内存已使用"
)
remoteViews.setProgressBar(R.id.progressBar, 100, memoryValue, false)
appWidgetManager.updateAppWidget(appWidgetIds, remoteViews)
}
override fun onDeleted(context: Context, appWidgetIds: IntArray) {
// When the user deletes the widget, delete the preference associated with it.
}
override fun onEnabled(context: Context) {
// Enter relevant functionality for when the first widget is created
}
override fun onDisabled(context: Context) {
// Enter relevant functionality for when the last widget is disabled
}
override fun onReceive(context: Context?, intent: Intent?) {
super.onReceive(context, intent)
intent?.let {
if (it.action.equals(CLICK_ACTION)) {
context?.startKtxActivity<CleanActivity>(flags = Intent.FLAG_ACTIVITY_NEW_TASK)
}
}
}
private fun getPendingIntent(
context: Context,
resID: Int
): PendingIntent? {
val intent = Intent(
context,
NewAppWidget::class.java
)
intent.action = CLICK_ACTION
intent.data = Uri.parse("id:$resID")
return PendingIntent.getBroadcast(context, 0, intent, 0)
}
private fun getMemoryValue(context: Context): Int {
return (100 - SystemUtils.getUsedPercentValue(context).toInt())
}
}
......@@ -4,6 +4,11 @@ import com.mints.cleaner.model.api.ApiService
import com.mints.cleaner.model.api.client.RetrofitClient
import com.mints.cleaner.model.repository.LoginRepository
import com.mints.cleaner.model.repository.MainRepository
<<<<<<< HEAD
=======
import com.mints.cleaner.model.repository.fileClean.FileCleanRepository
import com.mints.cleaner.ui.fileClean.FileCleanViewModel
>>>>>>> 0907_dev
import com.mints.cleaner.ui.login.LoginViewModel
import com.mints.cleaner.ui.main.MainViewModel
import org.koin.androidx.viewmodel.dsl.viewModel
......@@ -14,13 +19,22 @@ import org.koin.dsl.module
val viewModelModule = module {
viewModel { LoginViewModel(get()) }
viewModel { MainViewModel(get()) }
<<<<<<< HEAD
=======
viewModel { FileCleanViewModel(get()) }
>>>>>>> 0907_dev
}
val repositoryModule = module {
single { RetrofitClient.getService(
ApiService::class.java) }
single { LoginRepository(get()) }
<<<<<<< HEAD
single { MainRepository(get()) }
=======
single { MainRepository() }
single { FileCleanRepository() }
>>>>>>> 0907_dev
}
val appModule = listOf(viewModelModule, repositoryModule)
\ No newline at end of file
package com.mints.cleaner.manager
import android.annotation.TargetApi
import android.app.*
import android.content.Context
import android.content.Intent
import android.os.Build
import android.widget.RemoteViews
import androidx.core.app.NotificationCompat
import com.mints.cleaner.R
import com.mints.cleaner.ui.multiClean.MultiCleanActivity
/**
* 通知管理
*/
class NotifyManager private constructor(private val service: Service) {
companion object {
const val CHINALL_ID = "MINTSCLEAN"
const val CHINALL_NAME = "清理"
private var _inst: NotifyManager? = null
@JvmStatic
fun getInstance(service: Service): NotifyManager? {
return if (_inst != null) {
_inst
} else {
_inst = NotifyManager(service)
_inst
}
}
}
/**
* 创建通知
*/
fun createNotifyDialog(): Notification {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel(
CHINALL_ID,
CHINALL_NAME,
NotificationManager.IMPORTANCE_MAX
)
}
return NotificationCompat.Builder(
service,
CHINALL_ID
)
.setOngoing(true)
.setAutoCancel(true)
.setContentTitle("")
.setContentText("")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setContent(remoteViews)
.setVibrate(longArrayOf(0))
.build()
}
/**
* 创建通知渠道
*/
@TargetApi(Build.VERSION_CODES.O)
private fun createNotificationChannel(
channelId: String,
channelName: String,
importance: Int
) {
val channel = NotificationChannel(channelId, channelName, importance)
channel.enableVibration(false) //震动不可用
channel.setSound(null, null) //设置没有声
val notificationManager = service.getSystemService(
Context.NOTIFICATION_SERVICE
) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
/**
* 创建通知显示view
*/
private val remoteViews: RemoteViews
private get() {
val mainPendingIntent = PendingIntent.getActivity(
service,
0,
Intent(service, MultiCleanActivity::class.java),
PendingIntent.FLAG_UPDATE_CURRENT
)
val remoteViews = RemoteViews(service.packageName, R.layout.view_remote)
remoteViews.setOnClickPendingIntent(R.id.notify_ic, mainPendingIntent)
return remoteViews
}
}
\ No newline at end of file
......@@ -2,12 +2,10 @@ package com.mints.cleaner.model.api.client
import com.mints.cleaner.model.api.neterror.CashException
import com.mints.cleaner.model.api.neterror.ServerException
import com.mints.cleaner.model.api.neterror.Throwable
import com.mints.cleaner.model.repository.BaseResponse
import com.mints.core.Result
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.coroutineScope
import java.io.IOException
import java.lang.Exception
open class BaseRepository {
......
package com.mints.cleaner.model.bean
import android.graphics.drawable.Drawable
class AppProcessInfo : Comparable<AppProcessInfo?> {
/**
* The app name.
*/
var appName: String? = null
/**
* The name of the process that this object is associated with.
*/
var processName: String? = null
/**
* The pid of this process; 0 if none.
*/
var pid = 0
/**
* The user id of this process.
*/
var uid = 0
/**
* The icon.
*/
var icon: Drawable? = null
/**
* 占用的内存.
*/
var memory: Long = 0
/**
* 占用的内存.
*/
var cpu: String? = null
var packName: String? = null
/**
* 进程的状态,其中S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值是负数.
*/
var status: String? = null
/**
* 当前使用的线程数.
*/
var threadsCount: String? = null
var checked = true
/**
* 是否是系统进程.
*/
var isSystem = false
/**
* Instantiates a new ab process info.
*/
constructor() : super() {}
/**
* Instantiates a new ab process info.
*
* @param processName the process name
* @param pid the pid
* @param uid the uid
*/
constructor(processName: String?, pid: Int, uid: Int) : super() {
this.processName = processName
this.pid = pid
this.uid = uid
}
override fun compareTo(other: AppProcessInfo?): Int {
return if (processName!!.compareTo(other!!.processName!!) == 0) {
when {
memory < other!!.memory -> {
1
}
memory == other!!.memory -> {
0
}
else -> {
-1
}
}
} else {
processName!!.compareTo(other!!.processName!!)
}
}
}
\ No newline at end of file
package com.mints.cleaner.model.bean
import android.view.View
import androidx.databinding.BaseObservable
import androidx.databinding.Bindable
import com.mints.cleaner.BR
import com.mints.cleaner.R
class CleanHeaderTitle : BaseObservable {
// 左边图标
var leftIcon: Int = 0
// 左边图标点击事件
var leftAction: () -> Unit = {}
// 右边文字是否显示
var rightInfoVisible: Int = View.GONE
// 右边文字点击事件
var rightInfoAction: () -> Unit = {}
// 背景颜色
var background: Int = R.color.theme
@get:Bindable
// 标题内容
var title: String? = null
set(value) {
field = value
notifyPropertyChanged(BR.title)
}
@get:Bindable
// 右边文字内容
var rightInfo: String? = null
set(value) {
field = value
notifyPropertyChanged(BR.rightInfo)
}
constructor(
title: String,
leftIcon: Int,
leftAction: () -> Unit,
rightInfoVisible: Int,
rightInfo: String,
rightInfoAction: () -> Unit,
background: Int
) {
this.title = title
this.leftIcon = leftIcon
this.leftAction = leftAction
this.rightInfo = rightInfo
this.rightInfoVisible = rightInfoVisible
this.rightInfoAction = rightInfoAction
this.background = background
}
}
\ No newline at end of file
package com.mints.cleaner.model.bean
data class CleanItem(val title: String, val info: String, val image: Int)
\ No newline at end of file
package com.mints.cleaner.model.bean
data class FileBean(
val image: Any,
val path: String,
val time: String,
val name: String,
val size: Long
)
\ No newline at end of file
package com.mints.cleaner.model.bean
class Folder {
var name: String
var images: ArrayList<Image> = arrayListOf()
constructor(name: String) {
this.name = name
}
constructor(name: String, images: ArrayList<Image>) {
this.name = name
this.images = images
}
fun addImage(image: Image?) {
if (image != null && image.path.isEmpty()) {
if (images == null) {
images = ArrayList()
}
images.add(image)
}
}
}
\ No newline at end of file
package com.mints.cleaner.model.bean
class HeaderTitle(
// 标题内容
var title: String,
// 返回箭头是否显示
var leftIconVisible: Int,
// 左边图标
var leftIcon: Int,
// 左边图标点击事件
var leftAction: () -> Unit,
// 背景颜色
val background: Int
)
\ No newline at end of file
package com.mints.cleaner.model.bean
import com.chad.library.adapter.base.entity.MultiItemEntity
class HomeMultiItem : MultiItemEntity {
private var itemType: Int = 0
lateinit var itemData: CleanItem
lateinit var gvDataList: MutableList<Map<String, Any>>
constructor(itemType: Int) {
this.itemType = itemType
}
constructor(itemType: Int, itemData: CleanItem) {
this.itemType = itemType
this.itemData = itemData
}
constructor(itemType: Int, gvDataList: MutableList<Map<String, Any>>) {
this.itemType = itemType
this.gvDataList = gvDataList
}
companion object {
// 头布局
const val ITEM_TOP = 0x00000001
// 中间布局
const val ITEM_MID = 0x00000002
// 尾布局
const val ITEM_BOTTOM = 0x00000003
}
override fun getItemType(): Int {
return itemType
}
}
\ No newline at end of file
package com.mints.cleaner.model.bean
import android.net.Uri
import android.os.Parcel
import android.os.Parcelable
data class Image(
val path: String,
val time: Long,
val name: String,
val mimeType: String,
val uri: Uri,
val size: Long
) : Parcelable {
constructor(parcel: Parcel) : this(
parcel.readString()!!,
parcel.readLong(),
parcel.readString()!!,
parcel.readString()!!,
parcel.readParcelable<Uri>(Uri::class.java.classLoader) as Uri,
parcel.readLong()
)
override fun writeToParcel(dest: Parcel?, flags: Int) {
dest?.run {
writeString(path)
writeLong(time)
writeString(name)
writeString(mimeType)
writeParcelable(uri, 0)
writeLong(size)
}
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<Image> {
override fun createFromParcel(parcel: Parcel): Image {
return Image(parcel)
}
override fun newArray(size: Int): Array<Image?> {
return arrayOfNulls(size)
}
}
}
\ No newline at end of file
package com.mints.cleaner.model.bean
class Title(val title: Int, val icon: Int, val action: () -> Unit)
\ No newline at end of file
package com.mints.cleaner.model.repository
<<<<<<< HEAD
import com.mints.cleaner.model.api.ApiService
import com.mints.cleaner.model.api.client.BaseRepository
class MainRepository(val service: ApiService) : BaseRepository() {
=======
import com.mints.cleaner.R
import com.mints.cleaner.model.bean.HomeMultiItem
import com.mints.cleaner.model.bean.CleanItem
class MainRepository {
// 网格布局data
private val gvNames = arrayOf("手机加速", "微信清理", "QQ清理", "软件管理", "相册清理", "视频清理")
private val gvIcons = arrayOf(
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher
)
private val itemBottomTitle = arrayOf("文件清理", "安装包清理", "音乐清理", "压缩包清理")
private val itemBottomInfo = arrayOf("释放更多空间", "清理无用的安装包", "清理不喜欢的音乐", "清理无用的压缩包")
private val itemBottomImage = arrayOf(
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher
)
private val gvDataList: MutableList<Map<String, Any>> = ArrayList()
fun getHomeData(): ArrayList<HomeMultiItem> {
for (i in gvNames.indices) {
val item: MutableMap<String, Any> = HashMap()
item["item_gv_icon"] = gvIcons[i]
item["item_gv_text"] = gvNames[i]
gvDataList.add(item)
}
val multiItemList = arrayListOf(
HomeMultiItem(HomeMultiItem.ITEM_TOP),
HomeMultiItem(
HomeMultiItem.ITEM_MID,
gvDataList
)
)
for (i in itemBottomTitle.indices) {
multiItemList.add(
HomeMultiItem(
HomeMultiItem.ITEM_BOTTOM,
CleanItem(
itemBottomTitle[i],
itemBottomInfo[i],
itemBottomImage[i]
)
)
)
}
return multiItemList
}
>>>>>>> 0907_dev
}
\ No newline at end of file
package com.mints.cleaner.model.repository.fileClean
import com.mints.cleaner.R
import com.mints.cleaner.model.bean.CleanItem
class FileCleanRepository {
private val itemBottomTitle = arrayOf("相册清理", "视频清理", "安装包清理", "音乐清理", "压缩包清理", "大文件清理")
private val itemBottomInfo =
arrayOf("清理不需要的照片", "清理视频释放空间", "清理无用的安装包", "清理不喜欢的音乐", "清理无用的压缩包", "清理较大的文件")
private val itemBottomImage = arrayOf(
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher
)
fun getFileCleanData(): ArrayList<CleanItem> {
val fileCleanList = arrayListOf<CleanItem>()
for (i in itemBottomTitle.indices) {
fileCleanList.add(
CleanItem(
itemBottomTitle[i],
itemBottomInfo[i],
itemBottomImage[i]
)
)
}
return fileCleanList
}
}
\ No newline at end of file
package com.mints.cleaner.service
import android.annotation.SuppressLint
import android.content.Intent
import com.mints.cleaner.service.keep.KeepliveService
/**
* 开幕保活
*/
class ScreenService : KeepliveService() {
@SuppressLint("WrongConstant")
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val i = super.onStartCommand(intent, flags, startId)
// LogUtil.d("ScreenService",i.toString())
return i
}
}
\ No newline at end of file
package com.mints.cleaner.service.keep
import android.app.Service
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.IBinder
import com.mints.cleaner.manager.NotifyManager.Companion.getInstance
import com.mints.cleaner.ui.AdActivity
import com.mints.cleaner.util.LogUtil
import com.mints.cleaner.util.SystemUtils
import com.mints.cleaner.util.VersionUtils
import com.mints.ktx.ext.startKtxActivity
/**
* 后台进程保活管理类
*/
class KeepLiveManager {
/**
* 1像素的透明Activity
*/
private var activity: PixelActivity? = null
/**
* 监听锁屏/解锁的广播(必须动态注册)
*/
private var lockReceiver: LockReceiver? = null
/**
* 传入1像素的透明Activity实例
*
* @param activity
*/
fun setKeepLiveActivity(activity: PixelActivity?) {
this.activity = activity
}
/**
* 注册锁屏/解锁广播
*
* @param context
*/
fun registerReceiver(context: Context) {
lockReceiver = LockReceiver()
val filter = IntentFilter()
filter.addAction(Intent.ACTION_SCREEN_ON)
filter.addAction(Intent.ACTION_SCREEN_OFF)
filter.addAction(Intent.ACTION_USER_PRESENT)
context.registerReceiver(lockReceiver, filter)
}
/**
* 注销锁屏/解锁广播
*
* @param context
*/
fun unRegisterReceiver(context: Context) {
if (lockReceiver != null) {
context.unregisterReceiver(lockReceiver)
}
}
/**
* 设置服务为前台服务
*
* @param service
*/
fun setServiceForeground(service: Service) {
service.startForeground(
GRAY_SERVICE_ID,
getInstance(service)!!.createNotifyDialog()
)
}
private fun startLiveActivity(context: Context) {
val intent = Intent(context, PixelActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
}
private fun destroyLiveActivity() {
if (activity != null) {
activity!!.finish()
}
}
internal inner class LockReceiver : BroadcastReceiver() {
override fun onReceive(
context: Context,
intent: Intent
) {
when (intent.action) {
Intent.ACTION_SCREEN_OFF -> {
// 熄屏
SystemUtils.moveAppToFront(context)
startLiveActivity(context)
LogUtil.d("LockReceiver", "熄屏 Intent.ACTION_SCREEN_OFF")
}
Intent.ACTION_SCREEN_ON -> {
// 亮屏
if (VersionUtils.isAndroidQ()) {
SystemUtils.moveAppToFront(context)
context.startKtxActivity<AdActivity>(flags = Intent.FLAG_ACTIVITY_NEW_TASK)
} else {
context.startKtxActivity<AdActivity>(flags = Intent.FLAG_ACTIVITY_NEW_TASK)
}
LogUtil.d("LockReceiver", "亮屏 Intent.ACTION_SCREEN_ON")
}
Intent.ACTION_USER_PRESENT -> {
// 亮屏解锁
destroyLiveActivity()
}
}
}
}
/**
* 辅助Service
*/
class GrayInnerService : Service() {
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
startForeground(
GRAY_SERVICE_ID,
getInstance(this)!!.createNotifyDialog()
)
stopForeground(true)
stopSelf()
return super.onStartCommand(intent, flags, startId)
}
override fun onBind(intent: Intent): IBinder? {
return null
}
}
companion object {
/**
* 前台进程的NotificationId
*/
private const val GRAY_SERVICE_ID = 1002
/**
* 单例模式
*/
val instance = KeepLiveManager()
}
}
private fun Intent.setClass(context: Context, s: String) {
}
package com.mints.cleaner.service.keep
import android.app.Service
import android.content.Intent
import android.os.IBinder
open class KeepliveService : Service() {
override fun onCreate() {
KeepLiveManager.instance.registerReceiver(this)
super.onCreate()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
KeepLiveManager.instance.setServiceForeground(this)
return START_STICKY
}
override fun onDestroy() {
KeepLiveManager.instance.unRegisterReceiver(this)
super.onDestroy()
}
override fun onBind(intent: Intent): IBinder? {
return null
}
}
\ No newline at end of file
package com.mints.cleaner.service.keep
import android.app.Activity
import android.os.Bundle
import android.view.Gravity
import com.mints.cleaner.util.LogUtil
/**
* 一像素的Activity
*/
class PixelActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val window = window
window.setGravity(Gravity.LEFT or Gravity.TOP)
val params = window.attributes
params.x = 0
params.y = 0
params.height = 1
params.width = 1
window.attributes = params
KeepLiveManager.instance.setKeepLiveActivity(this)
}
override fun onResume() {
super.onResume()
LogUtil.d("PixelActivity : onResume")
}
}
package com.mints.cleaner.ui
import android.app.Activity
import android.app.KeyguardManager
import android.content.Context
import android.os.Build
import android.os.Bundle
import android.view.WindowManager
import com.mints.cleaner.R
import com.mints.cleaner.util.LogUtil
class AdActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true)
setTurnScreenOn(true)
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
keyguardManager.requestDismissKeyguard(this, null)
} else {
this.window.addFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
)
}
setContentView(R.layout.activity_ad)
}
}
\ No newline at end of file
......@@ -5,7 +5,6 @@ import androidx.viewpager2.adapter.FragmentStateAdapter
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.mints.cleaner.R
import com.mints.cleaner.ui.home.HomeFragment
import com.mints.cleaner.ui.my.MyFragment
import com.mints.cleaner.ui.news.NewsFragment
import com.mints.core.base.BaseFragment
import kotlinx.android.synthetic.main.activity_bottom_navigation.*
......@@ -13,18 +12,16 @@ import kotlinx.android.synthetic.main.activity_bottom_navigation.*
/**
* 这是首页 Tab
*/
class MainFragment: BaseFragment() {
class MainFragment : BaseFragment() {
private val fragmentList = arrayListOf<Fragment>()
private val homeFragment by lazy { HomeFragment() }//首页
private val newsFragment by lazy { NewsFragment() }//新闻
private val myFragment by lazy { MyFragment() }//我的
init {
fragmentList.run {
add(homeFragment)
add(newsFragment)
add(myFragment)
}
}
......@@ -46,9 +43,6 @@ class MainFragment: BaseFragment() {
R.id.wifi -> {
switchFragment(1)
}
R.id.my -> {
switchFragment(2)
}
}
true
}
......@@ -60,7 +54,7 @@ class MainFragment: BaseFragment() {
private fun initViewPager() {
mainViewpager.isUserInputEnabled = false
mainViewpager.offscreenPageLimit = 2
mainViewpager.offscreenPageLimit = 1
mainViewpager.adapter = object : FragmentStateAdapter(this) {
override fun createFragment(position: Int) = fragmentList[position]
......
package com.mints.cleaner.ui
import android.Manifest
import android.content.Intent
import android.os.Build
import android.view.KeyEvent
import android.widget.Toast
import com.mints.cleaner.App
import com.mints.cleaner.R
import com.mints.cleaner.service.ScreenService
import com.mints.cleaner.util.VersionUtils
import com.mints.core.base.BaseActivity
import com.permissionx.guolindev.PermissionX
class NavigationActivity : BaseActivity() {
override fun getLayoutResId() = R.layout.activity_navigation
override fun initView() {
// 开启子进程用来守护锁屏弹窗
startScreenService()
}
private fun startScreenService() {
if (VersionUtils.isAndroidO()) {
startForegroundService(Intent(App.CONTEXT, ScreenService::class.java))
} else {
startService(Intent(App.CONTEXT, ScreenService::class.java))
}
}
override fun initData() {
}
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
when (keyCode) {
// 直接返回后台
KeyEvent.KEYCODE_BACK -> moveTaskToBack(true)
}
return true
}
}
\ No newline at end of file
package com.mints.cleaner.ui
import android.widget.ImageView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions
import com.github.chrisbanes.photoview.PhotoViewAttacher
import com.mints.cleaner.R
import com.mints.cleaner.model.bean.Image
import com.mints.cleaner.util.VersionUtils
import com.mints.core.base.BaseActivity
import kotlinx.android.synthetic.main.activity_preview.*
class PreviewActivity : BaseActivity() {
companion object {
const val IMAGE = "image"
}
private val image: Image by lazy { intent.getParcelableExtra(IMAGE) as Image }
override fun getLayoutResId() = R.layout.activity_preview
override fun initView() {
val photoViewAttacher = PhotoViewAttacher(pv_preview)
pv_preview.scaleType = ImageView.ScaleType.FIT_CENTER
Glide.with(mContext)
.load(if (VersionUtils.isAndroidQ()) image.uri else image.path)
.apply(RequestOptions().diskCacheStrategy(DiskCacheStrategy.NONE)).override(720, 1080)
.into(pv_preview)
photoViewAttacher.update()
photoViewAttacher.setOnPhotoTapListener { _, _, _ ->
onBackPressed()
}
}
override fun initData() {
}
}
\ No newline at end of file
package com.mints.cleaner.ui.albumClean
import android.content.Intent
import android.net.Uri
import android.view.View
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.GridLayoutManager
import com.mints.cleaner.R
import com.mints.cleaner.adapter.albumClean.AlbumCleanAdapter
import com.mints.cleaner.databinding.ActivityAlbumCleanBinding
import com.mints.cleaner.model.bean.CleanHeaderTitle
import com.mints.cleaner.model.bean.Folder
import com.mints.cleaner.model.bean.Image
import com.mints.cleaner.ui.PreviewActivity
import com.mints.cleaner.util.FileUtils
import com.mints.cleaner.util.FormatUtils
import com.mints.core.base.BaseVMActivity
import com.mints.ktx.ext.startKtxActivity
import kotlinx.android.synthetic.main.activity_album_clean.*
import kotlinx.android.synthetic.main.activity_album_clean.btn_clean
import kotlinx.android.synthetic.main.activity_album_clean.clv_loading
import kotlinx.android.synthetic.main.activity_multi_clean.*
import java.io.File
import java.util.*
class AlbumCleanActivity : BaseVMActivity(), AlbumCleanAdapter.OnImageSelectListener,
AlbumCleanAdapter.OnItemClickListener {
private val binding by binding<ActivityAlbumCleanBinding>(R.layout.activity_album_clean)
private val dataList = arrayListOf<Image>()
// 是否全选
private var flag = false
private val albumAdapter: AlbumCleanAdapter by lazy {
AlbumCleanAdapter(
R.layout.item_album_clean,
dataList
)
}
override fun initView() {
binding.run {
title = CleanHeaderTitle(
getString(R.string.album_clean),
R.mipmap.ic_activity_arrow,
{
onBackPressed()
},
View.VISIBLE,
getString(R.string.full_choice),
{
if (!flag) {
albumAdapter.fullSelectImage()
title?.rightInfo = getString(R.string.cancel_full_choice)
title?.title = "已选中" + albumAdapter.getSelectImageList().size + "项"
} else {
albumAdapter.cancelFullSelectImage()
title?.rightInfo = getString(R.string.full_choice)
title?.title = getString(R.string.album_clean)
}
flag = !flag
},
R.color.theme
)
}
clv_loading.showLoading(5)
initRecyclerView()
btn_clean.setOnClickListener {
val selectImageList = albumAdapter.getSelectImageList()
if (selectImageList.isEmpty()) return@setOnClickListener
for (element in selectImageList) {
FileUtils.deleteImage(element.path, this)
updateAlbum(element.path)
}
dataList.removeAll(selectImageList)
albumAdapter.cleanSelectImage()
albumAdapter.notifyDataSetChanged()
}
}
private fun initRecyclerView() {
recyclerview_album.run {
layoutManager = GridLayoutManager(this@AlbumCleanActivity, 3)
adapter = albumAdapter
albumAdapter.setOnImageSelectListener(this@AlbumCleanActivity)
albumAdapter.setOnItemClickListener1(this@AlbumCleanActivity)
}
}
override fun initData() {
AlbumCleanModel.loadImageForSDCard(this, object : AlbumCleanModel.DataCallback {
override fun onSuccess(folders: ArrayList<Folder>?) {
folders?.let {
for (index in 0 until folders.size) {
dataList.addAll(folders[index].images)
}
}
runOnUiThread {
albumAdapter.notifyDataSetChanged()
clv_loading.delayLoading()
}
}
})
}
override fun startObserve() {
}
override fun onDestroy() {
super.onDestroy()
clv_loading.hideLoading()
}
override fun onImageSelect(selectCount: Int) {
// 改变 删除按钮数据
updateBtnText(selectCount)
}
override fun onItemClick(image: Image, position: Int) {
startKtxActivity<PreviewActivity>(value = PreviewActivity.IMAGE to image)
}
// 删除图片后更新图库
private fun updateAlbum(imgPath: String?) {
val intent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
intent.data = Uri.fromFile(File(imgPath))
sendBroadcast(intent)
}
// 若有选中图片,改变删除按钮样式,更新数据
private fun updateBtnText(selectCount: Int) {
if (selectCount > 0) {
btn_clean.background = ContextCompat.getDrawable(this, R.drawable.btn_clean_selected)
var selectSize = 0L
val selectImageList = albumAdapter.getSelectImageList()
for (element in selectImageList) {
selectSize += element.size
}
val selectSizeStr = FormatUtils.formatFileSize(selectSize)
btn_clean.text = "删除($selectSizeStr)"
} else {
btn_clean.background = ContextCompat.getDrawable(this, R.drawable.btn_clean_unselected)
btn_clean.text = "删除(0KB)"
}
}
}
\ No newline at end of file
package com.mints.cleaner.ui.clean
import android.app.ActivityManager
import android.content.Context
import com.mints.cleaner.R
import com.mints.cleaner.util.LogUtil
import com.mints.cleaner.util.SystemUtils
import com.mints.core.base.BaseActivity
class CleanActivity : BaseActivity() {
private var mActivityManager: ActivityManager? = null
override fun getLayoutResId() = R.layout.activity_clean
override fun initView() {
mActivityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
val availMemory = SystemUtils.getAvailMemory(this).toDouble()
val totalMemory = SystemUtils.getTotalMemory().toDouble()
mActivityManager?.run {
val memory = memoryClass
}
// val maxMemory = (Runtime.getRuntime().maxMemory() * 1.0 / (1024 * 1024)).toFloat()
// //当前分配的总内存
// val totalMemory =
// (Runtime.getRuntime().totalMemory() * 1.0 / (1024 * 1024)).toFloat()
// //剩余内存
// val freeMemory =
// (Runtime.getRuntime().freeMemory() * 1.0 / (1024 * 1024)).toFloat()
LogUtil.d("AAAAA" + availMemory)
LogUtil.d("AAAAA" + totalMemory)
LogUtil.d("AAAAA" + (((totalMemory - availMemory) / totalMemory) * 100).toInt())
LogUtil.d("AAAAA" + SystemUtils.getUsedPercentValue(this))
}
override fun onResume() {
super.onResume()
cleanMemory()
}
private fun cleanMemory() {
mActivityManager?.run {
val infoList = runningAppProcesses
val serviceLists = getRunningServices(100)
var count = 0
if (infoList.isNotEmpty()) {
infoList.forEach { it ->
if (it.importance > ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
val pkgList = it.pkgList
pkgList.forEach { it2 ->
mActivityManager?.killBackgroundProcesses(it2)
count++
}
}
}
}
}
}
override fun initData() {
}
override fun onBackPressed() {
// 屏蔽返回键
super.onBackPressed()
}
}
\ No newline at end of file
package com.mints.cleaner.ui.fileClean
import android.view.View
import com.mints.cleaner.R
import com.mints.cleaner.adapter.fileClean.FileCleanAdapter
import com.mints.cleaner.databinding.ActivityFileCleanBinding
import com.mints.cleaner.model.bean.HeaderTitle
import com.mints.cleaner.ui.albumClean.AlbumCleanActivity
import com.mints.cleaner.ui.multiClean.MultiCleanActivity
import com.mints.core.base.BaseVMActivity
import com.mints.ktx.ext.startKtxActivity
import kotlinx.android.synthetic.main.activity_file_clean.*
import org.koin.androidx.viewmodel.ext.android.viewModel
class FileCleanActivity : BaseVMActivity() {
private val binding by binding<ActivityFileCleanBinding>(R.layout.activity_file_clean)
private val fileCleanViewModel by viewModel<FileCleanViewModel>()
private val fileCleanAdapter by lazy {
FileCleanAdapter(
R.layout.item_clean_bottom,
fileCleanViewModel.repository.getFileCleanData()
)
}
override fun initView() {
binding.run {
viewModel = fileCleanViewModel
title = HeaderTitle(
getString(R.string.file_clean),
View.VISIBLE,
R.mipmap.ic_activity_arrow,
{
onBackPressed()
},
R.color.theme
)
}
initRecyclerView()
}
private fun initRecyclerView() {
recyclerview_file.run {
adapter = fileCleanAdapter
setHasFixedSize(true)
fileCleanAdapter.setOnItemClickListener { adapter, view, position ->
when (position) {
0 -> {
// 相册清理
startKtxActivity<AlbumCleanActivity>()
}
1 -> {
// 视频清理
startKtxActivity<MultiCleanActivity>(value = MultiCleanActivity.MULTI_TYPE to MultiCleanActivity.MULTI_TYPE_VIDEO)
}
2 -> {
// 安装包清理
startKtxActivity<MultiCleanActivity>(value = MultiCleanActivity.MULTI_TYPE to MultiCleanActivity.MULTI_TYPE_APK)
}
3 -> {
// 音乐清理
startKtxActivity<MultiCleanActivity>(value = MultiCleanActivity.MULTI_TYPE to MultiCleanActivity.MULTI_TYPE_AUDIO)
}
4 -> {
// 压缩包清理
startKtxActivity<MultiCleanActivity>(value = MultiCleanActivity.MULTI_TYPE to MultiCleanActivity.MULTI_TYPE_ZIP)
}
5 -> {
// 大文件清理
startKtxActivity<MultiCleanActivity>(value = MultiCleanActivity.MULTI_TYPE to MultiCleanActivity.MULTI_TYPE_BIGFILE)
}
else -> {
}
}
}
}
}
override fun initData() {
}
override fun startObserve() {
}
}
\ No newline at end of file
package com.mints.cleaner.ui.fileClean
import com.mints.cleaner.model.repository.fileClean.FileCleanRepository
import com.mints.core.base.BaseViewModel
class FileCleanViewModel(val repository: FileCleanRepository) : BaseViewModel() {
}
\ No newline at end of file
package com.mints.cleaner.ui.home
import android.Manifest
import android.os.Build
import android.os.Bundle
import android.os.Message
import android.view.LayoutInflater
import android.view.View
import android.widget.Toast
import androidx.recyclerview.widget.DefaultItemAnimator
import com.mints.cleaner.App
import com.mints.cleaner.BuildConfig
import com.mints.cleaner.Constant
import com.mints.cleaner.R
import com.mints.cleaner.adapter.home.HomeAdapter
import com.mints.cleaner.databinding.FragmentCleanBinding
import com.mints.cleaner.model.bean.HeaderTitle
import com.mints.cleaner.ui.albumClean.AlbumCleanActivity
import com.mints.cleaner.ui.fileClean.FileCleanActivity
import com.mints.cleaner.ui.login.LoginActivity
import com.mints.cleaner.ui.main.MainViewModel
import com.mints.cleaner.ui.multiClean.MultiCleanActivity
import com.mints.cleaner.ui.web.WebActivity
import com.mints.cleaner.util.LogUtil
import com.mints.core.base.BaseFragment
import com.mints.cleaner.util.NetSpeed
import com.mints.cleaner.util.WeakHandler
import com.mints.cleaner.widget.DialogListener
import com.mints.cleaner.widget.PowerDialog
import com.mints.core.base.BaseVMFragment
import com.mints.ktx.ext.startKtxActivity
import com.mints.ktx.ext.toast
import com.permissionx.guolindev.PermissionX
import kotlinx.android.synthetic.main.fragment_clean.*
import net.grandcentrix.tray.AppPreferences
import org.koin.androidx.viewmodel.ext.android.viewModel
/**
* 主页面
*/
class HomeFragment :BaseFragment(){
class HomeFragment : BaseVMFragment<FragmentCleanBinding>(R.layout.fragment_clean),
WeakHandler.IHandler {
private val mainViewModel by viewModel<MainViewModel>()
private val cleanAdapter by lazy { HomeAdapter(mainViewModel.repository.getHomeData()) }
private val speedHandler by lazy { WeakHandler(this) }
private val ps by lazy { AppPreferences(context) }
private var powerDialog: PowerDialog? = null//权限弹窗
override fun getLayoutResId()= R.layout.fragment_home
// 网速fragment切换时 是否暂停
private var speedIsPause: Boolean = false
override fun initView() {
LogUtil.e("HomeFragment","initView")
}
if (ps.getBoolean(Constant.LOAN_PERMISSION_FLAG, true)) {
powerDialog()
}else{
getPermissionList()
}
override fun initData() {
binding.run {
viewModel = mainViewModel
adapter = cleanAdapter
title = HeaderTitle(
getString(R.string.app_name),
View.GONE,
R.mipmap.ic_activity_arrow,
{},
R.color.theme
)
}
initRecyclerView()
}
override fun onResume() {
super.onResume()
LogUtil.e("HomeFragment","onResume")
LogUtil.e("onResume" + speedIsPause)
if (!speedIsPause) {
speedIsPause = true
speedHandler.sendEmptyMessageDelayed(NetSpeed.SPEED_MSG, NetSpeed.SPEED_INTERVAL)
}
}
override fun onPause() {
super.onPause()
LogUtil.e("onPause" + speedIsPause)
speedIsPause = false
}
private fun initRecyclerView() {
// 解决动画产生的item闪屏
(rv_clean.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false
cleanAdapter.run {
addFooterView(LayoutInflater.from(activity).inflate(R.layout.home_footer, null))
// 一键清理
setOnItemChildClickListener { _, _, _ ->
// 一键清理
activity?.let {
readyGo(LoginActivity::class.java)
}
}
// 竖向功能点击事件
setOnItemClickListener { _, _, position ->
when (position) {
2 -> {
// 文件清理
startKtxActivity<FileCleanActivity>()
}
3 -> {
// 安装包清理
startKtxActivity<MultiCleanActivity>(value = MultiCleanActivity.MULTI_TYPE to MultiCleanActivity.MULTI_TYPE_APK)
}
4 -> {
// 音乐清理
startKtxActivity<MultiCleanActivity>(value = MultiCleanActivity.MULTI_TYPE to MultiCleanActivity.MULTI_TYPE_AUDIO)
}
5 -> {
// 压缩包清理
startKtxActivity<MultiCleanActivity>(value = MultiCleanActivity.MULTI_TYPE to MultiCleanActivity.MULTI_TYPE_ZIP)
}
}
}
// 网格布局功能点击事件
setOnGridViewItemClickListener(object : HomeAdapter.OnGridViewItemClickListener {
override fun onGridViewItemClick(position: Int) {
when (position) {
0 -> {
// 手机加速
}
1 -> {
// 微信清理
}
2 -> {
// QQ清理
}
3 -> {
// 软件管理
}
4 -> {
// 相册清理
startKtxActivity<AlbumCleanActivity>()
}
5 -> {
// 视频清理
startKtxActivity<MultiCleanActivity>(value = MultiCleanActivity.MULTI_TYPE to MultiCleanActivity.MULTI_TYPE_VIDEO)
}
}
}
})
}
}
override fun initData() {
}
override fun startObserve() {
}
override fun handleMsg(msg: Message?) {
if (speedIsPause) {
msg?.let {
if (it.what == NetSpeed.SPEED_MSG) {
cleanAdapter.notifyItemChanged(0)
speedHandler.sendEmptyMessageDelayed(
NetSpeed.SPEED_MSG,
NetSpeed.SPEED_INTERVAL
)
}
}
}
}
/**
* 权限弹窗
*/
private fun powerDialog() {
powerDialog = PowerDialog(requireActivity(), object : DialogListener() {
override fun onClick(v: View) {
when (v.id) {
R.id.tv_dialogper_agreement -> {
val bundle = Bundle()
bundle.putString(WebActivity.WEB_TITLE, "用户协议")
bundle.putString(WebActivity.WEB_URL, BuildConfig.MainIp + "register.html")
readyGo(WebActivity::class.java, bundle)
}
R.id.tv_dialogper_policy -> {
val bundle = Bundle()
bundle.putString(WebActivity.WEB_TITLE, "用户协议")
bundle.putString(WebActivity.WEB_URL, BuildConfig.MainIp + "register.html")
readyGo(WebActivity::class.java, bundle)
}
R.id.btn_dialogper_back -> {
if (activity != null && !activity!!.isFinishing() &&
powerDialog != null && powerDialog!!.isShowing()
) {
toast(activity!!, "请您同意授权,否则将无法使用APP功能")
}
}
R.id.btn_dialogper_next -> {
if (activity != null && !activity!!.isFinishing() &&
powerDialog != null && powerDialog!!.isShowing()
) {
powerDialog!!.dismiss()
ps.put(Constant.LOAN_PERMISSION_FLAG, false)
// 获取权限
getPermissionList()
}
}
}
}
})
powerDialog!!.show()
}
private fun getPermissionList() {
val permissionList = ArrayList<String>()
permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
permissionList.add(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
}
PermissionX.init(this)
.permissions(permissionList)
.onExplainRequestReason { scope, deniedList ->
val message = "需要您同意以下权限才能正常使用"
scope.showRequestReasonDialog(deniedList, message, "确定", "取消")
}
.request { allGranted, grantedList, deniedList ->
if (allGranted) {
} else {
}
}
}
}
\ No newline at end of file
......@@ -3,12 +3,10 @@ package com.mints.cleaner.ui.login
import com.mints.cleaner.R
import com.mints.cleaner.databinding.ActivityLoginBinding
import com.mints.core.base.BaseVMActivity
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.koin.androidx.viewmodel.ext.android.viewModel
import androidx.lifecycle.Observer
import com.mints.cleaner.util.LogUtil
import kotlinx.android.synthetic.main.activity_login.*
import org.koin.androidx.viewmodel.ext.android.viewModel
import java.util.*
import kotlin.concurrent.schedule
class LoginActivity : BaseVMActivity() {
......@@ -19,6 +17,13 @@ class LoginActivity : BaseVMActivity() {
binding.run {
viewModel = loginViewModel
}
ccav_speed.startAnimation()
Timer().schedule(3000) {
runOnUiThread {
ccav_speed.stopAnimation()
}
}
}
override fun initData() {
......
......@@ -2,7 +2,10 @@ package com.mints.cleaner.ui.main
import com.mints.cleaner.R
import com.mints.cleaner.databinding.ActivityMainBinding
<<<<<<< HEAD
import com.mints.cleaner.ui.clean.CleanFragment
=======
>>>>>>> 0907_dev
import com.mints.core.base.BaseVMActivity
import org.koin.androidx.viewmodel.ext.android.viewModel
......@@ -11,18 +14,24 @@ class MainActivity : BaseVMActivity() {
private val mainViewModel by viewModel<MainViewModel>()
private val binding by binding<ActivityMainBinding>(R.layout.activity_main)
<<<<<<< HEAD
lateinit var cleanFragment: CleanFragment
=======
>>>>>>> 0907_dev
override fun initView() {
binding.run {
viewModel = mainViewModel
}
<<<<<<< HEAD
cleanFragment = CleanFragment()
val fragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.add(R.id.fragment_container, cleanFragment)
fragmentTransaction.commit()
=======
>>>>>>> 0907_dev
}
override fun initData() {
......
package com.mints.cleaner.ui.multiClean
import android.content.Context
import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
import android.media.MediaPlayer
import com.mints.cleaner.R
import com.mints.cleaner.model.bean.FileBean
import com.mints.cleaner.util.FileUtils
import com.mints.cleaner.util.FormatUtils
import com.mints.cleaner.util.LogUtil
import java.io.File
object ApkUtils {
/**
* 根据apk存储路径获取apk信息
*/
fun getApkInfo(
context: Context, apkPath: String
): FileBean {
var apkIcon: Drawable = context.getDrawable(R.mipmap.ic_launcher)!!
var apkLabel = ""
val pm: PackageManager = context.packageManager
val info = pm.getPackageArchiveInfo(
apkPath,
PackageManager.GET_ACTIVITIES
)
if (info != null) {
val appInfo = info.applicationInfo
appInfo.sourceDir = apkPath
appInfo.publicSourceDir = apkPath
try {
apkIcon = appInfo.loadIcon(pm)
apkLabel = appInfo.loadLabel(pm).toString()
} catch (e: OutOfMemoryError) {
LogUtil.e(e)
}
}
val apkFile = File(apkPath)
val size = apkFile.length()
val modifiedTime = FormatUtils.formatTime(apkFile.lastModified())
return FileBean(apkIcon, apkPath, modifiedTime, apkLabel, size)
}
/**
* 获取压缩包信息
*/
fun getZipInfo(
filePath: String
): FileBean {
val file = File(filePath)
val name = file.name
val modifiedTime = FormatUtils.formatTime(file.lastModified())
val size = file.length()
return FileBean("", filePath, modifiedTime, name, size)
}
/**
* 获取大文件信息
*/
fun getBigFileInfo(context: Context, filePath: String): FileBean {
val file = File(filePath)
val name = file.name
var modifiedTime: String
val extensionName = FileUtils.getExtensionName(name)
val size = file.length()
val image: String
when (extensionName) {
"apk" -> {
return getApkInfo(context, filePath)
}
"mp3" -> {
val mediaPlayer = MediaPlayer()
mediaPlayer.setDataSource(filePath)
mediaPlayer.prepare()
modifiedTime = FormatUtils.formatDuration(mediaPlayer.duration.toLong())
image = filePath
}
"mp4" -> {
val mediaPlayer = MediaPlayer()
mediaPlayer.setDataSource(filePath)
mediaPlayer.prepare()
modifiedTime = FormatUtils.formatDuration(mediaPlayer.duration.toLong())
image = filePath
}
"txt" -> {
modifiedTime = FormatUtils.formatTime(file.lastModified())
image = filePath
}
"jpeg" -> {
modifiedTime = FormatUtils.formatTime(file.lastModified())
image = filePath
}
"jpg" -> {
modifiedTime = FormatUtils.formatTime(file.lastModified())
image = filePath
}
"png" -> {
modifiedTime = FormatUtils.formatTime(file.lastModified())
image = filePath
}
"gif" -> {
modifiedTime = FormatUtils.formatTime(file.lastModified())
image = filePath
}
"zip" -> {
modifiedTime = FormatUtils.formatTime(file.lastModified())
image = ""
}
"rar" -> {
modifiedTime = FormatUtils.formatTime(file.lastModified())
image = ""
}
"7z" -> {
modifiedTime = FormatUtils.formatTime(file.lastModified())
image = ""
}
else -> {
modifiedTime = FormatUtils.formatTime(file.lastModified())
image = ""
}
}
return FileBean(image, filePath, modifiedTime, name, size)
}
}
\ No newline at end of file
package com.mints.cleaner.ui.multiClean
import android.os.Environment
import java.io.File
import java.util.*
object FileScanModel {
private val mEligibleFiles: ArrayList<String> by lazy { arrayListOf<String>() }
private val mBigFiles: ArrayList<String> by lazy { arrayListOf<String>() }
/**
* Java文件操作 根据文件后缀获取全部文件
*/
fun getSuffixFiles(callback: DataCallback, vararg suffixs: String) {
mEligibleFiles.clear()
Thread(Runnable {
val sdDir = Environment.getExternalStorageDirectory()
val listFiles = sdDir.listFiles()
getSuffixFile(listFiles, *suffixs)
callback.onSuccess(mEligibleFiles)
}).start()
}
private fun getSuffixFile(files: Array<File>, vararg suffixs: String) {
files?.let {
for (file in files) {
if (file.isDirectory) {
getSuffixFile(file.listFiles(), *suffixs)
} else {
val fileName = file.name
suffixs.forEach {
if (fileName.endsWith(".$it")) {
mEligibleFiles.add(file.absolutePath)
}
}
}
}
}
}
/**
* Java文件操作 根据文件大小获取文件
*/
fun getBigFiles(callback: DataCallback) {
mBigFiles.clear()
Thread(Runnable {
val sdDir = Environment.getExternalStorageDirectory()
val listFiles = sdDir.listFiles()
getBigFile(listFiles)
callback.onSuccess(mBigFiles)
}).start()
}
private fun getBigFile(files: Array<File>) {
files?.let {
for (file in files) {
if (file.isDirectory) {
getBigFile(file.listFiles())
} else {
// 大于10MB即视为大文件
if (file.length() > 1024 * 1024 * 10) {
mBigFiles.add(file.absolutePath)
}
}
}
}
}
interface DataCallback {
fun onSuccess(filePaths: ArrayList<String>?)
}
}
\ No newline at end of file
package com.mints.cleaner.ui.my
import com.mints.cleaner.R
import com.mints.cleaner.util.LogUtil
import com.mints.core.base.BaseFragment
/**
* 我的页面
*/
class MyFragment :BaseFragment(){
override fun getLayoutResId()= R.layout.fragment_my
override fun initView() {
LogUtil.e("MyFragment","initView")
}
override fun initData() {
}
override fun onResume() {
super.onResume()
LogUtil.e("MyFragment","onResume")
}
}
\ No newline at end of file
package com.mints.cleaner.ui.setting
import android.view.View
import com.mints.cleaner.R
import com.mints.cleaner.databinding.ActivitySettingBinding
import com.mints.cleaner.model.bean.HeaderTitle
import com.mints.core.base.BaseVMActivity
import kotlinx.android.synthetic.main.header_bar.*
class SettingActivity : BaseVMActivity() {
private val binding by binding<ActivitySettingBinding>(R.layout.activity_setting)
override fun initView() {
binding.run {
title = HeaderTitle(
getString(R.string.app_name),
View.GONE,
R.mipmap.ic_activity_arrow,
{},
R.color.theme
)
}
iv_header_left.setOnClickListener {
onBackPressed()
}
}
override fun initData() {
}
override fun startObserve() {
}
}
\ No newline at end of file
package com.mints.cleaner.ui.web
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import android.view.KeyEvent
import android.view.View
import android.webkit.ValueCallback
import android.webkit.WebView
import android.webkit.WebViewClient
import com.mints.cleaner.Constant
import com.mints.cleaner.R
import com.mints.core.base.BaseActivity
import com.mints.ktx.ext.toast
import kotlinx.android.synthetic.main.activity_web.*
/**
* 描述:WebActivity
* 作者:孟崔广
* 时间:2020/3/3 10:47
* 邮箱:mengcga@163.com
*/
class WebActivity : BaseActivity(), View.OnClickListener {
private var url: String? = null
private var title: String? = null
override fun getLayoutResId(): Int {
return R.layout.activity_web
}
override fun initView() {
pb_web.setProgress(0)
if (TextUtils.isEmpty(title)) {
tv_activity_title.setText("推荐")
} else {
tv_activity_title.setText(title)
}
if (!TextUtils.isEmpty(url)
&& (url!!.contains(".apk") || url!!.contains("pgyer"))
) {
val uri = Uri.parse(url)
val intent = Intent(Intent.ACTION_VIEW, uri)
startActivity(intent)
finish()
return
}
if (!TextUtils.isEmpty(url)) {
browser_layout.webView?.setWebViewClient(object : WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView,
url: String
): Boolean {
if (url.contains(".apk") || url.contains("pgyer") || url.contains("weixin://wap/pay") || url.contains(
"alipays://platformapi/startApp"
)
) {
val uri = Uri.parse(url)
val intent = Intent(Intent.ACTION_VIEW, uri)
startActivity(intent)
return true
}
return super.shouldOverrideUrlLoading(view, url)
}
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
}
})
browser_layout.loadUrl(url)
} else {
toast("获取URL地址失败")
finish()
}
tv_activity_back.setOnClickListener(this)
iv_activity_quit.setOnClickListener(this)
}
override fun initData() {}
protected val isApplyKitKatTranslucency: Boolean
protected get() = false
override fun getBundleExtras(extras: Bundle?) {
super.getBundleExtras(extras)
extras?.let {
title = it.getString(WEB_TITLE, "推荐")
url = it.getString(WEB_URL, "")
}
}
override fun onDestroy() {
super.onDestroy()
if (browser_layout != null) {
browser_layout.destroyDrawingCache()
browser_layout.clearWebView()
}
}
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK && browser_layout.canGoBack()) {
browser_layout.goBack() // 返回前一个页面
return true
}
return super.onKeyDown(keyCode, event)
}
companion object {
const val WEB_TITLE = "web_title"
const val WEB_URL = "web_url"
}
override fun onClick(v: View) {
when (v.id) {
R.id.tv_activity_back -> {
if (browser_layout != null && browser_layout.canGoBack()) {
browser_layout.goBack() // 返回前一个页面
} else {
finish()
}
}
R.id.iv_activity_quit -> {
finish()
}
}
}
}
\ No newline at end of file
package com.mints.cleaner.util
import android.content.ContentResolver
import android.content.ContentUris
import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.provider.MediaStore
object FileUtils {
fun deleteImage(imgPath: String?, context: Context): Boolean {
val resolver: ContentResolver = context.contentResolver
val cursor: Cursor = MediaStore.Images.Media.query(
resolver,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
arrayOf(MediaStore.Images.Media._ID),
MediaStore.Images.Media.DATA + "=?",
arrayOf(imgPath),
null
)
var result = false
var uri: Uri?
if (cursor.moveToFirst()) {
val id = cursor.getLong(0)
val contentUri: Uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
uri = ContentUris.withAppendedId(contentUri, id)
val count: Int = context.contentResolver.delete(uri, null, null)
result = count == 1
} else {
val cursor2 = MediaStore.Images.Media.query(
resolver,
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
arrayOf(MediaStore.Images.Media._ID),
MediaStore.Images.Media.DATA + "=?",
arrayOf(imgPath),
null
)
if (cursor2.moveToFirst()) {
val id = cursor2.getLong(0)
val contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
uri = ContentUris.withAppendedId(contentUri, id)
val count: Int = context.contentResolver.delete(uri, null, null)
result = count == 1
}
}
return result
}
/*
* Java文件操作 获取文件扩展名
* */
fun getExtensionName(filename: String?): String? {
filename?.let {
val dot = filename.lastIndexOf('.')
if (dot > -1 && dot < filename.length - 1) {
return filename.substring(dot + 1)
}
}
return filename
}
}
\ No newline at end of file
package com.mints.cleaner.util
import java.text.DecimalFormat
import java.text.SimpleDateFormat
import kotlin.math.roundToLong
object FormatUtils {
//定义GB的计算常量
private const val GB = 1024 * 1024 * 1024
//定义MB的计算常量
private const val MB = 1024 * 1024
//定义KB的计算常量
private const val KB = 1024
fun formatFileSize(bytes: Long): String {
if (bytes <= 0) return ""
//格式化小数
val format = DecimalFormat("###.0")
return when {
bytes / GB >= 1 -> {
format.format(bytes.toDouble() / GB) + "GB"
}
bytes / MB >= 1 -> {
format.format(bytes.toDouble() / MB) + "MB"
}
bytes / KB >= 1 -> {
format.format(bytes.toDouble() / KB) + "KB"
}
else -> {
bytes.toString() + "B"
}
}
}
fun formatDuration(duration: Long): String {
if (duration <= 0) return ""
var time: String? = ""
val minute: Long = duration / 60000
val seconds: Long = duration % 60000
val second = (seconds.toFloat() / 1000).roundToLong()
if (minute < 10) {
time += "0"
}
time += "$minute:"
if (second < 10) {
time += "0"
}
time += second
return time!!
}
fun formatTime(time: Long): String {
val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
return formatter.format(time)
}
}
\ No newline at end of file
package com.mints.cleaner.util
import android.content.Context
import android.net.TrafficStats
/**
* 获取网速
*/
object NetSpeed {
const val SPEED_INTERVAL: Long = 1000 //获取网速速度 1秒
const val SPEED_MSG = 101
private var lastTotalRxBytes: Long = 0
private var lastTimeStamp: Long = 0
/**
* 获取网速
*/
fun getNetSpeed(context: Context): String {
val nowTotalRxBytes = getTotalRxBytes(context.applicationInfo.uid)
val nowTimeStamp = System.currentTimeMillis()
val speed =
(nowTotalRxBytes - lastTotalRxBytes) * 1000 / (nowTimeStamp - lastTimeStamp) //毫秒转换
lastTimeStamp = nowTimeStamp
lastTotalRxBytes = nowTotalRxBytes
return "$speed kb/s"
}
private fun getTotalRxBytes(uid: Int): Long {
return if (TrafficStats.getUidRxBytes(uid) == TrafficStats.UNSUPPORTED.toLong()) 0 else TrafficStats.getTotalRxBytes() / 1024 //转为KB
}
}
\ No newline at end of file
package com.mints.cleaner.util
import android.content.Context
import android.content.Context.WIFI_SERVICE
import android.net.ConnectivityManager
import android.net.wifi.WifiManager
class NetWorkUtils {
......@@ -13,5 +16,12 @@ class NetWorkUtils {
val info = manager.activeNetworkInfo
return !(null == info || !info.isAvailable)
}
fun getConnectWifiSsid(context: Context): String? {
val wifiManager =
context.getSystemService(WIFI_SERVICE) as WifiManager
val wifiInfo = wifiManager.connectionInfo
return wifiInfo.ssid
}
}
}
\ No newline at end of file
This diff is collapsed.
package com.mints.cleaner.util
import android.os.Build
object VersionUtils {
/**
* 判断是否是Android L版本
*
* @return
*/
fun isAndroidL(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
}
/**
* 判断是否是Android N版本
*
* @return
*/
fun isAndroidN(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
}
/**
* 判断是否是AndroidO版本
*
* @return
*/
fun isAndroidO(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
}
/**
* 判断是否是Android P版本
*
* @return
*/
fun isAndroidP(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
}
/**
* 判断是否是Android Q版本
*
* @return
*/
fun isAndroidQ(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
}
}
\ No newline at end of file
package com.mints.cleaner.util
import android.os.Handler
import android.os.Looper
import android.os.Message
import java.lang.ref.WeakReference
class WeakHandler : Handler {
interface IHandler {
fun handleMsg(msg: Message?)
}
private val mRef: WeakReference<IHandler>
constructor(handler: IHandler) {
mRef = WeakReference(handler)
}
constructor(looper: Looper?, handler: IHandler) : super(looper) {
mRef = WeakReference(handler)
}
override fun handleMessage(msg: Message) {
val handler = mRef.get()
if (handler != null && msg != null) handler.handleMsg(msg)
}
}
\ No newline at end of file
package com.mints.cleaner.widget
import android.content.Context
import android.util.AttributeSet
import android.widget.GridView
class AutoHeightGv : GridView {
constructor(context: Context, attrs: AttributeSet,defStyle:Int) : super(context, attrs,defStyle)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context): super(context)
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val expandSpec = MeasureSpec.makeMeasureSpec(Int.MAX_VALUE shr 2, MeasureSpec.AT_MOST)
super.onMeasure(widthMeasureSpec, expandSpec)
}
}
\ No newline at end of file
package com.mints.cleaner.widget
import android.view.View
/**
* 自定义dialog父类监听
*/
abstract class DialogListener : View.OnClickListener {
abstract override fun onClick(v: View)
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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