Commit 404ef581 authored by jyx's avatar jyx

添加桌面插件

parent bba27861
......@@ -170,6 +170,7 @@ dependencies {
implementation Deps.grandcentrix_sharedPreference
implementation Deps.permissionx
implementation Deps.android_processes
// BASE64Decoder
implementation files('libs/sun.misc.BASE64Decoder.jar')
......
......@@ -3,12 +3,20 @@
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" />
<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" />
<application
android:name=".App"
......@@ -16,14 +24,16 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:persistent="true"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!-- 屏幕适配 -->
<meta-data
android:name="android.max_aspect"
android:value="2.4" />
<activity android:name=".ui.setting.SettingActivity"></activity>
<activity android:name=".ui.albumClean.AlbumCleanActivity" />
<activity
android:name=".ui.NavigationActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
......@@ -37,19 +47,29 @@
</intent-filter>
</activity>
<!-- 屏幕适配 -->
<meta-data
android:name="android.max_aspect"
android:value="2.4" />
<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.splash.SplashActivity" />
<activity
android:name=".ui.clean.CleanActivity"
android:launchMode="singleInstance"
android:theme="@style/CustomerTransparentTheme" />
<activity android:name=".ui.fileClean.FileCleanActivity" />
<activity
android:name=".ui.splash.SplashActivity"
android:launchMode="singleTop" />
<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"
......@@ -60,23 +80,46 @@
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" />
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:exported="false"
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" />
</application>
</manifest>
\ No newline at end of file
......@@ -52,7 +52,6 @@ class App : Application() {
}
}
}
/**
......
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
......@@ -4,11 +4,10 @@ import android.text.TextUtils
import android.widget.GridView
import android.widget.ImageView
import android.widget.SimpleAdapter
import com.bumptech.glide.Glide
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.mints.cleaner.R
import com.mints.cleaner.util.LogUtil
import com.mints.cleaner.model.bean.HomeMultiItem
import com.mints.cleaner.util.NetSpeed
import com.mints.cleaner.util.NetWorkUtils
......
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.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,8 @@ 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
import com.mints.cleaner.model.repository.fileClean.FileCleanRepository
import com.mints.cleaner.ui.fileClean.FileCleanViewModel
import com.mints.cleaner.ui.login.LoginViewModel
import com.mints.cleaner.ui.main.MainViewModel
import org.koin.androidx.viewmodel.dsl.viewModel
......@@ -14,13 +16,15 @@ import org.koin.dsl.module
val viewModelModule = module {
viewModel { LoginViewModel(get()) }
viewModel { MainViewModel(get()) }
viewModel { FileCleanViewModel(get()) }
}
val repositoryModule = module {
single { RetrofitClient.getService(
ApiService::class.java) }
single { LoginRepository(get()) }
single { MainRepository(get()) }
single { MainRepository() }
single { FileCleanRepository() }
}
val appModule = listOf(viewModelModule, repositoryModule)
\ No newline at end of file
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
data class CleanItem(val title: String, val info: String, val image: Int)
\ No newline at end of file
package com.mints.cleaner.adapter.home
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: BottomData
lateinit var itemData: CleanItem
lateinit var gvDataList: MutableList<Map<String, Any>>
......@@ -13,7 +13,7 @@ class HomeMultiItem : MultiItemEntity {
this.itemType = itemType
}
constructor(itemType: Int, itemData: BottomData) {
constructor(itemType: Int, itemData: CleanItem) {
this.itemType = itemType
this.itemData = itemData
}
......@@ -37,6 +37,4 @@ class HomeMultiItem : MultiItemEntity {
override fun getItemType(): Int {
return itemType
}
data class BottomData(val title: String, val info: String, val image: Int)
}
\ No newline at end of file
package com.mints.cleaner.model.repository
import com.mints.cleaner.R
import com.mints.cleaner.adapter.home.HomeMultiItem
import com.mints.cleaner.model.api.ApiService
import com.mints.cleaner.model.api.client.BaseRepository
import com.mints.cleaner.model.bean.HomeMultiItem
import com.mints.cleaner.model.bean.CleanItem
class MainRepository(val service: ApiService) : BaseRepository() {
class MainRepository {
// 网格布局data
private val gvNames = arrayOf("手机加速", "微信清理", "QQ清理", "软件管理", "相册清理", "视频清理")
......@@ -27,8 +26,6 @@ class MainRepository(val service: ApiService) : BaseRepository() {
R.mipmap.ic_launcher
)
private var multiItemList: ArrayList<HomeMultiItem> = arrayListOf()
private val gvDataList: MutableList<Map<String, Any>> = ArrayList()
fun getHomeData(): ArrayList<HomeMultiItem> {
......@@ -39,16 +36,19 @@ class MainRepository(val service: ApiService) : BaseRepository() {
gvDataList.add(item)
}
multiItemList = arrayListOf(
val multiItemList = arrayListOf(
HomeMultiItem(HomeMultiItem.ITEM_TOP),
HomeMultiItem(HomeMultiItem.ITEM_MID, gvDataList)
HomeMultiItem(
HomeMultiItem.ITEM_MID,
gvDataList
)
)
for (i in itemBottomTitle.indices) {
multiItemList.add(
HomeMultiItem(
HomeMultiItem.ITEM_BOTTOM,
HomeMultiItem.BottomData(
CleanItem(
itemBottomTitle[i],
itemBottomInfo[i],
itemBottomImage[i]
......
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
......@@ -7,6 +8,7 @@ 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())
......
......@@ -7,7 +7,11 @@ 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
/**
* 后台进程保活管理类
......@@ -89,14 +93,19 @@ class KeepLiveManager {
when (intent.action) {
Intent.ACTION_SCREEN_OFF -> {
// 熄屏
SystemUtils.moveAppToFront(context)
startLiveActivity(context)
LogUtil.d("LockReceiver","熄屏 Intent.ACTION_SCREEN_OFF")
LogUtil.d("LockReceiver", "熄屏 Intent.ACTION_SCREEN_OFF")
}
Intent.ACTION_SCREEN_ON -> {
// 亮屏
LogUtil.d("LockReceiver","亮屏 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 -> {
// 亮屏解锁
......@@ -137,3 +146,7 @@ class KeepLiveManager {
val instance = KeepLiveManager()
}
}
private fun Intent.setClass(context: Context, s: String) {
}
......@@ -6,8 +6,9 @@ import android.os.IBinder
open class KeepliveService : Service() {
override fun onCreate() {
super.onCreate()
KeepLiveManager.instance.registerReceiver(this)
super.onCreate()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
......@@ -16,8 +17,8 @@ open class KeepliveService : Service() {
}
override fun onDestroy() {
super.onDestroy()
KeepLiveManager.instance.unRegisterReceiver(this)
super.onDestroy()
}
override fun onBind(intent: Intent): IBinder? {
......
......@@ -3,6 +3,7 @@ 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
......@@ -21,4 +22,9 @@ class PixelActivity : Activity() {
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
......@@ -7,6 +7,7 @@ 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
......@@ -15,8 +16,11 @@ class NavigationActivity : BaseActivity() {
override fun getLayoutResId() = R.layout.activity_navigation
override fun initView() {
if (VersionUtils.isAndroidO()) {
startForegroundService(Intent(App.CONTEXT, ScreenService::class.java))
} else {
startService(Intent(App.CONTEXT, ScreenService::class.java))
}
PermissionX.init(this)
.permissions(
......
......@@ -17,6 +17,9 @@ 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.*
......@@ -64,6 +67,8 @@ class AlbumCleanActivity : BaseVMActivity(), AlbumCleanAdapter.OnImageSelectList
)
}
clv_loading.showLoading(5)
initRecyclerView()
btn_clean.setOnClickListener {
val selectImageList = albumAdapter.getSelectImageList()
......@@ -78,7 +83,6 @@ class AlbumCleanActivity : BaseVMActivity(), AlbumCleanAdapter.OnImageSelectList
albumAdapter.cleanSelectImage()
albumAdapter.notifyDataSetChanged()
}
}
private fun initRecyclerView() {
......@@ -101,6 +105,7 @@ class AlbumCleanActivity : BaseVMActivity(), AlbumCleanAdapter.OnImageSelectList
}
runOnUiThread {
albumAdapter.notifyDataSetChanged()
clv_loading.delayLoading()
}
}
})
......@@ -110,6 +115,13 @@ class AlbumCleanActivity : BaseVMActivity(), AlbumCleanAdapter.OnImageSelectList
}
override fun onDestroy() {
super.onDestroy()
clv_loading.hideLoading()
}
override fun onImageSelect(selectCount: Int) {
// 改变 删除按钮数据
updateBtnText(selectCount)
......
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
......@@ -9,8 +9,8 @@ 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.PreviewActivity
import com.mints.cleaner.ui.albumClean.AlbumCleanActivity
import com.mints.cleaner.ui.fileClean.FileCleanActivity
import com.mints.cleaner.ui.main.MainViewModel
import com.mints.cleaner.ui.multiClean.MultiCleanActivity
import com.mints.cleaner.util.LogUtil
......@@ -52,8 +52,6 @@ class HomeFragment : BaseVMFragment<FragmentCleanBinding>(R.layout.fragment_clea
}
initRecyclerView()
}
override fun onResume() {
......@@ -76,7 +74,7 @@ class HomeFragment : BaseVMFragment<FragmentCleanBinding>(R.layout.fragment_clea
private fun initRecyclerView() {
// 解决动画产生的item闪屏
(rv_clean.getItemAnimator() as DefaultItemAnimator).supportsChangeAnimations = false
(rv_clean.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false
cleanAdapter.run {
addFooterView(LayoutInflater.from(activity).inflate(R.layout.home_footer, null))
......@@ -92,7 +90,7 @@ class HomeFragment : BaseVMFragment<FragmentCleanBinding>(R.layout.fragment_clea
when (position) {
2 -> {
// 文件清理
startKtxActivity<FileCleanActivity>()
}
3 -> {
// 安装包清理
......@@ -100,11 +98,11 @@ class HomeFragment : BaseVMFragment<FragmentCleanBinding>(R.layout.fragment_clea
}
4 -> {
// 音乐清理
startKtxActivity<MultiCleanActivity>(value = MultiCleanActivity.MULTI_TYPE_AUDIO to MultiCleanActivity.MULTI_TYPE_AUDIO)
startKtxActivity<MultiCleanActivity>(value = MultiCleanActivity.MULTI_TYPE to MultiCleanActivity.MULTI_TYPE_AUDIO)
}
5 -> {
// 压缩包清理
startKtxActivity<MultiCleanActivity>(value = MultiCleanActivity.MULTI_TYPE_ZIP to MultiCleanActivity.MULTI_TYPE_ZIP)
startKtxActivity<MultiCleanActivity>(value = MultiCleanActivity.MULTI_TYPE to MultiCleanActivity.MULTI_TYPE_ZIP)
}
}
}
......@@ -131,7 +129,7 @@ class HomeFragment : BaseVMFragment<FragmentCleanBinding>(R.layout.fragment_clea
}
5 -> {
// 视频清理
startKtxActivity<MultiCleanActivity>(value = MultiCleanActivity.MULTI_TYPE_VIDEO to MultiCleanActivity.MULTI_TYPE_VIDEO)
startKtxActivity<MultiCleanActivity>(value = MultiCleanActivity.MULTI_TYPE to MultiCleanActivity.MULTI_TYPE_VIDEO)
}
}
......@@ -154,7 +152,10 @@ class HomeFragment : BaseVMFragment<FragmentCleanBinding>(R.layout.fragment_clea
msg?.let {
if (it.what == NetSpeed.SPEED_MSG) {
cleanAdapter.notifyItemChanged(0)
speedHandler.sendEmptyMessageDelayed(NetSpeed.SPEED_MSG, NetSpeed.SPEED_INTERVAL)
speedHandler.sendEmptyMessageDelayed(
NetSpeed.SPEED_MSG,
NetSpeed.SPEED_INTERVAL
)
}
}
}
......
......@@ -5,7 +5,6 @@ import com.mints.cleaner.databinding.ActivityLoginBinding
import com.mints.core.base.BaseVMActivity
import org.koin.androidx.viewmodel.ext.android.viewModel
class LoginActivity : BaseVMActivity() {
private val loginViewModel by viewModel<LoginViewModel>()
......@@ -15,7 +14,6 @@ class LoginActivity : BaseVMActivity() {
binding.run {
viewModel = loginViewModel
}
}
override fun initData() {
......
......@@ -13,6 +13,7 @@ object FileScanModel {
* Java文件操作 根据文件后缀获取全部文件
*/
fun getSuffixFiles(callback: DataCallback, vararg suffixs: String) {
mEligibleFiles.clear()
Thread(Runnable {
val sdDir = Environment.getExternalStorageDirectory()
......@@ -45,6 +46,7 @@ object FileScanModel {
* Java文件操作 根据文件大小获取文件
*/
fun getBigFiles(callback: DataCallback) {
mBigFiles.clear()
Thread(Runnable {
val sdDir = Environment.getExternalStorageDirectory()
......
......@@ -44,16 +44,12 @@ class MultiCleanActivity : BaseVMActivity(), MultiCleanAdapter.OnImageSelectList
// 视频清理
const val MULTI_TYPE_VIDEO = "VIDEO"
// 音频清理
const val MULTI_TYPE_AUDIO = "AUDIO"
// 压缩包清理
const val MULTI_TYPE_ZIP = "ZIP"
// 安装包清理
const val MULTI_TYPE_APK = "APK"
// 大文件清理
const val MULTI_TYPE_BIGFILE = "OTHERS"
}
......@@ -208,7 +204,7 @@ class MultiCleanActivity : BaseVMActivity(), MultiCleanAdapter.OnImageSelectList
}
}
clv_loading.showLoading()
clv_loading.showLoading(5)
initRecyclerView()
btn_clean.setOnClickListener {
......@@ -253,6 +249,8 @@ class MultiCleanActivity : BaseVMActivity(), MultiCleanAdapter.OnImageSelectList
}
override fun initData() {
dataList.clear()
when (mMultiType) {
MULTI_TYPE_VIDEO -> {
MultiCleanModel.loadVideoForSDCard(this, object : MultiCleanModel.DataCallback {
......@@ -269,6 +267,7 @@ class MultiCleanActivity : BaseVMActivity(), MultiCleanAdapter.OnImageSelectList
runOnUiThread {
multiAdapter.notifyDataSetChanged()
clv_loading.delayLoading()
}
}
......@@ -283,6 +282,7 @@ class MultiCleanActivity : BaseVMActivity(), MultiCleanAdapter.OnImageSelectList
runOnUiThread {
multiAdapter.notifyDataSetChanged()
clv_loading.delayLoading()
}
}
......@@ -313,6 +313,7 @@ class MultiCleanActivity : BaseVMActivity(), MultiCleanAdapter.OnImageSelectList
runOnUiThread {
multiAdapter.notifyDataSetChanged()
clv_loading.delayLoading()
}
}
......@@ -345,6 +346,7 @@ class MultiCleanActivity : BaseVMActivity(), MultiCleanAdapter.OnImageSelectList
runOnUiThread {
multiAdapter.notifyDataSetChanged()
clv_loading.delayLoading()
}
}
......@@ -377,6 +379,7 @@ class MultiCleanActivity : BaseVMActivity(), MultiCleanAdapter.OnImageSelectList
runOnUiThread {
multiAdapter.notifyDataSetChanged()
clv_loading.delayLoading()
}
}
......@@ -406,7 +409,7 @@ class MultiCleanActivity : BaseVMActivity(), MultiCleanAdapter.OnImageSelectList
override fun onItemClick(fileBean: FileBean, position: Int) {
// 根据不同类型跳转系统自带的文件打开器
var multiIntent: Intent?
val multiIntent: Intent?
when (mMultiType) {
MULTI_TYPE_AUDIO -> {
multiIntent = IntentUtils.getAudioFileIntent(this, fileBean.path)
......@@ -486,7 +489,7 @@ class MultiCleanActivity : BaseVMActivity(), MultiCleanAdapter.OnImageSelectList
sendBroadcast(intent)
}
// 若有选中图片,改变删除按钮样式,更新数据
// 若有选中文件,改变删除按钮样式,更新数据
private fun updateBtnText(selectCount: Int) {
if (selectCount > 0) {
btn_clean.background = ContextCompat.getDrawable(this, R.drawable.btn_clean_selected)
......
......@@ -8,8 +8,8 @@ import android.net.TrafficStats
*/
object NetSpeed {
val SPEED_INTERVAL: Long = 1000 //获取网速速度 1秒
val SPEED_MSG = 101
const val SPEED_INTERVAL: Long = 1000 //获取网速速度 1秒
const val SPEED_MSG = 101
private var lastTotalRxBytes: Long = 0
private var lastTimeStamp: Long = 0
......
package com.mints.cleaner.util
import android.app.Activity
import android.app.ActivityManager
import android.content.Context
import android.content.Intent
import java.io.BufferedReader
import java.io.FileReader
import java.io.IOException
object SystemUtils {
/**
* 描述:应用是否在前台
*/
private fun isAppRunningForeground(context: Context): Boolean {
val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
val runningAppProcessList = activityManager.runningAppProcesses ?: return false
runningAppProcessList.forEach {
if (it.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
&& it.processName == context.applicationInfo.processName
) {
return true
}
}
return false
}
/**
* 描述:将应用移动到前台
*/
fun moveAppToFront(context: Context) {
val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
val runningTasks = activityManager.getRunningTasks(100)
for (taskInfo in runningTasks) {
if (taskInfo.topActivity!!.packageName == context.packageName) {
activityManager.moveTaskToFront(taskInfo.id, 0)
break
}
}
}
/**
* 描述:将应用移动到后台
*/
fun moveAppToBack(context: Context) {
val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
val runningTasks = activityManager.getRunningTasks(100)
for (taskInfo in runningTasks) {
if (taskInfo.topActivity!!.packageName == context.packageName) {
val name = taskInfo.topActivity
val foregroundActivity = Class.forName(name!!.className).newInstance() as Activity
// foregroundActivity.onBackPressed()
val intent = Intent(Intent.ACTION_MAIN)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.addCategory(Intent.CATEGORY_HOME)
context.startActivity(intent)
foregroundActivity.overridePendingTransition(0, 0)
break
}
}
}
/**
* 描述:获取内存占用率.
*/
fun getUsedPercentValue(context: Context?): String {
val dir = "/proc/meminfo"
try {
val fr = FileReader(dir)
val br = BufferedReader(fr, 2048)
val memoryLine = br.readLine()
val subMemoryLine = memoryLine.substring(memoryLine.indexOf("MemTotal:"))
br.close()
val totalMemorySize =
subMemoryLine.replace("\\D+".toRegex(), "").toInt().toLong()
val availableSize: Long = getAvailMemory(context) / 1024
val percent =
((totalMemorySize - availableSize) / totalMemorySize.toFloat() * 100).toInt()
return "$percent"
} catch (e: IOException) {
e.printStackTrace()
}
return "none"
}
/**
* 描述:获取可用内存.
*/
fun getAvailMemory(context: Context?): Long {
// 获取android当前可用内存大小
val activityManager = context?.getSystemService(
Context.ACTIVITY_SERVICE
) as ActivityManager
val memoryInfo =
ActivityManager.MemoryInfo()
activityManager.getMemoryInfo(memoryInfo)
// 当前系统可用内存 ,将获得的内存大小规格化
return memoryInfo.availMem
}
/**
* 描述:总内存.
*/
fun getTotalMemory(): Long {
// 系统内存信息文件
val file = "/proc/meminfo"
val memInfo: String
val strs: Array<String>
var memory: Long = 0
try {
val fileReader = FileReader(file)
val bufferedReader = BufferedReader(
fileReader,
8192
)
// 读取meminfo第一行,系统内存大小
memInfo = bufferedReader.readLine()
strs = memInfo.split("\\s+".toRegex()).toTypedArray()
// 获得系统总内存,单位KB
memory = Integer.valueOf(strs[1]).toLong()
bufferedReader.close()
} catch (e: Exception) {
e.printStackTrace()
}
// Byte转位KB或MB
return memory * 1024
}
/**
* 该方法必须在Activity或Service类内调用,一般情况下,可以在Activity的onCreate()方法中调用。
* 由于应用每启动一个新的进程,就会调用一次Application的onCreate()方法,而个推SDK是一个独立的进程
......
......@@ -22,6 +22,15 @@ object VersionUtils {
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版本
*
......
package com.mints.cleaner.widget
import android.R.attr.radius
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.text.TextPaint
import android.util.AttributeSet
import android.view.View
class CleanBall : View {
private var mArcPaint: Paint? = null
private var mTextPaint: TextPaint? = null
private var centerX = 0
private var centerY = 0
private var mWidth = 0F
private var mHeight = 0F
private var mGap20 = 20F
private var mGap10 = 10F
private var mRadius = 100F
private var mProgress = 50F
constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(
context,
attrs,
defStyle
)
constructor(context: Context, attrs: AttributeSet?) : this(
context,
attrs,
androidx.appcompat.R.attr.radioButtonStyle
)
constructor(context: Context) : this(context, null)
init {
mArcPaint = Paint()
mArcPaint?.run {
isAntiAlias = true
style = Paint.Style.FILL
strokeWidth = 2F
color = Color.GREEN
}
mTextPaint = TextPaint()
mTextPaint?.run {
isAntiAlias = true
textSize = 22F
color = Color.WHITE
}
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val wideSize = MeasureSpec.getSize(widthMeasureSpec)
val wideMode = MeasureSpec.getMode(widthMeasureSpec)
val heightSize = MeasureSpec.getSize(heightMeasureSpec)
val heightMode = MeasureSpec.getMode(heightMeasureSpec)
var width: Int
var height: Int
if (wideMode == MeasureSpec.EXACTLY) { //精确值 或matchParent
width = wideSize
} else {
width = radius * 2 + paddingLeft + paddingRight
if (wideMode == MeasureSpec.AT_MOST) {
width = width.coerceAtMost(wideSize)
}
}
if (heightMode == MeasureSpec.EXACTLY) { //精确值 或matchParent
height = heightSize
} else {
height = radius * 2 + paddingLeft + paddingRight
if (heightMode == MeasureSpec.AT_MOST) {
height = height.coerceAtMost(heightSize)
}
}
setMeasuredDimension(width, height)
centerX = width / 2 // 获取圆心的x坐标
centerY = height / 2 // 获取圆心的y坐标
mWidth = width.toFloat() - paddingStart - paddingEnd
mHeight = height.toFloat() - paddingTop - paddingBottom
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
canvas?.run {
save()
// 白色椭圆
mArcPaint!!.color = Color.WHITE
val oval = RectF(0F, 0F + mGap20, width.toFloat(), height.toFloat() - mGap20)
drawRoundRect(oval, mRadius, mRadius, mArcPaint!!)
// 灰色椭圆
mArcPaint!!.color = Color.GRAY
val oval2 =
RectF(
0F + mGap20,
0F + mGap20 * 2,
width.toFloat() - mGap20 - mHeight,
height.toFloat() - mGap20 * 2
)
drawRoundRect(oval2, mRadius, mRadius, mArcPaint!!)
mArcPaint!!.color = Color.GREEN
// 进度
val oval3 = RectF(
0F + mGap20,
0F + mGap20 * 2,
(width.toFloat() - mGap20 - mHeight) * (mProgress / 100F),
height.toFloat() - mGap20 * 2
)
drawRoundRect(oval3, mRadius, mRadius, mArcPaint!!)
// 进度
val oval4 = RectF(
0F + mGap20 + (width.toFloat() - mGap20 - mHeight) * (10 / 100F),
0F + mGap20 * 2,
(width.toFloat() - mGap20 - mHeight) * (mProgress / 100F),
height.toFloat() - mGap20 * 2
)
drawRect(oval4, mArcPaint!!)
// 进度文字
val fontMetrics = Paint.FontMetrics()
mTextPaint!!.getFontMetrics(fontMetrics)
val offset = (fontMetrics.descent + fontMetrics.ascent) / 2
drawText(
"$mProgress%内存已使用",
0F + mGap20 + mGap20,
centerY - offset,
mTextPaint!!
)
// 加速球背景
mArcPaint!!.color = Color.WHITE
drawCircle(mWidth - mHeight / 2, mHeight / 2, mHeight / 2, mArcPaint!!)
// 加速球实心
mArcPaint!!.color = Color.GREEN
drawCircle(mWidth - mHeight / 2, mHeight / 2, (mHeight - mGap20) / 2, mArcPaint!!)
restore()
}
}
/**
* 0-100
*/
fun setProgress(process: Int) {
mProgress = process.toFloat()
invalidate()
}
}
\ No newline at end of file
......@@ -4,6 +4,8 @@ import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.os.Build
import android.os.Looper
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
......@@ -14,6 +16,10 @@ import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import com.mints.cleaner.R
import com.mints.cleaner.util.LogUtil
import com.mints.cleaner.util.VersionUtils
import java.util.*
import kotlin.concurrent.schedule
/**
* 清理界面-加载中
......@@ -94,6 +100,18 @@ class CleanLoadingView : LinearLayout {
this.visibility = View.GONE
}
fun delayLoading() {
set?.let {
if (VersionUtils.isAndroidO()) {
it.currentPlayTime = 4000
} else {
it.cancel()
it.duration = 1000
it.start()
}
}
}
@SuppressLint("ObjectAnimatorBinding")
private fun start(time: Long) {
......@@ -120,7 +138,6 @@ class CleanLoadingView : LinearLayout {
animator = ValueAnimator.ofInt(0, 101)
}
animator?.addUpdateListener { valueAnimator ->
tvLoadingProgress?.text = valueAnimator.animatedValue.toString() + "%"
......
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="1000dp" />
<gradient
android:angle="-90"
android:endColor="@color/green"
android:startColor="@color/green_01" />
<stroke
android:width="4dp"
android:color="@color/white" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@android:id/background"
android:drawable="@drawable/shape_progressbar_bg" />
<item android:id="@android:id/progress">
<clip android:drawable="@drawable/shape_progressbar_progress" />
</item>
</layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="20dp" />
<stroke
android:width="10dp"
android:color="@color/white" />
<solid android:color="#dadada" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="50dp" />
<stroke
android:width="10dp"
android:color="@color/white" />
<solid android:color="#FFFFFF" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="20dp" />
<solid android:color="@color/green" />
<stroke
android:width="10dp"
android:color="@color/white" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/ic_launcher">
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
......@@ -18,11 +18,14 @@
layout="@layout/clean_header_bar"
app:title="@{title}" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview_album"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
android:layout_height="match_parent" />
<LinearLayout
android:layout_width="match_parent"
......@@ -46,6 +49,13 @@
</LinearLayout>
<com.mints.cleaner.widget.CleanLoadingView
android:id="@+id/clv_loading"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</LinearLayout>
</layout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</FrameLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type="com.mints.cleaner.ui.fileClean.FileCleanViewModel" />
<variable
name="title"
type="com.mints.cleaner.model.bean.HeaderTitle" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
layout="@layout/header_bar"
app:title="@{title}" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview_file"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout>
</layout>
\ No newline at end of file
......@@ -8,9 +8,11 @@
type="com.mints.cleaner.ui.login.LoginViewModel" />
</data>
<RelativeLayout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="@color/colorAccent"
android:orientation="vertical">
<Button
android:id="@+id/btn_getdata"
......@@ -20,6 +22,11 @@
android:onClick="@{()->viewModel.getRotationChart()}"
android:text="getData" />
</RelativeLayout>
<com.mints.cleaner.widget.CleanBall
android:layout_width="match_parent"
android:layout_height="100dp" />
</LinearLayout>
</layout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingStart="10dp"
android:paddingEnd="10dp">
<ProgressBar
android:id="@+id/progressBar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_gravity="center"
android:background="@drawable/shape_progressbar_bg2"
android:max="100"
android:paddingEnd="60dp"
android:progress="50"
android:progressDrawable="@drawable/layer_list_progressbar" />
<TextView
android:id="@+id/tv_memory"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="20dp"
android:textColor="@color/white"
android:textSize="12sp" />
<Button
android:id="@+id/btn_clean"
android:layout_width="66dp"
android:layout_height="66dp"
android:layout_gravity="right|center"
android:background="@drawable/btn_clean_ball"
android:text="加速"
android:textSize="12sp" />
</FrameLayout>
......@@ -15,7 +15,6 @@
android:id="@+id/item_gv_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="手机加速" />
</LinearLayout>
\ No newline at end of file
......@@ -16,6 +16,7 @@
<color name="gray">#999999</color>
<color name="gray_01">#F5F5F5</color>
<color name="gray_02">#E8E8F0</color>
<color name="green_01">#7FFFAA</color>
<color name="green">#00FF00</color>
<color name="status_bg">#002444</color>
......
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--
Refer to App Widget Documentation for margin information
http://developer.android.com/guide/topics/appwidgets/index.html#CreatingLayout
-->
<dimen name="widget_margin">8dp</dimen>
</resources>
\ No newline at end of file
<resources>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">Cleaner</string>
<item name="BaseQuickAdapter_databinding_support" type="id" />
......@@ -49,5 +49,10 @@
<string name="no_connect_wifi">Wifi 未连接</string>
<string name="connect_wifi">Wifi 已连接</string>
<string name="no_network">无网络</string>
<string name="appwidget_text">EXAMPLE</string>
<string name="configure">Configure</string>
<string name="add_widget">Add widget</string>
<string name="cleaned">清理垃圾 (<xliff:g id="memory">%1$s</xliff:g>)</string>
</resources>
\ No newline at end of file
......@@ -6,9 +6,13 @@
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
</style>p
</style>
p
<style name="CustomerTransparentTheme" parent="AppTheme">
<!-- 为窗体的Enter和Exit设置动画 -->
<item name="android:windowAnimationStyle">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
</style>
......@@ -30,8 +34,24 @@
</style>
<style name="LiveActivityStyle">
<!-- 背景设置为透明 -->
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<!-- 是否有边框 -->
<item name="android:windowFrame">@null</item>
<item name="android:windowNoTitle">true</item>
<!-- 是否浮动在界面上 -->
<item name="android:windowIsFloating">true</item>
<!-- 是否透明 -->
<item name="android:windowIsTranslucent">true</item>
<!-- 窗体上面是否有遮盖 -->
<item name="android:windowContentOverlay">@null</item>
<!-- 背景是否变暗 -->
<item name="android:backgroundDimEnabled">false</item>
<!-- 为窗体的Enter和Exit设置动画 -->
<item name="android:windowAnimationStyle">@null</item>
<!-- 是否禁止窗体显示前显示的View -->
<item name="android:windowDisablePreview">true</item>
<item name="android:windowNoDisplay">false</item>
</style>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialKeyguardLayout="@layout/app_widget_clean"
android:initialLayout="@layout/app_widget_clean"
android:minWidth="180dp"
android:minHeight="40dp"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="86400000"
android:widgetCategory="home_screen">
<!--
android:minWidth : 最小宽度
android:minHeight : 最小高度
android:updatePeriodMillis : 更新widget的时间间隔(ms),"86400000"为1个小时 最小为30分钟
android:previewImage : 预览图片
android:initialLayout : 加载到桌面时对应的布局文件
android:resizeMode : widget可以被拉伸的方向。horizontal表示可以水平拉伸,vertical表示可以竖直拉伸
android:widgetCategory : widget可以被显示的位置。home_screen表示可以将widget添加到桌面,keyguard表示widget可以被添加到锁屏界面。
android:initialKeyguardLayout : 加载到锁屏界面时对应的布局文件
-->
</appwidget-provider>
\ No newline at end of file
......@@ -46,6 +46,7 @@ object Versions {
const val retrofit_adapter_rxjava = "2.1.0"
const val orhanobut_logger = "2.2.0"
const val permissionx = "1.4.0"
const val android_processes = "1.1.1"
}
object Deps {
......@@ -93,8 +94,10 @@ object Deps {
const val koin_android = "org.koin:koin-android:${Versions.koin}"
const val koin_androidx_scope = "org.koin:koin-androidx-scope:${Versions.koin}"
const val koin_androidx_viewmodel = "org.koin:koin-androidx-viewmodel:${Versions.koin}"
const val android_processes = "com.jaredrummler:android-processes:${Versions.android_processes}"
// 类似sharedPreference 可多进程间访问
const val grandcentrix_sharedPreference = "net.grandcentrix.tray:tray:${Versions.grandcentrix_sharedPreference}"
const val permissionx = "com.permissionx.guolindev:permissionx:${Versions.permissionx}"
}
\ No newline at end of file
package com.mints.core.base
import android.content.Context
import android.graphics.PixelFormat
import android.os.Bundle
import android.view.WindowManager
import android.widget.Button
/**
* 不使用ViewModel的BaseActivity
......@@ -29,4 +34,28 @@ abstract class BaseActivity : BaseAppCompatActivity() {
override fun toggleIsBack2Left() = false
// override fun onStop() {
// super.onStop()
// val button = Button(applicationContext)
// val wm = applicationContext
// .getSystemService(Context.WINDOW_SERVICE) as WindowManager
// val wmParams = WindowManager.LayoutParams()
//
// /**
// * 以下都是WindowManager.LayoutParams的相关属性 具体用途请参考SDK文档
// */
// wmParams.type = WindowManager.LayoutParams.TYPE_PHONE // 这里是关键,你也可以试试2003
// wmParams.format = PixelFormat.RGBA_8888 // 设置图片格式,效果为背景透明
//
// /**
// * 这里的flags也很关键 代码实际是wmParams.flags |=FLAG_NOT_FOCUSABLE;
// * 40的由来是wmParams的默认属性(32)+ FLAG_NOT_FOCUSABLE(8)
// */
// wmParams.flags = (WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
// or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
// or WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
// wmParams.height = 1
// wm.addView(button, wmParams) // 创建View
// }
}
\ 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